[Asterisk-cvs] asterisk asterisk.c,1.72,1.73 channel.c,1.99,1.100 manager.c,1.44,1.45

markster at lists.digium.com markster at lists.digium.com
Sun Apr 25 16:37:00 CDT 2004


Update of /usr/cvsroot/asterisk
In directory mongoose.digium.com:/tmp/cvs-serv23905

Modified Files:
	asterisk.c channel.c manager.c 
Log Message:
Properly migrate from select to poll for core asterisk.


Index: asterisk.c
===================================================================
RCS file: /usr/cvsroot/asterisk/asterisk.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -d -r1.72 -r1.73
--- asterisk.c	24 Apr 2004 23:11:28 -0000	1.72
+++ asterisk.c	25 Apr 2004 20:42:45 -0000	1.73
@@ -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 @@
 	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 @@
 			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 *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 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 @@
 		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 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 @@
 
 	} else {
  		/* Do nothing */
-		ast_select(0,NULL,NULL,NULL,NULL);
+		poll(NULL,0, -1);
 	}
 	return 0;
 }

Index: channel.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channel.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -d -r1.99 -r1.100
--- channel.c	24 Apr 2004 23:11:28 -0000	1.99
+++ channel.c	25 Apr 2004 20:42:45 -0000	1.100
@@ -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>
@@ -776,29 +777,29 @@
 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;
+	int spoint;
+	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 +808,30 @@
 			*ms = 0;
 		return -1;
 	}
-
+	spoint = 0;
 	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, &spoint))) {
+				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 +839,23 @@
 	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;
+	int spoint;
 	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 +883,35 @@
 		}
 		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;
@@ -909,6 +929,7 @@
 
 	if (havewhen)
 		time(&now);
+	spoint = 0;
 	for (x=0;x<n;x++) {
 		c[x]->blocking = 0;
 		if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
@@ -918,10 +939,11 @@
 		}
 		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))
-						c[x]->exception = 1;
+				if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) {
+					if (res & POLLPRI)
+						c[x]->exception = -1;
+					else
+						c[x]->exception = 0;
 					c[x]->fdno = y;
 					winner = c[x];
 				}
@@ -929,15 +951,30 @@
 		}
 	}
 	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, &spoint))) {
+				if (outfd)
+					*outfd = fds[x];
+				if (exception) {	
+					if (res & POLLPRI) 
+						*exception = -1;
+					else
+						*exception = 0;
+				}
+				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: manager.c
===================================================================
RCS file: /usr/cvsroot/asterisk/manager.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- manager.c	24 Apr 2004 23:11:28 -0000	1.44
+++ manager.c	25 Apr 2004 20:42:45 -0000	1.45
@@ -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 @@
 	/* 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 @@
 		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 @@
 	/* 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 @@
 		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) {




More information about the svn-commits mailing list