diff --git a/TODO b/TODO index 6bfe265..a79ee16 100644 --- a/TODO +++ b/TODO @@ -6,3 +6,6 @@ VERY BIG TODO: - handle errors after all system call...especially open, close, etc. - IPV6 support + +- There seem to be a problem in the server under heavy load. Some tests with ab show that at some point it does not accept any more connections. Nor does it seem to answer request. I guess that it might be difficult to find this.... + => might be done... diff --git a/src/server/poll.c b/src/server/poll.c index cf061c8..95bec71 100644 --- a/src/server/poll.c +++ b/src/server/poll.c @@ -58,21 +58,23 @@ serverPoll(Server this) { /* * wait for handles to become ready */ - if (-1 == (events = poll(this->fds, this->nfds, -1))) { - switch (errno) { - default: - case EBADF: - case EINVAL: - case ENOMEM: - doShutdown = 1; - // DROP THROUGH + do { + if (-1 == (events = poll(this->fds, this->nfds, -1))) { + switch (errno) { + default: + case EBADF: + case EINVAL: + case ENOMEM: + doShutdown = 1; + // DROP THROUGH - case EINTR: - loggerLog(this->logger, LOGGER_CRIT, - "poll systemcall failed: [%s] - service terminated", - strerror(errno)); + case EINTR: + loggerLog(this->logger, LOGGER_CRIT, + "poll systemcall failed: [%s] - service terminated", + strerror(errno)); + } } - } + } while (! doShutdown && 0 >= events); return events; } diff --git a/src/server/read.c b/src/server/read.c index a8add3e..4be6eab 100644 --- a/src/server/read.c +++ b/src/server/read.c @@ -20,6 +20,8 @@ * along with this program. If not, see . */ +#include + #include "server.h" #include "logger.h" #include "stream.h" @@ -44,6 +46,16 @@ serverRead(Server this, unsigned int i) (this->conns)[fd].worker, (this->conns)[fd].stream))) { + case -1: + /* + * read failure + */ + if (errno == EAGAIN || errno == EWOULDBLOCK) { + /* on EGAIN just try again later. */ + break; + } + // DROP-THROUGH + case -2: /** * normal close: this must be mapped to -2 within the @@ -52,18 +64,17 @@ serverRead(Server this, unsigned int i) * \todo make sure all pending writes will be done before * close. */ - // DROP-THROUGH - case -1: /* - * read failure / close connection + * close connection if not EAGAIN, this would also + * remove the filedescriptor from the poll list. + * Else just return indicate */ loggerLog(this->logger, LOGGER_INFO, "connection[%d] closed...%s", fd, inet_ntoa((((this->conns)[fd].sock)->addr).sin_addr)); serverCloseConn(this, i); - break; case 0: break; diff --git a/src/server/run.c b/src/server/run.c index 3ba416c..b44741f 100644 --- a/src/server/run.c +++ b/src/server/run.c @@ -38,20 +38,20 @@ serverRun(Server this) while (!doShutdown) //! until error or signal { - int events; + int events = 0; unsigned int i; - int naccs = 10; - events = serverPoll(this); - if (doShutdown || 0 >= events) break; + if (0 == events) { + events = serverPoll(this); + } /** * handle accept */ if (0 != ((this->fds)[0].revents & POLLIN)) { - events--; - while(-1 != serverHandleAccept(this, 0) && 0 < naccs) { - naccs--; + if (-1 == serverHandleAccept(this, 0)) { + (this->fds)[0].revents |= ~POLLIN; + events--; } } @@ -59,33 +59,31 @@ serverRun(Server this) * handle accept SSL */ if (0 != ((this->fds)[1].revents & POLLIN)) { - events--; - while(-1 != serverHandleAccept(this, 1) && 0 < naccs) { - naccs--; + if (-1 == serverHandleAccept(this, 1)) { + (this->fds)[1].revents |= ~POLLIN; + events--; } } for (i=2; i < this->nfds; i++) { - int nreads = 10, nwrites = 10; - /** * handle reads */ - if (0 != ((this->fds)[i].revents & POLLIN) && 0 < nreads) { - events--; - nreads--; - - serverRead(this, i); + if (0 != ((this->fds)[i].revents & POLLIN)) { + if (0 < serverRead(this, i)) { + (this->fds)[i].revents |= ~POLLIN; + events--; + } } /** * handle writes */ - if (0 != ((this->fds)[i].revents & POLLOUT) && 0 < nwrites) { - events--; - nwrites--; - - serverWrite(this, i); + if (0 != ((this->fds)[i].revents & POLLOUT)) { + if (0 < serverWrite(this, i)) { + (this->fds)[i].revents |= ~POLLOUT; + events--; + } } if (0 > events)