Hi,
This patch completes the support of Solaris 10 event ports for Cherokee. I guess Cherokee is the first ever web server with Solaris 10 event ports!! . Thanks to Cherokee's modular architecture it was very easy to do. Congratulations Alo.
Best regards, Rodrigo
--- cherokee-0.4.22.old/cherokee/fdpoll-port.c 2005-05-20 08:29:58.000000000 +0100 +++ cherokee-0.4.22/cherokee/fdpoll-port.c 2005-05-20 08:30:07.000000000 +0100 @@ -29,6 +29,16 @@ #include <poll.h> #include <port.h> #include <unistd.h> +#include <errno.h> + +#define WRITE "" +#define READ NULL + +#define POLL_READ (POLLIN) +#define POLL_WRITE (POLLOUT) +#define POLL_ERROR (POLLHUP | POLLERR | POLLNVAL) + + /***********************************************************************/ /* Solaris 10: Event ports */ @@ -51,17 +61,45 @@ typedef struct { struct cherokee_fdpoll poll; - int port; + int port; + port_event_t *port_events; + int *port_activefd; + int port_readyfds; } cherokee_fdpoll_port_t; +static ret_t +fd_associate( cherokee_fdpoll_port_t *fdp, int fd, void *rw ) +{ + int rc; + + rc = port_associate (fdp->port, /* port */ + PORT_SOURCE_FD, /* source */ + fd, /* object */ + rw?POLL_WRITE:POLL_READ, /* events */ + rw); /* user data */ + + if ( rc == -1 ) { + PRINT_ERROR ("ERROR: port_associate: fd %d: %s\n", fd, + strerror(errno)); + return ret_error; + } + + return ret_ok; +} + static ret_t _free (cherokee_fdpoll_port_t *fdp) { - port_close (fdp->port); - - free (fdp); + if ( fdp->port > 0 ) { + close (fdp->port); + } + + free( fdp->port_events ); + free( fdp->port_activefd ); + + free( fdp ); return ret_ok; } @@ -69,72 +107,144 @@ static ret_t _add (cherokee_fdpoll_port_t *fdp, int fd, int rw) { -/* int port_associate (int port, - int source, - uintptr_t object, - int events, - void *user);*/ - - - port_associate (fdp->port, /* port */ - PORT_SOURCE_FD, /* source */ - fd, /* object */ - rw?POLLOUT:POLLIN, /* events */ - NULL); /* user */ + int rc; + + rc = fd_associate(fdp, fd, rw?WRITE:READ); + if ( rc == -1 ) { + PRINT_ERROR ("ERROR: port_associate: fd %d: %s\n", fd, + strerror(errno)); + return ret_error; + } + + FDPOLL(fdp)->npollfds++; + return ret_ok; } static ret_t _del (cherokee_fdpoll_port_t *fdp, int fd) { + int rc; + + rc = port_dissociate( fdp->port, /* port */ + PORT_SOURCE_FD, /* source */ + fd); /* object */ + if ( rc == -1 ) { + PRINT_ERROR ("ERROR: port_dissociate: %d,%s\n", fd, + strerror(errno)); + return ret_error; + } + + FDPOLL(fdp)->npollfds--; + + /* remote fd from the active fd list + */ + fdp->port_activefd[fd] = -1; + + return ret_ok; } static int _watch (cherokee_fdpoll_port_t *fdp, int timeout_msecs) { - int re; - int i, fd; - uint_t nget; - timespec_t to; - port_event_t pe[5]; + int i, rc, fd; + struct timespec timeout; - to.tv_sec = timeout_msecs / 1000L; - to.tv_nsec = ( timeout_msecs % 1000L ) * 1000000L; - - re = port_getn (fdp->port, &pe, 5, &nget, &to); - if ((re) || (nget == -1)) { - /* port_close, close ? */ - return ret_error; + timeout.tv_sec = timeout_msecs/1000L; + timeout.tv_nsec = ( timeout_msecs % 1000L ) * 1000000L; + + /* memset(fdp->port_events, 0, FDPOLL(fdp)->nfiles); */ + memset(fdp->port_activefd, -1, FDPOLL(fdp)->system_nfiles); + + /* First call to get the number of file descriptors with activity + */ + rc = port_getn (fdp->port, fdp->port_events, 0, &fdp->port_readyfds, + &timeout); + if ( rc < 0 ) { + PRINT_ERROR ("ERROR: port_getn: %s\n", strerror(errno)); + return 0; + } + if ( fdp->port_readyfds == 0 ) { + /* Get at least 1 fd to wait for activity + */ + fdp->port_readyfds = 1; + } + /* Second call to get the events of the file descriptors with + * activity + */ + rc = port_getn (fdp->port, fdp->port_events,FDPOLL(fdp)->nfiles, + &fdp->port_readyfds, &timeout); + if ( ( (rc < 0) && (errno != ETIME) ) || (fdp->port_readyfds == -1)) { + PRINT_ERROR ("ERROR: port_getn: %s\n", strerror(errno)); + return 0; } - fd = pe.portev_object; - printf ("fd = %d\n", fd); - -/* - int port_get(int port, port_event_t *pe, const timespec_t - *timeout); - - int port_getn(int port, port_event_t list[], uint_t max, - uint_t *nget, const timespec_t *timeout); -*/ + for ( i = 0; i < fdp->port_readyfds; ++i ) { + int nfd; + + nfd = fdp->port_events[i].portev_object; + fdp->port_activefd[nfd] = fdp->port_events[i].portev_events; + rc = fd_associate( fdp, + nfd, + fdp->port_events[i].portev_user); + if ( rc < 0 ) { + PRINT_ERROR ("ERROR: port_associate: %s\n", + strerror(errno)); + } + } + + + return fdp->port_readyfds; } static int _check (cherokee_fdpoll_port_t *fdp, int fd, int rw) { + uint32_t events; + + /* Sanity check: is it a wrong fd? + */ + if ( fd < 0 ) return -1; + + events = fdp->port_activefd[fd]; + if ( events == -1 ) return 0; + + switch (rw) { + case 0: + events &= (POLL_READ | POLL_ERROR); + break; + case 1: + events &= (POLL_WRITE | POLL_ERROR); + break; + } + + return events; } static ret_t _reset (cherokee_fdpoll_port_t *fdp, int fd) { + return ret_ok; } + static void _set_mode (cherokee_fdpoll_port_t *fdp, int fd, int rw) { + int rc; + + rc = port_associate( fdp->port, + PORT_SOURCE_FD, + fd, + rw?POLLOUT:POLLIN, + NULL); + if ( rc == -1 ) { + PRINT_ERROR ("ERROR: port_associate: fd %d: %s\n", fd, + strerror(errno)); + } } @@ -163,9 +273,23 @@ nfd->check = (fdpoll_func_check_t) _check; nfd->watch = (fdpoll_func_watch_t) _watch; - /* Look for max fd limit + /* */ - n->port = port_create(); + n->port_readyfds = 0; + n->port_events = ( port_event_t *)malloc(sizeof(port_event_t)*nfd->nfiles); + n->port_activefd = (int *)malloc(sizeof(int) * nfd->system_nfiles); + + if ( (!n->port_events) || (!n->port_activefd) ) { + _free( n ); + return ret_nomem; + } + + memset(n->port_activefd, -1, nfd->system_nfiles); + + if ( (n->port = port_create()) == -1 ) { + _free( n ); + return ret_error; + } /* Return the object */
_______________________________________________ Cherokee mailing list Cherokee@lists.alobbs.com http://www.alobbs.com/cgi-bin/mailman/listinfo/cherokee