SOURCES: tpop3d-poll.patch (NEW) - new; use poll instead of select

arekm arekm at pld-linux.org
Thu Jun 22 17:46:00 CEST 2006


Author: arekm                        Date: Thu Jun 22 15:46:00 2006 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- new; use poll instead of select

---- Files affected:
SOURCES:
   tpop3d-poll.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/tpop3d-poll.patch
diff -u /dev/null SOURCES/tpop3d-poll.patch:1.1
--- /dev/null	Thu Jun 22 17:46:00 2006
+++ SOURCES/tpop3d-poll.patch	Thu Jun 22 17:45:55 2006
@@ -0,0 +1,268 @@
+diff -ur tpop3d-1.5.3.org/connection.h tpop3d-1.5.3/connection.h
+--- tpop3d-1.5.3.org/connection.h	2003-01-09 23:59:37.000000000 +0100
++++ tpop3d-1.5.3/connection.h	2006-06-22 17:29:20.000000000 +0200
+@@ -15,6 +15,7 @@
+ #include <netinet/in.h>
+ #include <sys/socket.h>
+ #include <sys/types.h>
++#include <sys/poll.h>
+ 
+ #include "authswitch.h"
+ #include "buffer.h"
+@@ -89,13 +90,13 @@
+      * buffering and state issues. post_select should return a combination of
+      * the flags defined below, as well as doing any I/O-layer specific
+      * handling. */
+-    void (*pre_select)(connection c, int *n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
++    void (*pre_select)(connection c, int *n, struct pollfd *pfds);
+     
+     /* post_select:
+      * Do handling after select has completed. Returns 1 if new data have been
+      * read, 0 if not. May alter the connection_state of the associated
+      * connection. */
+-    int (*post_select)(connection c, fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
++    int (*post_select)(connection c, struct pollfd *pfds);
+ 
+     /* shutdown:
+      * Shut down the connection. Returns zero on success, IOABS_WOULDBLOCK if
+diff -ur tpop3d-1.5.3.org/ioabs_tcp.c tpop3d-1.5.3/ioabs_tcp.c
+--- tpop3d-1.5.3.org/ioabs_tcp.c	2003-09-30 20:45:46.000000000 +0200
++++ tpop3d-1.5.3/ioabs_tcp.c	2006-06-22 17:42:03.000000000 +0200
+@@ -17,7 +17,7 @@
+ #include <time.h>
+ #include <unistd.h>
+ 
+-#include <sys/select.h>
++#include <sys/poll.h>
+ 
+ #include "connection.h"
+ #include "util.h"
+@@ -61,13 +61,14 @@
+ 
+ /* ioabs_tcp_pre_select:
+  * Simple pre-select handling for TCP. */
+-static void ioabs_tcp_pre_select(connection c, int *n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) {
++static void ioabs_tcp_pre_select(connection c, int *n, struct pollfd *pfds) {
+     struct ioabs_tcp *io;
+     io = (struct ioabs_tcp*)c->io;
+ 
+-    FD_SET(c->s, readfds);
++    pfds[c->s].fd = c->s;
++    pfds[c->s].events |= POLLIN;
+     if (buffer_available(c->wrb) > 0)
+-        FD_SET(c->s, writefds);
++	pfds[c->s].events |= POLLOUT;
+     
+     if (c->s > *n)
+         *n = c->s;
+@@ -75,13 +76,13 @@
+ 
+ /* ioabs_tcp_post_select:
+  * Simple post-select handling for TCP. */
+-static int ioabs_tcp_post_select(connection c, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) {
++static int ioabs_tcp_post_select(connection c, struct pollfd *pfds) {
+     int ret = 0;
+     ssize_t n;
+     struct ioabs_tcp *io;
+     io = (struct ioabs_tcp*)c->io;
+ 
+-    if (FD_ISSET(c->s, readfds)) {
++    if (pfds[c->s].revents == POLLIN) {
+         /* Can read data. */
+         do {
+             char *r;
+@@ -110,7 +111,7 @@
+         }
+     }
+ 
+-    if (FD_ISSET(c->s, writefds) && buffer_available(c->wrb) > 0) {
++    if (pfds[c->s].revents == POLLOUT && buffer_available(c->wrb) > 0) {
+         /* Can write data. */
+         n = 1;
+         do {
+diff -ur tpop3d-1.5.3.org/ioabs_tls.c tpop3d-1.5.3/ioabs_tls.c
+--- tpop3d-1.5.3.org/ioabs_tls.c	2006-06-22 11:21:16.000000000 +0200
++++ tpop3d-1.5.3/ioabs_tls.c	2006-06-22 17:42:14.000000000 +0200
+@@ -21,7 +21,7 @@
+ 
+ #include <openssl/ssl.h>
+ 
+-#include <sys/select.h>
++#include <sys/poll.h>
+ 
+ #include "connection.h"
+ #include "listener.h"
+@@ -228,15 +228,16 @@
+ 
+ /* ioabs_tls_pre_select:
+  * Pre-select handling for TLS, taking account of the rehandshaking nonsense. */
+-static void ioabs_tls_pre_select(connection c, int *n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) {
++static void ioabs_tls_pre_select(connection c, int *n, struct pollfd *pfds) {
+     struct ioabs_tls *io;
+     io = (struct ioabs_tls*)c->io;
+ 
+-    FD_SET(c->s, readfds);  /* always want to read */
++    pfds[c->s].fd = c->s;
++    pfds[c->s].events |= POLLIN; /* always want to read */
+     if (!io->write_blocked_on_read &&
+         (buffer_available(c->wrb) > 0 || io->accept_blocked_on_write
+          || io->read_blocked_on_write || io->shutdown_blocked_on_write))
+-        FD_SET(c->s, writefds);
++        pfds[c->s].events |= POLLOUT;
+ 
+     if (c->s > *n)
+         *n = c->s;
+@@ -244,15 +245,15 @@
+ 
+ /* ioabs_tls_post_select:
+  * Post-select handling for TLS, with its complicated logic. */
+-static int ioabs_tls_post_select(connection c, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) {
++static int ioabs_tls_post_select(connection c, struct pollfd *pfds) {
+     int ret = 0, R = 0;
+     ssize_t n, wtotal;
+     int canread, canwrite;
+     struct ioabs_tls *io;
+     io = (struct ioabs_tls*)c->io;
+ 
+-    canread  = FD_ISSET(c->s, readfds);
+-    canwrite = FD_ISSET(c->s, writefds);
++    canread  = pfds[c->s].revents == POLLIN;
++    canwrite = pfds[c->s].revents == POLLOUT;
+     
+     /* First, accept handling. */
+     if ((io->accept_blocked_on_read && canread) || (io->accept_blocked_on_write && canwrite)) {
+diff -ur tpop3d-1.5.3.org/netloop.c tpop3d-1.5.3/netloop.c
+--- tpop3d-1.5.3.org/netloop.c	2006-06-22 11:21:17.000000000 +0200
++++ tpop3d-1.5.3/netloop.c	2006-06-22 17:38:21.000000000 +0200
+@@ -30,6 +30,7 @@
+ 
+ #include <sys/socket.h>
+ #include <sys/time.h>
++#include <sys/poll.h>
+ 
+ #include "config.h"
+ #include "connection.h"
+@@ -105,11 +106,12 @@
+ 
+ /* listeners_pre_select:
+  * Called before the main select(2) so listening sockets can be polled. */
+-static void listeners_pre_select(int *n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) {
++static void listeners_pre_select(int *n, struct pollfd *pfds) {
+     item *t;
+     vector_iterate(listeners, t) {
+         int s = ((listener)t->v)->s;
+-        FD_SET(s, readfds);
++	pfds[s].fd = s;
++	pfds[s].events |= POLLIN;
+         if (s > *n) *n = s;
+     }
+ }
+@@ -117,11 +119,11 @@
+ /* listeners_post_select:
+  * Called after the main select(2) to allow listening sockets to sort
+  * themselves out. */
+-static void listeners_post_select(fd_set *readfds, fd_set *writefds, fd_set *exceptfds) {
++static void listeners_post_select(struct pollfd *pfds) {
+     item *t;
+     vector_iterate(listeners, t) {
+         listener L = (listener)t->v;
+-        if (FD_ISSET(L->s, readfds)) {
++	if (pfds[L->s].revents == POLLIN) {
+             struct sockaddr_in sin, sinlocal;
+             size_t l = sizeof(sin);
+             static int tcp_send_buf = -1;
+@@ -192,12 +194,12 @@
+ 
+ /* connections_pre_select:
+  * Called before the main select(2) so connections can be polled. */
+-static void connections_pre_select(int *n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) {
++static void connections_pre_select(int *n, struct pollfd *pfds) {
+     connection *J;
+     for (J = connections; J < connections + max_connections; ++J)
+         /* Don't add frozen connections to the select masks. */
+         if (*J && !connection_isfrozen(*J) && (*J)->cstate != closed)
+-            (*J)->io->pre_select(*J, n, readfds, writefds, exceptfds);
++            (*J)->io->pre_select(*J, n, pfds);
+ }
+ 
+ /* fork_child CONNECTION
+@@ -380,7 +382,7 @@
+  * running/closing/closed state machine around and reading and writing the I/O
+  * buffers. We need to try to parse commands when it's indicated that data have
+  * been read, and react to the changed state of any connection. */
+-static void connections_post_select(fd_set *readfds, fd_set *writefds, fd_set *exceptfds) {
++static void connections_post_select(struct pollfd *pfds) {
+     static size_t i;
+     size_t i0;
+     time_t start;
+@@ -400,7 +402,7 @@
+         }
+ 
+         /* Handle all post-select I/O. */
+-        r = c->io->post_select(c, readfds, writefds, exceptfds);
++        r = c->io->post_select(c, pfds);
+ 
+         if (r && !connection_isfrozen(c)) {
+             /*
+@@ -528,6 +530,7 @@
+     extern pid_t child_died;
+     extern int child_died_signal;
+     sigset_t chmask;
++    struct pollfd *pfds;
+     
+     sigemptyset(&chmask);
+     sigaddset(&chmask, SIGCHLD);
+@@ -536,32 +539,33 @@
+     max_connections = 2 * max_running_children;
+     connections = (connection*)xcalloc(max_connections, sizeof(connection*));
+ 
++    pfds = malloc(max_connections * sizeof(struct pollfd));
++    if (pfds == NULL) {
++	log_print(LOG_ERR, "net_loop: couldn't allocate memory for poll data");
++	return;
++    }
++
+     log_print(LOG_INFO, _("net_loop: tpop3d version %s successfully started"), TPOP3D_VERSION);
+     
+     /* Main select() loop */
+     while (!foad) {
+-        fd_set readfds, writefds;
+-        struct timeval tv = {0};
+         int n = 0, e;
+ 
+-        FD_ZERO(&readfds);
+-        FD_ZERO(&writefds);
++	memset(pfds, 0, max_connections * sizeof(struct pollfd));
+ 
+-        tv.tv_sec = 1;  /* must be smaller than timeout */
++        if (!post_fork) listeners_pre_select(&n, pfds);
+ 
+-        if (!post_fork) listeners_pre_select(&n, &readfds, &writefds, NULL);
++        connections_pre_select(&n, pfds);
+ 
+-        connections_pre_select(&n, &readfds, &writefds, NULL);
+-
+-        e = select(n + 1, &readfds, &writefds, NULL, &tv);
++	e = poll(pfds, n + 1, 200);
+         if (e == -1 && errno != EINTR) {
+-            log_print(LOG_WARNING, "net_loop: select: %m");
++            log_print(LOG_WARNING, "net_loop: poll: %m");
+         } else if (e >= 0) {
+             /* Check for new incoming connections */
+-            if (!post_fork) listeners_post_select(&readfds, &writefds, NULL);
++            if (!post_fork) listeners_post_select(pfds);
+ 
+             /* Monitor existing connections */
+-            connections_post_select(&readfds, &writefds, NULL);
++            connections_post_select(pfds);
+         }
+ 
+         sigprocmask(SIG_BLOCK, &chmask, NULL);
+@@ -596,5 +600,7 @@
+             if (*J) connection_delete(*J);
+         xfree(connections);
+     }
++
++    free(pfds);
+ }
+ 
================================================================


More information about the pld-cvs-commit mailing list