Change select references to poll in core asterisk functions (hope this works)
authorMark Spencer <markster@digium.com>
Sat, 24 Apr 2004 23:02:21 +0000 (23:02 +0000)
committerMark Spencer <markster@digium.com>
Sat, 24 Apr 2004 23:02:21 +0000 (23:02 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2756 65c4cc65-6c06-0410-ace0-fbb531ad65f3

asterisk.c
channel.c
manager.c

index bc27f37..6566bb7 100755 (executable)
@@ -13,6 +13,7 @@
 
 #include <unistd.h>
 #include <stdlib.h>
+#include <sys/poll.h>
 #include <asterisk/logger.h>
 #include <asterisk/options.h>
 #include <asterisk/cli.h>
@@ -229,26 +230,24 @@ static void *netconsole(void *vconsole)
        char hostname[256];
        char tmp[512];
        int res;
-       int max;
-       fd_set rfds;
+       struct pollfd fds[2];
        
        if (gethostname(hostname, sizeof(hostname)))
                strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
        snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, ast_mainpid, ASTERISK_VERSION);
        fdprint(con->fd, tmp);
        for(;;) {
-               FD_ZERO(&rfds); 
-               FD_SET(con->fd, &rfds);
-               FD_SET(con->p[0], &rfds);
-               max = con->fd;
-               if (con->p[0] > max)
-                       max = con->p[0];
-               res = ast_select(max + 1, &rfds, NULL, NULL, NULL);
+               fds[0].fd = con->fd;
+               fds[0].events = POLLIN;
+               fds[1].fd = con->p[0];
+               fds[1].events = POLLIN;
+
+               res = poll(fds, 2, -1);
                if (res < 0) {
-                       ast_log(LOG_WARNING, "select returned < 0: %s\n", strerror(errno));
+                       ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
                        continue;
                }
-               if (FD_ISSET(con->fd, &rfds)) {
+               if (fds[0].revents) {
                        res = read(con->fd, tmp, sizeof(tmp));
                        if (res < 1) {
                                break;
@@ -256,7 +255,7 @@ static void *netconsole(void *vconsole)
                        tmp[res] = 0;
                        ast_cli_command(con->fd, tmp);
                }
-               if (FD_ISSET(con->p[0], &rfds)) {
+               if (fds[1].revents) {
                        res = read(con->p[0], tmp, sizeof(tmp));
                        if (res < 1) {
                                ast_log(LOG_ERROR, "read returned %d\n", res);
@@ -280,23 +279,23 @@ static void *netconsole(void *vconsole)
 static void *listener(void *unused)
 {
        struct sockaddr_un sun;
-       fd_set fds;
        int s;
        int len;
        int x;
        int flags;
+       struct pollfd fds[1];
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        for(;;) {
                if (ast_socket < 0)
                        return NULL;
-               FD_ZERO(&fds);
-               FD_SET(ast_socket, &fds);
-               s = ast_select(ast_socket + 1, &fds, NULL, NULL, NULL);
+               fds[0].fd = ast_socket;
+               fds[0].events= POLLIN;
+               s = poll(fds, 1, -1);
                if (s < 0) {
                        if (errno != EINTR)
-                               ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
+                               ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
                        continue;
                }
                len = sizeof(sun);
@@ -397,7 +396,7 @@ static int ast_tryconnect(void)
 
 static void urg_handler(int num)
 {
-       /* Called by soft_hangup to interrupt the select, read, or other
+       /* Called by soft_hangup to interrupt the poll, read, or other
           system call.  We don't actually need to do anything though.  */
        /* Cannot EVER ast_log from within a signal handler */
        if (option_debug) 
@@ -628,7 +627,7 @@ static void console_verboser(const char *s, int pos, int replace, int complete)
                fputs(s + pos,stdout);
        fflush(stdout);
        if (complete)
-       /* Wake up a select()ing console */
+       /* Wake up a poll()ing console */
                if (option_console && consolethread != AST_PTHREADT_NULL)
                        pthread_kill(consolethread, SIGURG);
 }
@@ -821,38 +820,38 @@ static struct ast_cli_entry astbang = { { "!", NULL }, handle_bang, "Execute a s
 
 static int ast_el_read_char(EditLine *el, char *cp)
 {
-        int num_read=0;
+    int num_read=0;
        int lastpos=0;
-       fd_set rfds;
+       struct pollfd fds[2];
        int res;
        int max;
        char buf[512];
 
        for (;;) {
-               FD_ZERO(&rfds);
-               FD_SET(ast_consock, &rfds);
-               max = ast_consock;
+               max = 1;
+               fds[0].fd = ast_consock;
+               fds[0].events = POLLIN;
                if (!option_exec) {
-                       FD_SET(STDIN_FILENO, &rfds);
-                       if (STDIN_FILENO > max)
-                               max = STDIN_FILENO;
+                       fds[1].fd = STDIN_FILENO;
+                       fds[1].events = POLLIN;
+                       max++;
                }
-               res = ast_select(max+1, &rfds, NULL, NULL, NULL);
+               res = poll(fds, max, -1);
                if (res < 0) {
                        if (errno == EINTR)
                                continue;
-                       ast_log(LOG_ERROR, "select failed: %s\n", strerror(errno));
+                       ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
                        break;
                }
 
-               if (FD_ISSET(STDIN_FILENO, &rfds)) {
+               if (!option_exec && fds[1].revents) {
                        num_read = read(STDIN_FILENO, cp, 1);
                        if (num_read < 1) {
                                break;
                        } else 
                                return (num_read);
                }
-               if (FD_ISSET(ast_consock, &rfds)) {
+               if (fds[0].revents) {
                        res = read(ast_consock, buf, sizeof(buf) - 1);
                        /* if the remote side disappears exit */
                        if (res < 1) {
@@ -1672,7 +1671,7 @@ int main(int argc, char *argv[])
 
        } else {
                /* Do nothing */
-               ast_select(0,NULL,NULL,NULL,NULL);
+               poll(NULL,0, -1);
        }
        return 0;
 }
index 035677b..82d5452 100755 (executable)
--- a/channel.c
+++ b/channel.c
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <math.h>                      /* For PI */
+#include <sys/poll.h>
 #include <asterisk/pbx.h>
 #include <asterisk/frame.h>
 #include <asterisk/sched.h>
@@ -773,32 +774,40 @@ int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen,
        return 0;
 }
 
+static inline int ast_fdisset(struct pollfd *pfds, int fd, int max)
+{
+       int x;
+       for (x=0;x<max;x++)
+               if (pfds[x].fd == fd) 
+                       return pfds[x].revents;
+       return 0;
+}
+
 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
 {
        /* Wait for x amount of time on a file descriptor to have input.  */
-       struct timeval tv;
-       fd_set rfds, efds;
+       struct timeval start, now;
        int res;
-       int x, max=-1;
+       int x, y;
        int winner = -1;
+       struct pollfd *pfds;
        
-       tv.tv_sec = *ms / 1000;
-       tv.tv_usec = (*ms % 1000) * 1000;
-       FD_ZERO(&rfds);
-       FD_ZERO(&efds);
+       pfds = alloca(sizeof(struct pollfd) * n);
+       if (!pfds) {
+               ast_log(LOG_WARNING, "alloca failed!  bad things will happen.\n");
+               return -1;
+       }
+       if (*ms > 0)
+               gettimeofday(&start, NULL);
+       y = 0;
        for (x=0;x<n;x++) {
                if (fds[x] > -1) {
-                       FD_SET(fds[x], &rfds);
-                       FD_SET(fds[x], &efds);
-                       if (fds[x] > max)
-                               max = fds[x];
+                       pfds[y].fd = fds[x];
+                       pfds[y].events = POLLIN | POLLPRI;
+                       y++;
                }
        }
-       if (*ms >= 0)
-               res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
-       else
-               res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
-
+       res = poll(pfds, y, *ms);
        if (res < 0) {
                /* Simulate a timeout if we were interrupted */
                if (errno != EINTR)
@@ -807,15 +816,29 @@ int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
                        *ms = 0;
                return -1;
        }
-
        for (x=0;x<n;x++) {
-               if ((fds[x] > -1) && (FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0)) {
-                       if (exception)
-                               *exception = FD_ISSET(fds[x], &efds);
-                       winner = fds[x];
+               if (fds[x] > -1) {
+                       if ((res = ast_fdisset(pfds, fds[x], y))) {
+                               winner = fds[x];
+                               if (exception) {
+                                       if (res & POLLPRI)
+                                               *exception = -1;
+                                       else
+                                               *exception = 0;
+                               }
+                       }
                }
        }
-       *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+       if (*ms > 0) {
+               long passed;
+               gettimeofday(&now, NULL);
+               passed = (now.tv_sec - start.tv_sec) * 1000;
+               passed += (now.tv_usec - start.tv_usec) / 1000;
+               if (passed <= *ms)
+                       *ms -= passed;
+               else
+                       *ms = 0;
+       }
        return winner;
 }
 
@@ -823,13 +846,21 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
        int *exception, int *outfd, int *ms)
 {
        /* Wait for x amount of time on a file descriptor to have input.  */
-       struct timeval tv;
-       fd_set rfds, efds;
+       struct timeval start, end;
+       struct pollfd *pfds;
        int res;
-       int x, y, max=-1;
+       long rms;
+       int x, y, max;
        time_t now = 0;
        long whentohangup = 0, havewhen = 0, diff;
        struct ast_channel *winner = NULL;
+
+       pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds));
+       if (!pfds) {
+               ast_log(LOG_WARNING, "alloca failed!  bad things will happen.\n");
+               *outfd = -1;
+               return NULL;
+       }
        if (outfd)
                *outfd = -99999;
        if (exception)
@@ -857,41 +888,35 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
                }
                ast_mutex_unlock(&c[x]->lock);
        }
-       
-       tv.tv_sec = *ms / 1000;
-       tv.tv_usec = (*ms % 1000) * 1000;
+
+       rms = *ms;
        
        if (havewhen) {
                if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
-                       tv.tv_sec = whentohangup;
-                       tv.tv_usec = 0;
+                       rms =  whentohangup * 1000;
                }
        }
-       FD_ZERO(&rfds);
-       FD_ZERO(&efds);
-
+       max = 0;
        for (x=0;x<n;x++) {
                for (y=0;y<AST_MAX_FDS;y++) {
                        if (c[x]->fds[y] > -1) {
-                               FD_SET(c[x]->fds[y], &rfds);
-                               FD_SET(c[x]->fds[y], &efds);
-                               if (c[x]->fds[y] > max)
-                                       max = c[x]->fds[y];
+                               pfds[max].fd = c[x]->fds[y];
+                               pfds[max].events = POLLIN | POLLPRI;
+                               max++;
                        }
                }
                CHECK_BLOCKING(c[x]);
        }
        for (x=0;x<nfds; x++) {
-               FD_SET(fds[x], &rfds);
-               FD_SET(fds[x], &efds);
-               if (fds[x] > max)
-                       max = fds[x];
+               if (fds[x] > -1) {
+                       pfds[max].fd = fds[x];
+                       pfds[max].events = POLLIN | POLLPRI;
+                       max++;
+               }
        }
-       if ((*ms >= 0) || (havewhen))
-               res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
-       else
-               res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
-
+       if (*ms > 0) 
+               gettimeofday(&start, NULL);
+       res = poll(pfds, max, rms);
        if (res < 0) {
                for (x=0;x<n;x++) 
                        c[x]->blocking = 0;
@@ -918,26 +943,41 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
                }
                for (y=0;y<AST_MAX_FDS;y++) {
                        if (c[x]->fds[y] > -1) {
-                               if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) {
-                                       /* Set exception flag if appropriate */
-                                       if (FD_ISSET(c[x]->fds[y], &efds))
+                               if ((res = ast_fdisset(pfds, c[x]->fds[y], max))) {
+                                       if (res & POLLPRI)
                                                c[x]->exception = 1;
-                                       c[x]->fdno = y;
+                                       else
+                                               c[x]->exception = 0;
                                        winner = c[x];
                                }
                        }
                }
        }
        for (x=0;x<nfds;x++) {
-               if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && !winner) {
-                       if (outfd)
-                               *outfd = fds[x];
-                       if (FD_ISSET(fds[x], &efds) && exception)
-                               *exception = 1;
-                       winner = NULL;
-               }
+               if (fds[x] > -1) {
+                       if ((res = ast_fdisset(pfds, fds[x], max))) {
+                               if (outfd)
+                                       *outfd = fds[x];
+                               if (exception) {        
+                                       if (res & POLLPRI) 
+                                               *exception = -1;
+                                       else
+                                               *exception = 1;
+                               }
+                               winner = NULL;
+                       }
+               }       
+       }
+       if (*ms > 0) {
+               long diff;
+               gettimeofday(&end, NULL);
+               diff = (end.tv_sec - start.tv_sec) * 1000;
+               diff += (end.tv_usec - start.tv_usec) * 1000;
+               if (diff < *ms)
+                       *ms -= diff;
+               else
+                       *ms = 0;
        }
-       *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
        return winner;
 }
 
index b46685e..abef7a5 100755 (executable)
--- a/manager.c
+++ b/manager.c
@@ -25,6 +25,7 @@
 #include <signal.h>
 #include <errno.h>
 #include <unistd.h>
+#include <sys/poll.h>
 #include <asterisk/channel.h>
 #include <asterisk/file.h>
 #include <asterisk/manager.h>
@@ -68,8 +69,7 @@ int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
        /* Try to write string, but wait no more than ms milliseconds
           before timing out */
        int res=0;
-       struct timeval tv;
-       fd_set fds;
+       struct pollfd fds[1];
        while(len) {
                res = write(fd, s, len);
                if ((res < 0) && (errno != EAGAIN)) {
@@ -78,12 +78,10 @@ int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
                if (res < 0) res = 0;
                len -= res;
                s += res;
-               tv.tv_sec = timeoutms / 1000;
-               tv.tv_usec = timeoutms % 1000;
-               FD_ZERO(&fds);
-               FD_SET(fd, &fds);
+               fds[0].fd = fd;
+               fds[0].events = POLLOUT;
                /* Wait until writable again */
-               res = select(fd + 1, NULL, &fds, NULL, &tv);
+               res = poll(fds, 1, timeoutms);
                if (res < 1)
                        return -1;
        }
@@ -715,7 +713,7 @@ static int get_input(struct mansession *s, char *output)
        /* output must have at least sizeof(s->inbuf) space */
        int res;
        int x;
-       fd_set fds;
+       struct pollfd fds[1];
        for (x=1;x<s->inlen;x++) {
                if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
                        /* Copy output data up to and including \r\n */
@@ -732,9 +730,9 @@ static int get_input(struct mansession *s, char *output)
                ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", inet_ntoa(s->sin.sin_addr), s->inbuf);
                s->inlen = 0;
        }
-       FD_ZERO(&fds);
-       FD_SET(s->fd, &fds);
-       res = ast_select(s->fd + 1, &fds, NULL, NULL, NULL);
+       fds[0].fd = s->fd;
+       fds[0].events = POLLIN;
+       res = poll(fds, 1, -1);
        if (res < 0) {
                ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
        } else if (res > 0) {