[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 */