mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 00:35:42 +01:00
Recoded to use poll rather than select and
This commit is contained in:
parent
33b8d4717e
commit
740881bdf5
1 changed files with 62 additions and 31 deletions
|
@ -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--;
|
||||||
|
|
Loading…
Reference in a new issue