Recoded to use poll rather than select and

This commit is contained in:
Jaroslav Kysela 2001-02-23 09:58:14 +00:00
parent 33b8d4717e
commit 740881bdf5

View file

@ -30,6 +30,7 @@
*/ */
static void usage(void); static void usage(void);
static void init_buf(void); static void init_buf(void);
static void init_pollfds(void);
static void close_files(void); static void close_files(void);
static void init_seq(char *source, char *dest); static void init_seq(char *source, char *dest);
static int get_port(char *service); static int get_port(char *service);
@ -57,7 +58,13 @@ static int cur_wrlen, max_wrlen;
#define MAX_CONNECTION 10 #define MAX_CONNECTION 10
static snd_seq_t *handle; static snd_seq_t *handle;
static int seqfd, sockfd, netfd[MAX_CONNECTION] = {[0 ... MAX_CONNECTION-1] = -1}; static struct pollfd *seqifds = NULL;
static struct pollfd *seqofds = NULL;
static struct pollfd *pollfds = NULL;
static int seqifds_count = 0;
static int seqofds_count = 0;
static int pollfds_count = 0;
static int sockfd, netfd[MAX_CONNECTION] = {[0 ... MAX_CONNECTION-1] = -1};
static int max_connection; static int max_connection;
static int cur_connected; static int cur_connected;
static int seq_port; static int seq_port;
@ -117,10 +124,12 @@ int main(int argc, char **argv)
if (optind >= argc) { if (optind >= argc) {
server_mode = 1; server_mode = 1;
max_connection = MAX_CONNECTION; max_connection = MAX_CONNECTION;
init_pollfds();
init_server(port); init_server(port);
} else { } else {
server_mode = 0; server_mode = 0;
max_connection = 1; max_connection = 1;
init_pollfds();
init_client(argv[optind], port); init_client(argv[optind], port);
} }
@ -168,6 +177,16 @@ static void init_buf(void)
cur_wrlen = 0; cur_wrlen = 0;
} }
/*
* allocate and initialize poll array
*/
static void init_pollfds(void)
{
pollfds_count = seqifds_count + seqofds_count + 1 + max_connection;
pollfds = (struct pollfd *)calloc(pollfds_count, sizeof(struct pollfd));
assert(pollfds);
}
/* /*
* parse command line to client:port * parse command line to client:port
* NB: the given string will be broken. * NB: the given string will be broken.
@ -232,16 +251,28 @@ static void close_files(void)
static void init_seq(char *source, char *dest) static void init_seq(char *source, char *dest)
{ {
snd_seq_addr_t addr; snd_seq_addr_t addr;
int err; int err, counti, counto;
struct pollfd pfd;
if (snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) { if (snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
perror("snd_seq_open"); perror("snd_seq_open");
exit(1); exit(1);
} }
err = snd_seq_poll_descriptors(handle, &pfd, 1, POLLIN | POLLOUT); if (seqifds)
assert(err == 1); free(seqifds);
seqfd = pfd.fd; if (seqofds)
free(seqofds);
counti = seqifds_count = snd_seq_poll_descriptors_count(handle, POLLIN);
assert(counti > 0);
counto = seqofds_count = snd_seq_poll_descriptors_count(handle, POLLOUT);
assert(counto > 0);
seqifds = (struct pollfd *)calloc(counti, sizeof(struct pollfd));
assert(seqifds);
seqofds = (struct pollfd *)calloc(counto, sizeof(struct pollfd));
assert(seqofds);
err = snd_seq_poll_descriptors(handle, seqifds, counti, POLLIN);
assert(err == counti);
err = snd_seq_poll_descriptors(handle, seqofds, counto, POLLOUT);
assert(err == counto);
snd_seq_nonblock(handle, 0); snd_seq_nonblock(handle, 0);
@ -418,49 +449,49 @@ static void init_client(char *server, int port)
cur_connected = 1; cur_connected = 1;
} }
/*
* set file descriptor
*/
static void set_fd(int fd, fd_set *p, int *width)
{
FD_SET(fd, p);
if (fd >= *width)
*width = fd + 1;
}
/* /*
* event loop * event loop
*/ */
static void do_loop(void) static void do_loop(void)
{ {
fd_set rfd;
int i, rc, width; int i, rc, width;
int seqifd_ptr, sockfd_ptr = -1, netfd_ptr;
for (;;) { for (;;) {
FD_ZERO(&rfd); memset(pollfds, 0, pollfds_count * sizeof(struct pollfd));
width = 0; seqifd_ptr = 0;
set_fd(seqfd, &rfd, &width); memcpy(pollfds, seqifds, width = seqifds_count);
if (server_mode) if (server_mode) {
set_fd(sockfd, &rfd, &width); sockfd_ptr = width;
for (i = 0; i < max_connection; i++) { pollfds[width].fd = sockfd;
if (netfd[i] >= 0) pollfds[width].events = POLLIN;
set_fd(netfd[i], &rfd, &width); width++;
} }
rc = select(width, &rfd, NULL, NULL, NULL); netfd_ptr = width;
for (i = 0; i < max_connection; i++) {
if (netfd[i] >= 0) {
pollfds[width].fd = netfd[i];
pollfds[width].events = POLLIN;
width++;
}
}
rc = poll(pollfds, width, -1);
if (rc <= 0) if (rc <= 0)
exit(1); exit(1);
if (server_mode) { if (server_mode) {
if (FD_ISSET(sockfd, &rfd)) if (pollfds[sockfd_ptr].revents & (POLLIN|POLLOUT))
start_connection(); start_connection();
} }
if (FD_ISSET(seqfd, &rfd)) { for (i = 0; i < seqifds_count; i++)
if (copy_local_to_remote()) if (pollfds[seqifd_ptr + i].revents & (POLLIN|POLLOUT)) {
if (copy_local_to_remote())
return;
break; break;
} }
for (i = 0; i < max_connection; i++) { for (i = 0; i < max_connection; i++) {
if (netfd[i] < 0) if (netfd[i] < 0)
continue; continue;
if (FD_ISSET(netfd[i], &rfd)) { if (pollfds[netfd_ptr + i].revents & (POLLIN|POLLOUT)) {
if (copy_remote_to_local(netfd[i])) { if (copy_remote_to_local(netfd[i])) {
netfd[i] = -1; netfd[i] = -1;
cur_connected--; cur_connected--;