[NeoStats-Devel] [Commits] r2709 - in trunk: . lib/event lib/event/WIN32-Code src
[email protected] Sat, 13 Aug 2005 17:06:04 +1000
| Newsgroups | gmane.comp.neostats.devel |
|---|---|
| Message-ID | <[email protected]> |
Author: Fish
Date: Sat Aug 13 15:05:58 2005
New Revision: 2709
Modified:
trunk/ChangeLog
trunk/TODO
trunk/lib/event/WIN32-Code/config.h
trunk/lib/event/WIN32-Code/win32.c
trunk/lib/event/buffer.c
trunk/lib/event/devpoll.c
trunk/lib/event/epoll.c
trunk/lib/event/epoll_sub.c
trunk/lib/event/evbuffer.c
trunk/lib/event/event.c
trunk/lib/event/event.h
trunk/lib/event/kqueue.c
trunk/lib/event/log.c
trunk/lib/event/log.h
trunk/lib/event/poll.c
trunk/lib/event/rtsig.c
trunk/lib/event/select.c
trunk/lib/event/signal.c
trunk/src/main.c
Log:
sync up libevent.
Modified: trunk/ChangeLog
==============================================================================
--- trunk/ChangeLog (original)
+++ trunk/ChangeLog Sat Aug 13 15:05:58 2005
@@ -4,6 +4,7 @@
Fish (F), Mark (M), DeadNotBuried (D)
===============================================================================
* NeoStats * Version 3.0.a3-dev
+ - Sync up libevent to distribution of 1.1a (F)
- Make QuoteServ take a optional database for Quote Command (F)
- Fix up triggering WANT_NICKIP code (F)
- Fix up quoteserv and un-init memory errors causing crashes for me (F)
Modified: trunk/TODO
==============================================================================
--- trunk/TODO (original)
+++ trunk/TODO Sat Aug 13 15:05:58 2005
@@ -8,3 +8,10 @@
<StatServ> rollergirl.sg.as.irc-chat.net is lagged out with a ping of 1123867742
=FloodServ= HOST: - default host is always empty
+
+unloading connectserv segv's neostats
+
+My NeoStats is using 29Mb of memory on 150 users.... most modules loaded. Valgrind is overdue
+just to check memory allocations
+
+hostserv unet style vhosts is broken?
Modified: trunk/lib/event/WIN32-Code/config.h
==============================================================================
--- trunk/lib/event/WIN32-Code/config.h (original)
+++ trunk/lib/event/WIN32-Code/config.h Sat Aug 13 15:05:58 2005
@@ -1,149 +1,231 @@
-/* config.h. Generated by configure. */
-/* config.h.in. Generated from configure.in by autoheader. */
+/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define if kqueue works correctly with pipes */
-/* #undef HAVE_WORKING_KQUEUE */
+#undef HAVE_WORKING_KQUEUE
/* Define to `unsigned long long' if <sys/types.h> doesn't define. */
-/* #undef u_int64_t */
+#undef u_int64_t
/* Define to `unsigned int' if <sys/types.h> doesn't define. */
-/* #undef u_int32_t */
+#undef u_int32_t
/* Define to `unsigned short' if <sys/types.h> doesn't define. */
-/* #undef u_int16_t */
+#undef u_int16_t
/* Define to `unsigned char' if <sys/types.h> doesn't define. */
-/* #undef u_int8_t */
+#undef u_int8_t
/* Define if timeradd is defined in <sys/time.h> */
-/* #undef HAVE_TIMERADD */
+#undef HAVE_TIMERADD
#ifndef HAVE_TIMERADD
-#define timeradd(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
- if ((vvp)->tv_usec >= 1000000) { \
- (vvp)->tv_sec++; \
- (vvp)->tv_usec -= 1000000; \
- } \
- } while (0)
-#define timersub(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
- if ((vvp)->tv_usec < 0) { \
- (vvp)->tv_sec--; \
- (vvp)->tv_usec += 1000000; \
- } \
- } while (0)
+#undef timersub
+#define timeradd(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
+ if ((vvp)->tv_usec >= 1000000) { \
+ (vvp)->tv_sec++; \
+ (vvp)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+#define timersub(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
#endif /* !HAVE_TIMERADD */
+#undef HAVE_TIMERCLEAR
+#ifndef HAVE_TIMERCLEAR
+#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
+#endif
+
+#define HAVE_TIMERCMP
+#ifndef HAVE_TIMERCMP
+#undef timercmp
+#define timercmp(tvp, uvp, cmp) \
+ (((tvp)->tv_sec == (uvp)->tv_sec) ? \
+ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec))
+#endif
+
+#undef HAVE_TIMERISSET
+#ifndef HAVE_TIMERISSET
+#undef timerisset
+#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#endif
+
/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
-#define HAVE_TAILQFOREACH 1
+#define HAVE_TAILQFOREACH
#ifndef HAVE_TAILQFOREACH
-#define TAILQ_FIRST(head) ((head)->tqh_first)
-#define TAILQ_END(head) NULL
-#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-#define TAILQ_FOREACH(var, head, field) \
- for((var) = TAILQ_FIRST(head); \
- (var) != TAILQ_END(head); \
- (var) = TAILQ_NEXT(var, field))
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
- (elm)->field.tqe_next = (listelm); \
- *(listelm)->field.tqe_prev = (elm); \
- (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#define TAILQ_END(head) NULL
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+#define TAILQ_FOREACH(var, head, field) \
+ for((var) = TAILQ_FIRST(head); \
+ (var) != TAILQ_END(head); \
+ (var) = TAILQ_NEXT(var, field))
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#endif /* TAILQ_FOREACH */
-/* Define to 1 if you have the `gettimeofday' function. */
+
+/* Define if /dev/poll is available */
+#undef HAVE_DEVPOLL
+
+/* Define if your system supports the epoll system calls */
+#undef HAVE_EPOLL
+
+/* Define if you have the `epoll_ctl' function. */
+#undef HAVE_EPOLL_CTL
+
+/* Define if you have the `err' function. */
+#undef HAVE_ERR
+
+/* Define if you have the `fcntl' function. */
+#undef HAVE_FCNTL
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
-/* Define to 1 if you have the <inttypes.h> header file. */
+/* Define if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
-/* Define to 1 if you have the `kqueue' function. */
-/* #undef HAVE_KQUEUE */
+/* Define if you have the `kqueue' function. */
+#undef HAVE_KQUEUE
+
+/* Define if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
-/* Define to 1 if you have the <memory.h> header file. */
+/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
-/* Define to 1 if you have the `select' function. */
-/* #undef HAVE_SELECT */
+/* Define if you have the `poll' function. */
+#undef HAVE_POLL
+
+/* Define if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define if your system supports POSIX realtime signals */
+#undef HAVE_RTSIG
+
+/* Define if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define if F_SETFD is defined in <fcntl.h> */
+#undef HAVE_SETFD
+
+/* Define if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define if you have the `sigtimedwait' function. */
+#undef HAVE_SIGTIMEDWAIT
-/* Define to 1 if you have the <stdint.h> header file. */
-/* #undef HAVE_STDINT_H */
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
-/* Define to 1 if you have the <stdlib.h> header file. */
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
-/* Define to 1 if you have the <string.h> header file. */
+/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
-/* Define to 1 if you have the <sys/event.h> header file. */
-#define HAVE_SYS_EVENT_H 1
+/* Define if you have the <sys/devpoll.h> header file. */
+#undef HAVE_SYS_DEVPOLL_H
+
+/* Define if you have the <sys/epoll.h> header file. */
+#undef HAVE_SYS_EPOLL_H
+
+/* Define if you have the <sys/event.h> header file. */
+#undef HAVE_SYS_EVENT_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
-/* Define to 1 if you have the <sys/queue.h> header file. */
-#define HAVE_SYS_QUEUE_H 1
+/* Define if you have the <sys/queue.h> header file. */
+#undef HAVE_SYS_QUEUE_H
-/* Define to 1 if you have the <sys/stat.h> header file. */
+/* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
-/* Define to 1 if you have the <sys/time.h> header file. */
-/* #undef HAVE_SYS_TIME_H */
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
-/* Define to 1 if you have the <sys/types.h> header file. */
+/* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
-/* Define to 1 if you have the <unistd.h> header file. */
-/* #undef HAVE_UNISTD_H */
+/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
+#undef HAVE_TAILQFOREACH
+
+/* Define if timeradd is defined in <sys/time.h> */
+#undef HAVE_TIMERADD
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
-/* Define to 1 if you have the `warnx' function. */
-#define HAVE_WARNX 1
+/* Define if you have the `vasprintf' function. */
+#undef HAVE_VASPRINTF
+
+/* Define if kqueue works correctly with pipes */
+#undef HAVE_WORKING_KQUEUE
+
+/* Define if realtime signals work on pipes */
+#undef HAVE_WORKING_RTSIG
/* Name of package */
#define PACKAGE "libevent"
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
+/* Version number of package */
+#define VERSION "1.0b"
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
+/* Define as `__inline' if that's what the C compiler calls it, or to nothing
+ if it is not supported. */
+#define inline __inline
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#define TIME_WITH_SYS_TIME 1
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
-/* Version number of package */
-#define VERSION "0.6"
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
-typedef unsigned char u_char;
+/* Define to unsigned int if you dont have it */
+#undef socklen_t
-/* Winsock compatibility */
-#define SHUT_WR SD_SEND
+/* Define to `unsigned short' if <sys/types.h> does not define. */
+#undef u_int16_t
-struct timeval;
-struct timezone;
-int gettimeofday(struct timeval *tv, struct timezone *tz);
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef u_int32_t
-#define read win_read
-#define write win_write
+/* Define to `unsigned long long' if <sys/types.h> does not define. */
+/* #undef u_int64_t */
-int win_read(int, void *, unsigned int);
-int win_write(int, void *, unsigned int);
-int socketpair(int d, int type, int protocol, int *sv);
+/* Define to `unsigned char' if <sys/types.h> does not define. */
+/* #undef u_int8_t */
-#define __func__ __FILE__
\ No newline at end of file
+/* Define to __FUNCTION__ or __file__ if your compiler doesn't have __func__ */
+#define __func__ __FUNCTION__
Modified: trunk/lib/event/WIN32-Code/win32.c
==============================================================================
--- trunk/lib/event/WIN32-Code/win32.c (original)
+++ trunk/lib/event/WIN32-Code/win32.c Sat Aug 13 15:05:58 2005
@@ -391,7 +391,7 @@
{
struct event *ev;
short ncalls;
-
+
TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
ncalls = evsigcaught[EVENT_SIGNAL(ev)];
if (ncalls) {
Modified: trunk/lib/event/buffer.c
==============================================================================
--- trunk/lib/event/buffer.c (original)
+++ trunk/lib/event/buffer.c Sat Aug 13 15:05:58 2005
@@ -25,14 +25,16 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define _GNU_SOURCE
-#include <sys/types.h>
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#ifdef HAVE_VASPRINTF
+/* If we have vasprintf, we need to define this before we include stdio.h. */
+#define _GNU_SOURCE
+#endif
+#include <sys/types.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
@@ -174,9 +176,56 @@
return (nread);
}
+/*
+ * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'.
+ * The returned buffer needs to be freed by the called.
+ */
+
+char *
+evbuffer_readline(struct evbuffer *buffer)
+{
+ char *data = EVBUFFER_DATA(buffer);
+ size_t len = EVBUFFER_LENGTH(buffer);
+ char *line;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (data[i] == '\r' || data[i] == '\n')
+ break;
+ }
+
+ if (i == len)
+ return (NULL);
+
+ if ((line = malloc(i + 1)) == NULL) {
+ fprintf(stderr, "%s: out of memory\n", __func__);
+ evbuffer_drain(buffer, i);
+ return (NULL);
+ }
+
+ memcpy(line, data, i);
+ line[i] = '\0';
+
+ /*
+ * Some protocols terminate a line with '\r\n', so check for
+ * that, too.
+ */
+ if ( i < len - 1 ) {
+ char fch = data[i], sch = data[i+1];
+
+ /* Drain one more character if needed */
+ if ( (sch == '\r' || sch == '\n') && sch != fch )
+ i += 1;
+ }
+
+ evbuffer_drain(buffer, i + 1);
+
+ return (line);
+}
+
/* Adds data to an event buffer */
-static void
+static inline void
evbuffer_align(struct evbuffer *buf)
{
memmove(buf->orig_buffer, buf->buffer, buf->off);
@@ -278,16 +327,11 @@
u_char *p;
size_t oldoff = buf->off;
int n = EVBUFFER_MAX_READ;
-#ifdef WIN32
- /*DWORD dwBytesRead;*/
-#endif
#ifndef WIN32
-#ifdef FIONREAD
- if (ioctl(fd, FIONREAD, &n) == -1)
+ if (ioctl(fd, FIONREAD, &n) == -1 || n == 0)
n = EVBUFFER_MAX_READ;
#endif
-#endif
if (howmuch < 0 || howmuch > n)
howmuch = n;
@@ -305,13 +349,12 @@
if (n == 0)
return (0);
#else
- n = recv( fd, p, howmuch, 0 ); /*ReadFile((HANDLE)fd, p, howmuch, &dwBytesRead, NULL);*/
+ n = recv( fd, p, howmuch, 0 );
errno = GetLastError();
- if (n == 0)
+ if (n == -1)
return (-1);
if (n == 0)
return (0);
- /*n = dwBytesRead;*/
#endif
buf->off += n;
@@ -327,10 +370,7 @@
evbuffer_write(struct evbuffer *buffer, int fd)
{
int n;
-#ifdef WIN32
- /*DWORD dwBytesWritten;*/
-#endif
-
+
#ifndef WIN32
n = write(fd, buffer->buffer, buffer->off);
if (n == -1)
@@ -339,13 +379,12 @@
return (0);
#else
n = send( fd, buffer->buffer, buffer->off, 0 );
- /*WriteFile((HANDLE)fd, buffer->buffer, buffer->off, &dwBytesWritten, NULL);*/
- if (n == 0)
+ if (n == -1)
return (-1);
if (n == 0)
return (0);
- /*n = dwBytesWritten;*/
#endif
+
evbuffer_drain(buffer, n);
return (n);
Modified: trunk/lib/event/devpoll.c
==============================================================================
--- trunk/lib/event/devpoll.c (original)
+++ trunk/lib/event/devpoll.c Sat Aug 13 15:05:58 2005
@@ -24,13 +24,11 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_DEVPOLL
-
#include <sys/types.h>
#include <sys/resource.h>
#ifdef HAVE_SYS_TIME_H
@@ -53,9 +51,6 @@
#include "evsignal.h"
#include "log.h"
-
-
-
extern volatile sig_atomic_t evsignal_caught;
/* due to limitations in the devpoll interface, we need to keep track of
@@ -150,7 +145,7 @@
/* Initialize the kernel queue */
if ((dpfd = open("/dev/poll", O_RDWR)) == -1) {
- event_warn("%s: open: /dev/poll", __func__);
+ event_warn("open: /dev/poll");
free(devpollop);
return (NULL);
}
@@ -204,7 +199,7 @@
fds = realloc(devpollop->fds, nfds * sizeof(struct evdevpoll));
if (fds == NULL) {
- event_warn("%s: realloc", __func__);
+ event_warn("realloc");
return (-1);
}
devpollop->fds = fds;
@@ -244,7 +239,7 @@
if (res == -1) {
if (errno != EINTR) {
- event_warn("%s: ioctl: DP_POLL", __func__);
+ event_warn("ioctl: DP_POLL");
return (-1);
}
@@ -407,4 +402,4 @@
return (0);
}
-#endif
+#endif
Modified: trunk/lib/event/epoll.c
==============================================================================
--- trunk/lib/event/epoll.c (original)
+++ trunk/lib/event/epoll.c Sat Aug 13 15:05:58 2005
@@ -29,8 +29,6 @@
#endif
#ifdef HAVE_EPOLL
-
-
#include <stdint.h>
#include <sys/types.h>
#include <sys/resource.h>
@@ -55,7 +53,6 @@
#include "evsignal.h"
#include "log.h"
-
extern volatile sig_atomic_t evsignal_caught;
/* due to limitations in the epoll interface, we need to keep track of
@@ -119,7 +116,7 @@
/* Initalize the kernel queue */
if ((epfd = epoll_create(nfiles)) == -1) {
- event_warn("%s: epoll_create", __func__);
+ event_warn("epoll_create");
return (NULL);
}
@@ -166,7 +163,7 @@
fds = realloc(epollop->fds, nfds * sizeof(struct evepoll));
if (fds == NULL) {
- event_warn("%s: realloc", __func__);
+ event_warn("realloc");
return (-1);
}
epollop->fds = fds;
@@ -197,7 +194,7 @@
if (res == -1) {
if (errno != EINTR) {
- event_warn("%s: epoll_wait", __func__);
+ event_warn("epoll_wait");
return (-1);
}
@@ -253,7 +250,7 @@
epoll_add(void *arg, struct event *ev)
{
struct epollop *epollop = arg;
- struct epoll_event epev;
+ struct epoll_event epev = {0, {0}};
struct evepoll *evep;
int fd, op, events;
@@ -301,7 +298,7 @@
epoll_del(void *arg, struct event *ev)
{
struct epollop *epollop = arg;
- struct epoll_event epev;
+ struct epoll_event epev = {0, {0}};
struct evepoll *evep;
int fd, events, op;
int needwritedelete = 1, needreaddelete = 1;
@@ -337,14 +334,14 @@
epev.events = events;
epev.data.ptr = evep;
- if (epoll_ctl(epollop->epfd, op, fd, &epev) == -1)
- return (-1);
-
if (needreaddelete)
evep->evread = NULL;
if (needwritedelete)
evep->evwrite = NULL;
+ if (epoll_ctl(epollop->epfd, op, fd, &epev) == -1)
+ return (-1);
+
return (0);
}
#endif
Modified: trunk/lib/event/epoll_sub.c
==============================================================================
--- trunk/lib/event/epoll_sub.c (original)
+++ trunk/lib/event/epoll_sub.c Sat Aug 13 15:05:58 2005
@@ -27,18 +27,15 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
+
#ifdef HAVE_EPOLL
+#include <stdint.h>
+
#include <sys/param.h>
#include <sys/types.h>
#include <sys/syscall.h>
-#ifdef HAVE_SYS_EPOLL_H
#include <sys/epoll.h>
-#endif
#include <unistd.h>
int
Modified: trunk/lib/event/evbuffer.c
==============================================================================
--- trunk/lib/event/evbuffer.c (original)
+++ trunk/lib/event/evbuffer.c Sat Aug 13 15:05:58 2005
@@ -45,6 +45,11 @@
#include "event.h"
+/* prototypes */
+
+void bufferevent_setwatermark(struct bufferevent *, short, size_t, size_t);
+void bufferevent_read_pressure_cb(struct evbuffer *, size_t, size_t, void *);
+
static int
bufferevent_add(struct event *ev, int timeout)
{
@@ -96,7 +101,7 @@
res = evbuffer_read(bufev->input, fd, -1);
if (res == -1) {
#ifdef WIN32
- errno = WSAGetLastError();
+ errno = WSAGetLastError();
#endif
if (errno == EAGAIN || errno == EINTR)
goto reschedule;
@@ -139,12 +144,10 @@
#ifdef WIN32
#ifndef EINPROGRESS
-//#define EINPROGRESS WSAEWOULDBLOCK
#define EINPROGRESS WSAEINPROGRESS
#endif
#endif
-
static void
bufferevent_writecb(int fd, short event, void *arg)
{
@@ -161,7 +164,7 @@
res = evbuffer_write(bufev->output, fd);
if (res == -1) {
#ifdef WIN32
- errno = WSAGetLastError();
+ errno = WSAGetLastError();
#endif
if (errno == EAGAIN ||
errno == EINTR ||
@@ -251,6 +254,8 @@
return (0);
}
+/* Closing the file descriptor is the responsibility of the caller */
+
void
bufferevent_free(struct bufferevent *bufev)
{
Modified: trunk/lib/event/event.c
==============================================================================
--- trunk/lib/event/event.c (original)
+++ trunk/lib/event/event.c Sat Aug 13 15:05:58 2005
@@ -49,7 +49,6 @@
#endif
#include <errno.h>
#include <string.h>
-#include <err.h>
#include <assert.h>
#include "event.h"
@@ -111,7 +110,7 @@
/* Handle signals - This is a deprecated interface */
int (*event_sigcb)(void); /* Signal callback when gotsig is set */
-int event_gotsig; /* Set in signal handler */
+volatile int event_gotsig; /* Set in signal handler */
/* Prototypes */
static void event_queue_insert(struct event_base *, struct event *, int);
@@ -179,10 +178,6 @@
return (current_base);
}
-char *event_show_method() {
- return current_base->evsel->name;
-}
-
int
event_priority_init(int npriorities)
{
@@ -297,6 +292,13 @@
current_base, tv));
}
+int
+event_base_loopexit(struct event_base *event_base, struct timeval *tv)
+{
+ return (event_once(-1, EV_TIMEOUT, event_loopexit_cb,
+ event_base, tv));
+}
+
/* not thread safe */
int
@@ -354,8 +356,10 @@
timerclear(&tv);
/* If we have no events, we just exit */
- if (!event_haveevents(base))
+ if (!event_haveevents(base)) {
+ event_debug(("%s: no events registered.", __func__));
return (1);
+ }
res = evsel->dispatch(base, evbase, &tv);
@@ -375,6 +379,7 @@
return (-1);
}
+ event_debug(("%s: asked to terminate loop.", __func__));
return (0);
}
@@ -430,6 +435,7 @@
event_set(&eonce->ev, fd, events, event_once_cb, eonce);
} else {
/* Bad event combination */
+ free(eonce);
return (-1);
}
@@ -470,7 +476,7 @@
return (-1);
ev->ev_base = base;
- ev->ev_pri = current_base->nactivequeues/2;
+ ev->ev_pri = base->nactivequeues/2;
return (0);
}
@@ -789,3 +795,22 @@
event_errx(1, "%s: unknown queue %x", __func__, queue);
}
}
+
+/* Functions for debugging */
+
+const char *
+event_get_version(void)
+{
+ return (VERSION);
+}
+
+/*
+ * No thread-safe interface needed - the information should be the same
+ * for all threads.
+ */
+
+const char *
+event_get_method(void)
+{
+ return (current_base->evsel->name);
+}
Modified: trunk/lib/event/event.h
==============================================================================
--- trunk/lib/event/event.h (original)
+++ trunk/lib/event/event.h Sat Aug 13 15:05:58 2005
@@ -32,7 +32,10 @@
#endif
#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+typedef unsigned char u_char;
#endif
#define EVLIST_TIMEOUT 0x01
@@ -80,8 +83,8 @@
struct event_base *ev_base;
#ifdef WIN32
- HANDLE ev_fd;
- OVERLAPPED overlap;
+ HANDLE ev_fd;
+ OVERLAPPED overlap;
#else
int ev_fd;
#endif
@@ -142,9 +145,9 @@
#define EVLOOP_ONCE 0x01
#define EVLOOP_NONBLOCK 0x02
int event_loop(int);
-char *event_show_method();
int event_base_loop(struct event_base *, int);
int event_loopexit(struct timeval *); /* Causes the loop to exit */
+int event_base_loopexit(struct event_base *, struct timeval *);
#define evtimer_add(ev, tv) event_add(ev, tv)
#define evtimer_set(ev, cb, arg) event_set(ev, -1, 0, cb, arg)
@@ -180,6 +183,10 @@
#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT)
#endif
+/* Some simple debugging functions */
+const char *event_get_version(void);
+const char *event_get_method(void);
+
/* These functions deal with event priorities */
int event_priority_init(int);
@@ -248,7 +255,8 @@
int bufferevent_disable(struct bufferevent *bufev, short event);
void bufferevent_settimeout(struct bufferevent *bufev,
int timeout_read, int timeout_write);
-void bufferevent_setwatermark(struct bufferevent *bufev, short events, size_t lowmark, size_t highmark);
+void bufferevent_setwatermark(struct bufferevent *bufev,
+ short events, size_t lowmark, size_t highmark);
#define EVBUFFER_LENGTH(x) (x)->off
#define EVBUFFER_DATA(x) (x)->buffer
@@ -260,6 +268,7 @@
int evbuffer_expand(struct evbuffer *, size_t);
int evbuffer_add(struct evbuffer *, void *, size_t);
int evbuffer_remove(struct evbuffer *, void *, size_t);
+char *evbuffer_readline(struct evbuffer *);
int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *);
int evbuffer_add_printf(struct evbuffer *, char *fmt, ...);
void evbuffer_drain(struct evbuffer *, size_t);
@@ -267,6 +276,7 @@
int evbuffer_read(struct evbuffer *, int, int);
u_char *evbuffer_find(struct evbuffer *, u_char *, size_t);
void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_t, void *), void *);
+
#ifdef __cplusplus
}
#endif
Modified: trunk/lib/event/kqueue.c
==============================================================================
--- trunk/lib/event/kqueue.c (original)
+++ trunk/lib/event/kqueue.c Sat Aug 13 15:05:58 2005
@@ -29,6 +29,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#ifdef HAVE_WORKING_KQUEUE
#include <sys/types.h>
@@ -58,7 +59,6 @@
#include "event.h"
#include "log.h"
-
#define EVLIST_X_KQINKERNEL 0x1000
#define NEVENT 64
@@ -118,12 +118,33 @@
}
kqueueop->events = malloc(NEVENT * sizeof(struct kevent));
if (kqueueop->events == NULL) {
- free (kqueueop);
free (kqueueop->changes);
+ free (kqueueop);
return (NULL);
}
kqueueop->nevents = NEVENT;
+ /* Check for Mac OS X kqueue bug. */
+ kqueueop->changes[0].ident = -1;
+ kqueueop->changes[0].filter = EVFILT_READ;
+ kqueueop->changes[0].flags = EV_ADD;
+ /*
+ * If kqueue works, then kevent will succeed, and it will
+ * stick an error in events[0]. If kqueue is broken, then
+ * kevent will fail.
+ */
+ if (kevent(kq,
+ kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
+ kqueueop->events[0].ident != -1 ||
+ kqueueop->events[0].flags != EV_ERROR) {
+ event_warn("%s: detected broken kqueue; not using.", __func__);
+ free(kqueueop->changes);
+ free(kqueueop->events);
+ free(kqueueop);
+ close(kq);
+ return (NULL);
+ }
+
return (kqueueop);
}
@@ -220,13 +241,17 @@
* closed,
* ENOENT when the file discriptor was closed and
* then reopened.
+ * EINVAL for some reasons not understood; EINVAL
+ * should not be returned ever; but FreeBSD does :-\
* An error is also indicated when a callback deletes
* an event we are still processing. In that case
* the data field is set to ENOENT.
*/
if (events[i].data == EBADF ||
+ events[i].data == EINVAL ||
events[i].data == ENOENT)
continue;
+ errno = events[i].data;
return (-1);
}
Modified: trunk/lib/event/log.c
==============================================================================
--- trunk/lib/event/log.c (original)
+++ trunk/lib/event/log.c Sat Aug 13 15:05:58 2005
@@ -37,21 +37,32 @@
* SUCH DAMAGE.
*/
+#ifdef HAVE_CONFIG_H
#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#ifndef WIN32
+#endif
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include "misc.h"
+#endif
+#include <sys/types.h>
+#include <sys/tree.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <sys/_time.h>
#endif
-#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
#include "event.h"
+#include "log.h"
+
static void _warn_helper(int severity, int log_errno, const char *fmt,
va_list ap);
static void event_log(int severity, const char *msg);
@@ -76,6 +87,17 @@
return r;
}
+static int
+event_snprintf(char *str, size_t size, const char *format, ...)
+{
+ va_list ap;
+ int r;
+ va_start(ap, format);
+ r = event_vsnprintf(str, size, format, ap);
+ va_end(ap);
+ return r;
+}
+
void
event_err(int eval, const char *fmt, ...)
{
@@ -142,15 +164,21 @@
_warn_helper(int severity, int log_errno, const char *fmt, va_list ap)
{
char buf[1024];
+ size_t len;
if (fmt != NULL)
event_vsnprintf(buf, sizeof(buf), fmt, ap);
else
buf[0] = '\0';
+
if (log_errno >= 0) {
- strncat(buf, ": ", 1024);
- strncat(buf, strerror(log_errno), 1024);
- }
+ len = strlen(buf);
+ if (len < sizeof(buf) - 3) {
+ event_snprintf(buf + len, sizeof(buf) - len, ": %s",
+ strerror(log_errno));
+ }
+ }
+
event_log(severity, buf);
}
Modified: trunk/lib/event/log.h
==============================================================================
--- trunk/lib/event/log.h (original)
+++ trunk/lib/event/log.h Sat Aug 13 15:05:58 2005
@@ -27,15 +27,14 @@
#ifndef _LOG_H_
#define _LOG_H_
-#undef EVENT_DEBUG
-
void event_err(int eval, const char *fmt, ...);
void event_warn(const char *fmt, ...);
void event_errx(int eval, const char *fmt, ...);
void event_warnx(const char *fmt, ...);
void event_msgx(const char *fmt, ...);
void _event_debugx(const char *fmt, ...);
-#ifdef EVENT_DEBUG
+#undef USE_DEBUG
+#ifdef USE_DEBUG
#define event_debug(x) _event_debugx x
#else
#define event_debug(x)
Modified: trunk/lib/event/poll.c
==============================================================================
--- trunk/lib/event/poll.c (original)
+++ trunk/lib/event/poll.c Sat Aug 13 15:05:58 2005
@@ -31,8 +31,6 @@
#endif
#ifdef HAVE_POLL
-
-
#include <sys/types.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
@@ -48,19 +46,27 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+#ifdef CHECK_INVARIANTS
+#include <assert.h>
+#endif
#include "event.h"
#include "event-internal.h"
#include "evsignal.h"
#include "log.h"
-
extern volatile sig_atomic_t evsignal_caught;
struct pollop {
int event_count; /* Highest number alloc */
+ int nfds; /* Size of event_* */
+ int fd_count; /* Size of idxplus1_by_fd */
struct pollfd *event_set;
- struct event **event_back;
+ struct event **event_r_back;
+ struct event **event_w_back;
+ int *idxplus1_by_fd; /* Index into event_set by fd; we add 1 so
+ * that 0 (which is easy to memset) can mean
+ * "no entry." */
sigset_t evsigmask;
};
@@ -109,64 +115,52 @@
return (evsignal_recalc(&pop->evsigmask));
}
-int
-poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
+#ifdef CHECK_INVARIANTS
+static void
+poll_check_ok(struct pollop *pop)
{
- int res, i, count, sec, nfds;
+ int i, idx;
struct event *ev;
- struct pollop *pop = arg;
- count = pop->event_count;
- nfds = 0;
- TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
- if (nfds + 1 >= count) {
- if (count < 32)
- count = 32;
- else
- count *= 2;
-
- /* We need more file descriptors */
- pop->event_set = realloc(pop->event_set,
- count * sizeof(struct pollfd));
- if (pop->event_set == NULL) {
- event_warn("realloc");
- return (-1);
- }
- pop->event_back = realloc(pop->event_back,
- count * sizeof(struct event *));
- if (pop->event_back == NULL) {
- event_warn("realloc");
- return (-1);
- }
- pop->event_count = count;
- }
- if (ev->ev_events & EV_WRITE) {
- struct pollfd *pfd = &pop->event_set[nfds];
- pfd->fd = ev->ev_fd;
- pfd->events = POLLOUT;
- pfd->revents = 0;
-
- pop->event_back[nfds] = ev;
-
- nfds++;
- }
- if (ev->ev_events & EV_READ) {
- struct pollfd *pfd = &pop->event_set[nfds];
-
- pfd->fd = ev->ev_fd;
- pfd->events = POLLIN;
- pfd->revents = 0;
-
- pop->event_back[nfds] = ev;
-
- nfds++;
+ for (i = 0; i < pop->fd_count; ++i) {
+ idx = pop->idxplus1_by_fd[i]-1;
+ if (idx < 0)
+ continue;
+ assert(pop->event_set[idx].fd == i);
+ if (pop->event_set[idx].events & POLLIN) {
+ ev = pop->event_r_back[idx];
+ assert(ev);
+ assert(ev->ev_events & EV_READ);
+ assert(ev->ev_fd == i);
+ }
+ if (pop->event_set[idx].events & POLLOUT) {
+ ev = pop->event_w_back[idx];
+ assert(ev);
+ assert(ev->ev_events & EV_WRITE);
+ assert(ev->ev_fd == i);
}
}
+ for (i = 0; i < pop->nfds; ++i) {
+ struct pollfd *pfd = &pop->event_set[i];
+ assert(pop->idxplus1_by_fd[pfd->fd] == i+1);
+ }
+}
+#else
+#define poll_check_ok(pop)
+#endif
+
+int
+poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
+{
+ int res, i, sec, nfds;
+ struct pollop *pop = arg;
if (evsignal_deliver(&pop->evsigmask) == -1)
return (-1);
+ poll_check_ok(pop);
sec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
+ nfds = pop->nfds;
res = poll(pop->event_set, nfds, sec);
if (evsignal_recalc(&pop->evsigmask) == -1)
@@ -190,29 +184,36 @@
for (i = 0; i < nfds; i++) {
int what = pop->event_set[i].revents;
-
+ struct event *r_ev = NULL, *w_ev = NULL;
+ if (!what)
+ continue;
+
res = 0;
/* If the file gets closed notify */
- if (what & POLLHUP)
+ if (what & (POLLHUP|POLLERR))
what |= POLLIN|POLLOUT;
- if (what & POLLERR)
- what |= POLLIN|POLLOUT;
- if (what & POLLIN)
+ if (what & POLLIN) {
res |= EV_READ;
- if (what & POLLOUT)
+ r_ev = pop->event_r_back[i];
+ }
+ if (what & POLLOUT) {
res |= EV_WRITE;
+ w_ev = pop->event_w_back[i];
+ }
if (res == 0)
continue;
- ev = pop->event_back[i];
- res &= ev->ev_events;
-
- if (res) {
- if (!(ev->ev_events & EV_PERSIST))
- event_del(ev);
- event_active(ev, res, 1);
- }
+ if (r_ev && (res & r_ev->ev_events)) {
+ if (!(r_ev->ev_events & EV_PERSIST))
+ event_del(r_ev);
+ event_active(r_ev, res & r_ev->ev_events, 1);
+ }
+ if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) {
+ if (!(w_ev->ev_events & EV_PERSIST))
+ event_del(w_ev);
+ event_active(w_ev, res & w_ev->ev_events, 1);
+ }
}
return (0);
@@ -222,9 +223,79 @@
poll_add(void *arg, struct event *ev)
{
struct pollop *pop = arg;
+ struct pollfd *pfd = NULL;
+ int i;
if (ev->ev_events & EV_SIGNAL)
return (evsignal_add(&pop->evsigmask, ev));
+ if (!(ev->ev_events & (EV_READ|EV_WRITE)))
+ return (0);
+
+ poll_check_ok(pop);
+ if (pop->nfds + 1 >= pop->event_count) {
+ if (pop->event_count < 32)
+ pop->event_count = 32;
+ else
+ pop->event_count *= 2;
+
+ /* We need more file descriptors */
+ pop->event_set = realloc(pop->event_set,
+ pop->event_count * sizeof(struct pollfd));
+ if (pop->event_set == NULL) {
+ event_warn("realloc");
+ return (-1);
+ }
+ pop->event_r_back = realloc(pop->event_r_back,
+ pop->event_count * sizeof(struct event *));
+ pop->event_w_back = realloc(pop->event_w_back,
+ pop->event_count * sizeof(struct event *));
+ if (pop->event_r_back == NULL ||
+ pop->event_w_back == NULL) {
+ event_warn("realloc");
+ return (-1);
+ }
+ }
+ if (ev->ev_fd >= pop->fd_count) {
+ int new_count;
+ if (pop->fd_count < 32)
+ new_count = 32;
+ else
+ new_count = pop->fd_count * 2;
+ while (new_count <= ev->ev_fd)
+ new_count *= 2;
+ pop->idxplus1_by_fd =
+ realloc(pop->idxplus1_by_fd, new_count*sizeof(int));
+ if (pop->idxplus1_by_fd == NULL) {
+ event_warn("realloc");
+ return (-1);
+ }
+ memset(pop->idxplus1_by_fd + pop->fd_count,
+ 0, sizeof(int)*(new_count - pop->fd_count));
+ pop->fd_count = new_count;
+ }
+
+ i = pop->idxplus1_by_fd[ev->ev_fd] - 1;
+ if (i >= 0) {
+ pfd = &pop->event_set[i];
+ } else {
+ i = pop->nfds++;
+ pfd = &pop->event_set[i];
+ pfd->events = 0;
+ pfd->fd = ev->ev_fd;
+ pop->event_w_back[i] = pop->event_r_back[i] = NULL;
+ pop->idxplus1_by_fd[ev->ev_fd] = i + 1;
+ }
+
+ pfd->revents = 0;
+ if (ev->ev_events & EV_WRITE) {
+ pfd->events |= POLLOUT;
+ pop->event_w_back[i] = ev;
+ }
+ if (ev->ev_events & EV_READ) {
+ pfd->events |= POLLIN;
+ pop->event_r_back[i] = ev;
+ }
+ poll_check_ok(pop);
return (0);
}
@@ -237,10 +308,52 @@
poll_del(void *arg, struct event *ev)
{
struct pollop *pop = arg;
+ struct pollfd *pfd = NULL;
+ int i;
+
+ if (ev->ev_events & EV_SIGNAL)
+ return (evsignal_del(&pop->evsigmask, ev));
- if (!(ev->ev_events & EV_SIGNAL))
+ if (!(ev->ev_events & (EV_READ|EV_WRITE)))
return (0);
- return (evsignal_del(&pop->evsigmask, ev));
+ poll_check_ok(pop);
+ i = pop->idxplus1_by_fd[ev->ev_fd] - 1;
+ if (i < 0)
+ return (-1);
+
+ /* Do we still want to read or write? */
+ pfd = &pop->event_set[i];
+ if (ev->ev_events & EV_READ) {
+ pfd->events &= ~POLLIN;
+ pop->event_r_back[i] = NULL;
+ }
+ if (ev->ev_events & EV_WRITE) {
+ pfd->events &= ~POLLOUT;
+ pop->event_w_back[i] = NULL;
+ }
+ poll_check_ok(pop);
+ if (pfd->events)
+ /* Another event cares about that fd. */
+ return (0);
+
+ /* Okay, so we aren't interested in that fd anymore. */
+ pop->idxplus1_by_fd[ev->ev_fd] = 0;
+
+ --pop->nfds;
+ if (i != pop->nfds) {
+ /*
+ * Shift the last pollfd down into the now-unoccupied
+ * position.
+ */
+ memcpy(&pop->event_set[i], &pop->event_set[pop->nfds],
+ sizeof(struct pollfd));
+ pop->event_r_back[i] = pop->event_r_back[pop->nfds];
+ pop->event_w_back[i] = pop->event_w_back[pop->nfds];
+ pop->idxplus1_by_fd[pop->event_set[i].fd] = i + 1;
+ }
+
+ poll_check_ok(pop);
+ return (0);
}
#endif
Modified: trunk/lib/event/rtsig.c
==============================================================================
--- trunk/lib/event/rtsig.c (original)
+++ trunk/lib/event/rtsig.c Sat Aug 13 15:05:58 2005
@@ -4,7 +4,6 @@
#ifdef HAVE_RTSIG
-
/* Enable F_SETSIG and F_SETOWN */
#define _GNU_SOURCE
@@ -32,7 +31,6 @@
#include "event.h"
#include "log.h"
-
extern struct event_list signalqueue;
struct rtsigop {
@@ -437,4 +435,5 @@
return (0);
}
+
#endif
Modified: trunk/lib/event/select.c
==============================================================================
--- trunk/lib/event/select.c (original)
+++ trunk/lib/event/select.c Sat Aug 13 15:05:58 2005
@@ -32,7 +32,6 @@
#ifdef HAVE_SELECT
-
#include <sys/types.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
@@ -47,14 +46,15 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
-#include <err.h>
+#ifdef CHECK_INVARIANTS
+#include <assert.h>
+#endif
#include "event.h"
#include "event-internal.h"
#include "evsignal.h"
#include "log.h"
-
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
@@ -64,8 +64,12 @@
struct selectop {
int event_fds; /* Highest fd in fd set */
int event_fdsz;
- fd_set *event_readset;
- fd_set *event_writeset;
+ fd_set *event_readset_in;
+ fd_set *event_writeset_in;
+ fd_set *event_readset_out;
+ fd_set *event_writeset_out;
+ struct event **event_r_by_fd;
+ struct event **event_w_by_fd;
sigset_t evsigmask;
};
@@ -84,6 +88,8 @@
select_dispatch
};
+static int select_resize(struct selectop *sop, int fdsz);
+
void *
select_init(void)
{
@@ -96,11 +102,40 @@
if (!(sop = calloc(1, sizeof(struct selectop))))
return (NULL);
+ select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
+
evsignal_init(&sop->evsigmask);
return (sop);
}
+#ifdef CHECK_INVARIANTS
+static void
+check_selectop(struct selectop *sop)
+{
+ int i;
+ for (i=0;i<=sop->event_fds;++i) {
+ if (FD_ISSET(i, sop->event_readset_in)) {
+ assert(sop->event_r_by_fd[i]);
+ assert(sop->event_r_by_fd[i]->ev_events & EV_READ);
+ assert(sop->event_r_by_fd[i]->ev_fd == i);
+ } else {
+ assert(! sop->event_r_by_fd[i]);
+ }
+ if (FD_ISSET(i, sop->event_writeset_in)) {
+ assert(sop->event_w_by_fd[i]);
+ assert(sop->event_w_by_fd[i]->ev_events & EV_WRITE);
+ assert(sop->event_w_by_fd[i]->ev_fd == i);
+ } else {
+ assert(! sop->event_w_by_fd[i]);
+ }
+ }
+
+}
+#else
+#define check_selectop(sop)
+#endif
+
/*
* Called with the highest fd that we know about. If it is 0, completely
* recalculate everything.
@@ -110,41 +145,8 @@
select_recalc(struct event_base *base, void *arg, int max)
{
struct selectop *sop = arg;
- fd_set *readset, *writeset;
- struct event *ev;
- int fdsz;
-
- if (sop->event_fds < max)
- sop->event_fds = max;
-
- if (!sop->event_fds) {
- TAILQ_FOREACH(ev, &base->eventqueue, ev_next)
- if (ev->ev_fd > sop->event_fds)
- sop->event_fds = ev->ev_fd;
- }
-
- fdsz = howmany(sop->event_fds + 1, NFDBITS) * sizeof(fd_mask);
- if (fdsz > sop->event_fdsz) {
- if ((readset = realloc(sop->event_readset, fdsz)) == NULL) {
- event_warn("malloc");
- return (-1);
- }
- if ((writeset = realloc(sop->event_writeset, fdsz)) == NULL) {
- event_warn("malloc");
- free(readset);
- return (-1);
- }
-
- memset((char *)readset + sop->event_fdsz, 0,
- fdsz - sop->event_fdsz);
- memset((char *)writeset + sop->event_fdsz, 0,
- fdsz - sop->event_fdsz);
-
- sop->event_readset = readset;
- sop->event_writeset = writeset;
- sop->event_fdsz = fdsz;
- }
+ check_selectop(sop);
return (evsignal_recalc(&sop->evsigmask));
}
@@ -152,26 +154,23 @@
int
select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
{
- int maxfd, res;
- struct event *ev, *next;
+ int res, i;
struct selectop *sop = arg;
- memset(sop->event_readset, 0, sop->event_fdsz);
- memset(sop->event_writeset, 0, sop->event_fdsz);
+ check_selectop(sop);
- TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
- if (ev->ev_events & EV_WRITE)
- FD_SET(ev->ev_fd, sop->event_writeset);
- if (ev->ev_events & EV_READ)
- FD_SET(ev->ev_fd, sop->event_readset);
- }
+ memcpy(sop->event_readset_out, sop->event_readset_in,
+ sop->event_fdsz);
+ memcpy(sop->event_writeset_out, sop->event_writeset_in,
+ sop->event_fdsz);
if (evsignal_deliver(&sop->evsigmask) == -1)
return (-1);
- res = select(sop->event_fds + 1, sop->event_readset,
- sop->event_writeset, NULL, tv);
+ res = select(sop->event_fds + 1, sop->event_readset_out,
+ sop->event_writeset_out, NULL, tv);
+ check_selectop(sop);
if (evsignal_recalc(&sop->evsigmask) == -1)
return (-1);
@@ -188,32 +187,94 @@
event_debug(("%s: select reports %d", __func__, res));
- maxfd = 0;
- for (ev = TAILQ_FIRST(&base->eventqueue); ev != NULL; ev = next) {
- next = TAILQ_NEXT(ev, ev_next);
-
+ check_selectop(sop);
+ for (i = 0; i <= sop->event_fds; ++i) {
+ struct event *r_ev = NULL, *w_ev = NULL;
res = 0;
- if (FD_ISSET(ev->ev_fd, sop->event_readset))
+ if (FD_ISSET(i, sop->event_readset_out)) {
+ r_ev = sop->event_r_by_fd[i];
res |= EV_READ;
- if (FD_ISSET(ev->ev_fd, sop->event_writeset))
+ }
+ if (FD_ISSET(i, sop->event_writeset_out)) {
+ w_ev = sop->event_w_by_fd[i];
res |= EV_WRITE;
- res &= ev->ev_events;
-
- if (res) {
- if (!(ev->ev_events & EV_PERSIST))
- event_del(ev);
- else if (ev->ev_fd > maxfd)
- maxfd = ev->ev_fd;
- event_active(ev, res, 1);
- } else if (ev->ev_fd > maxfd)
- maxfd = ev->ev_fd;
+ }
+ if (r_ev && (res & r_ev->ev_events)) {
+ if (!(r_ev->ev_events & EV_PERSIST))
+ event_del(r_ev);
+ event_active(r_ev, res & r_ev->ev_events, 1);
+ }
+ if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) {
+ if (!(w_ev->ev_events & EV_PERSIST))
+ event_del(w_ev);
+ event_active(w_ev, res & w_ev->ev_events, 1);
+ }
}
+ check_selectop(sop);
- sop->event_fds = maxfd;
+ return (0);
+}
+
+
+static int
+select_resize(struct selectop *sop, int fdsz)
+{
+ int n_events, n_events_old;
+
+ fd_set *readset_in = NULL;
+ fd_set *writeset_in = NULL;
+ fd_set *readset_out = NULL;
+ fd_set *writeset_out = NULL;
+ struct event **r_by_fd = NULL;
+ struct event **w_by_fd = NULL;
+
+ n_events = (fdsz/sizeof(fd_mask)) * NFDBITS;
+ n_events_old = (sop->event_fdsz/sizeof(fd_mask)) * NFDBITS;
+
+ if (sop->event_readset_in)
+ check_selectop(sop);
+
+ if ((readset_in = realloc(sop->event_readset_in, fdsz)) == NULL)
+ goto error;
+ sop->event_readset_in = readset_in;
+ if ((readset_out = realloc(sop->event_readset_out, fdsz)) == NULL)
+ goto error;
+ sop->event_readset_out = readset_out;
+ if ((writeset_in = realloc(sop->event_writeset_in, fdsz)) == NULL)
+ goto error;
+ sop->event_writeset_in = writeset_in;
+ if ((writeset_out = realloc(sop->event_writeset_out, fdsz)) == NULL)
+ goto error;
+ sop->event_writeset_out = writeset_out;
+ if ((r_by_fd = realloc(sop->event_r_by_fd,
+ n_events*sizeof(struct event*))) == NULL)
+ goto error;
+ sop->event_r_by_fd = r_by_fd;
+ if ((w_by_fd = realloc(sop->event_w_by_fd,
+ n_events * sizeof(struct event*))) == NULL)
+ goto error;
+ sop->event_w_by_fd = w_by_fd;
+
+ memset((char *)sop->event_readset_in + sop->event_fdsz, 0,
+ fdsz - sop->event_fdsz);
+ memset((char *)sop->event_writeset_in + sop->event_fdsz, 0,
+ fdsz - sop->event_fdsz);
+ memset(sop->event_r_by_fd + n_events_old, 0,
+ (n_events-n_events_old) * sizeof(struct event*));
+ memset(sop->event_w_by_fd + n_events_old, 0,
+ (n_events-n_events_old) * sizeof(struct event*));
+
+ sop->event_fdsz = fdsz;
+ check_selectop(sop);
return (0);
+
+ error:
+ event_warn("malloc");
+ return (-1);
}
+
int
select_add(void *arg, struct event *ev)
{
@@ -222,12 +283,40 @@
if (ev->ev_events & EV_SIGNAL)
return (evsignal_add(&sop->evsigmask, ev));
- /*
+ check_selectop(sop);
+ /*
* Keep track of the highest fd, so that we can calculate the size
* of the fd_sets for select(2)
*/
- if (sop->event_fds < ev->ev_fd)
+ if (sop->event_fds < ev->ev_fd) {
+ int fdsz = sop->event_fdsz;
+
+ if (fdsz < sizeof(fd_mask))
+ fdsz = sizeof(fd_mask);
+
+ while (fdsz <
+ (howmany(ev->ev_fd + 1, NFDBITS) * sizeof(fd_mask)))
+ fdsz *= 2;
+
+ if (fdsz != sop->event_fdsz) {
+ if (select_resize(sop, fdsz)) {
+ check_selectop(sop);
+ return (-1);
+ }
+ }
+
sop->event_fds = ev->ev_fd;
+ }
+
+ if (ev->ev_events & EV_READ) {
+ FD_SET(ev->ev_fd, sop->event_readset_in);
+ sop->event_r_by_fd[ev->ev_fd] = ev;
+ }
+ if (ev->ev_events & EV_WRITE) {
+ FD_SET(ev->ev_fd, sop->event_writeset_in);
+ sop->event_w_by_fd[ev->ev_fd] = ev;
+ }
+ check_selectop(sop);
return (0);
}
@@ -241,9 +330,26 @@
{
struct selectop *sop = arg;
- if (!(ev->ev_events & EV_SIGNAL))
+ check_selectop(sop);
+ if (ev->ev_events & EV_SIGNAL)
+ return (evsignal_del(&sop->evsigmask, ev));
+
+ if (sop->event_fds < ev->ev_fd) {
+ check_selectop(sop);
return (0);
+ }
- return (evsignal_del(&sop->evsigmask, ev));
+ if (ev->ev_events & EV_READ) {
+ FD_CLR(ev->ev_fd, sop->event_readset_in);
+ sop->event_r_by_fd[ev->ev_fd] = NULL;
+ }
+
+ if (ev->ev_events & EV_WRITE) {
+ FD_CLR(ev->ev_fd, sop->event_writeset_in);
+ sop->event_w_by_fd[ev->ev_fd] = NULL;
+ }
+
+ check_selectop(sop);
+ return (0);
}
-#endif
+#endif
Modified: trunk/lib/event/signal.c
==============================================================================
--- trunk/lib/event/signal.c (original)
+++ trunk/lib/event/signal.c Sat Aug 13 15:05:58 2005
@@ -56,10 +56,6 @@
static int needrecalc;
volatile sig_atomic_t evsignal_caught = 0;
-void evsignal_process(void);
-int evsignal_recalc(sigset_t *);
-int evsignal_deliver(sigset_t *);
-
static struct event ev_signal;
static int ev_signal_pair[2];
static int ev_signal_added;
Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c (original)
+++ trunk/src/main.c Sat Aug 13 15:05:58 2005
@@ -417,7 +417,7 @@
*/
if( InitCore() != NS_SUCCESS )
return EXIT_FAILURE;
- dlog( DEBUG1, "NeoStats will use %s", event_show_method() );
+ dlog( DEBUG1, "NeoStats will use %s", event_get_method() );
nlog( LOG_NOTICE, "NeoStats \"%s\" started.", me.version );
#ifdef WIN32
/* override pcre lib malloc calls with our own version */