Pantek Library
Hosting Provided By
CybrHost
High Speed Hosting

bk commit into 6.0 tree (dkatz:1.2647)

From: <damien(at)mysql.com>
Date: Wed Oct 31 2007 - 15:37:07 EDT


Below is the list of changes that have just been committed into a local 6.0 repository of dkatz. When dkatz does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository.
For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@1.2647, 2007-10-31 15:36:58-04:00, dkatz@damien-katzs-computer.local +42 -0   WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  config/ac-macros/libevent.m4@1.1, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +304 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  config/ac-macros/libevent.m4@1.0, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +0 -0

  configure.in@1.386, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +2 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/Makefile.am@1.47, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +2 -2     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/Makefile.am@1.1, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +20 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/Makefile.am@1.0, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +0 -0

Do you need help?X

  extra/libevent/README@1.1, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +53 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/README@1.0, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/buffer.c@1.1, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +460 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/buffer.c@1.0, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/compat/sys/_time.h@1.1, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +163 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/compat/sys/_time.h@1.0, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/compat/sys/queue.h@1.1, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +488 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/compat/sys/queue.h@1.0, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +0 -0

Do you need more help?X

  extra/libevent/compat/sys/tree.h@1.1, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +677 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/compat/sys/tree.h@1.0, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/devpoll.c@1.1, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +419 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/devpoll.c@1.0, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/epoll.c@1.1, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +366 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/epoll.c@1.0, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/epoll_sub.c@1.1, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +52 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/epoll_sub.c@1.0, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +0 -0

Can we help you?X

  extra/libevent/evbuffer.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +413 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/evbuffer.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/evdns.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +3116 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/evdns.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/evdns.h@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +367 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/evdns.h@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/event-internal.h@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +61 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/event-internal.h@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

Can't find what you're looking for?X

  extra/libevent/event.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +928 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/event.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/event.h@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +340 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/event.h@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/event_tagging.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +372 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/event_tagging.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/evhttp.h@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +221 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/evhttp.h@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

Don't know where to look next?X

  extra/libevent/evport.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +531 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/evport.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/evsignal.h@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +44 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/evsignal.h@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/http-internal.h@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +122 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/http-internal.h@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/http.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +2368 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/http.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

Confused? Frustrated?X

  extra/libevent/kqueue.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +419 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/kqueue.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/log.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +219 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/log.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/log.h@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +43 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/log.h@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/poll.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +391 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/poll.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

Call Pantek today for Open Source Technical Support at 1-877-546-8934 - 24/7/365X

  extra/libevent/select.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +373 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/select.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/signal.c@1.1, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +195 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/signal.c@1.0, 2007-10-31 15:36:51-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/strlcpy-internal.h@1.1, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +23 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/strlcpy-internal.h@1.0, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +0 -0

  extra/libevent/strlcpy.c@1.1, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +76 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  extra/libevent/strlcpy.c@1.0, 2007-10-31 15:36:52-04:00, dkatz@damien-katzs-computer.local +0 -0

Do you need help?X

  libmysqld/Makefile.am@1.118, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +5 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  mysql-test/r/crash_commit_before.result@1.3, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +1 -1     Fix a test case that fails by setting the global debug variable instead of the session debug variable.     

    "SET SESSION debug" sets a value that is actually stored in a OS thread variable, instead of the session (THD) object. The libevent work breaks this because each request is likely handled by a different OS thread.

  mysql-test/r/sp-threads.result@1.10, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +2 -2     Changed code that populates the process table to uniformally output blank status as NULL, instead of sometimes NULL/sometimes emptry string.

  mysql-test/t/crash_commit_before.test@1.7, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +1 -1     Fix a test case that fails by setting the global debug variable instead of the session debug variable.     

    "SET SESSION debug" sets a value that is actually stored in a OS thread variable, instead of the session (THD) object. The libevent work breaks this because each request is likely handled by a different OS thread.

  sql/Makefile.am@1.200, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +3 -2     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  sql/mysql_priv.h@1.530, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +1 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

Do you need more help?X

  sql/scheduler.cc@1.2, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +514 -3     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  sql/scheduler.h@1.2, 2007-10-31 15:36:49-04:00, dkatz@damien-katzs-computer.local +26 -0     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  sql/sql_connect.cc@1.15, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +1 -1     WL441: Work to integrate libevent and support the --thread_handling=pool-of-threads runtime option.

  sql/sql_show.cc@1.438, 2007-10-31 15:36:50-04:00, dkatz@damien-katzs-computer.local +2 -2     Changed code that populates the process table to uniformally output blank status as NULL, instead of sometimes NULL/sometimes emptry string.

diff -Nrup a/config/ac-macros/libevent.m4 b/config/ac-macros/libevent.m4

--- /dev/null	Wed Dec 31 16:00:00 196900

+++ b/config/ac-macros/libevent.m4 2007-10-31 15:36:52 -04:00
@@ -0,0 +1,304 @@
+dnl ---------------------------------------------------------------------------
+dnl Macro: MYSQL_USE_BUNDLED_LIBEVENT
+dnl
+dnl SYNOPSIS
+dnl MYSQL_USE_BUNDLED_LIBEVENT()
+dnl
+dnl DESCRIPTION
+dnl Add defines so libevent is built and linked with
+dnl ---------------------------------------------------------------------------
+AC_DEFUN([MYSQL_USE_BUNDLED_LIBEVENT], [
+
+ libevent_dir="libevent"
+ AC_SUBST([libevent_dir])
+
+ libevent_libs="\$(top_builddir)/extra/libevent/libevent.la"
+ libevent_includes="-I\$(top_builddir)/extra/libevent"
+ AC_SUBST(libevent_libs)
+ AC_SUBST(libevent_includes)
+
+ AC_DEFINE([HAVE_LIBEVENT], [1], [If we want to use libevent and have connection pooling])
+ AC_MSG_RESULT([using bundled libevent])
+
+ dnl Things that libevent needs
+ AC_CHECK_HEADERS(inttypes.h stdint.h poll.h signal.h sys/epoll.h sys/time.h \
+ sys/queue.h sys/event.h sys/devpoll.h netinet/in6.h)
+
+if test "x$ac_cv_header_sys_queue_h" = "xyes"; then
+ AC_MSG_CHECKING(for TAILQ_FOREACH in sys/queue.h)
+ AC_EGREP_CPP(yes,
+[
+#include <sys/queue.h>
+#ifdef TAILQ_FOREACH
+ yes
+#endif
+], [AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_TAILQFOREACH, 1,
+ [Define if TAILQ_FOREACH is defined in <sys/queue.h>])],
+ AC_MSG_RESULT(no)
+ )
+fi
+
+if test "x$ac_cv_header_sys_time_h" = "xyes"; then
+ AC_MSG_CHECKING(for timeradd in sys/time.h)
+ AC_EGREP_CPP(yes,
+[
+#include <sys/time.h>
+#ifdef timeradd
+ yes
+#endif
+], [ AC_DEFINE(HAVE_TIMERADD, 1,
+ [Define if timeradd is defined in <sys/time.h>])
+ AC_MSG_RESULT(yes)] ,AC_MSG_RESULT(no)
+)
+fi
+
+if test "x$ac_cv_header_sys_time_h" = "xyes"; then
+ AC_MSG_CHECKING(for timercmp in sys/time.h)
+ AC_EGREP_CPP(yes,
+[
+#include <sys/time.h>
+#ifdef timercmp
+ yes
+#endif
+], [ AC_DEFINE(HAVE_TIMERCMP, 1,
+ [Define if timercmp is defined in <sys/time.h>])
+ AC_MSG_RESULT(yes)] ,AC_MSG_RESULT(no)
+)
+fi
+
+if test "x$ac_cv_header_sys_time_h" = "xyes"; then
+ AC_MSG_CHECKING(for timerclear in sys/time.h)
+ AC_EGREP_CPP(yes,
+[
+#include <sys/time.h>
+#ifdef timerclear
+ yes
+#endif
+], [ AC_DEFINE(HAVE_TIMERCLEAR, 1,
+ [Define if timerclear is defined in <sys/time.h>])
+ AC_MSG_RESULT(yes)] ,AC_MSG_RESULT(no)
+)
+fi
+
+if test "x$ac_cv_header_sys_time_h" = "xyes"; then
+ AC_MSG_CHECKING(for timerisset in sys/time.h)
+ AC_EGREP_CPP(yes,
+[
+#include <sys/time.h>
+#ifdef timerisset
+ yes
+#endif
+], [ AC_DEFINE(HAVE_TIMERISSET, 1,
+ [Define if timerisset is defined in <sys/time.h>])
+ AC_MSG_RESULT(yes)] ,AC_MSG_RESULT(no)
+)
+fi
+
+dnl Checks for library functions.
+AC_CHECK_FUNCS(vasprintf strsep getaddrinfo getnameinfo inet_ntop)
+
+if test "x$ac_cv_func_clock_gettime" = "xyes"; then
+ AC_DEFINE(DNS_USE_CPU_CLOCK_FOR_ID, 1, [Define if clock_gettime is available in libc])
+else
+ AC_DEFINE(DNS_USE_GETTIMEOFDAY_FOR_ID, 1, [Define is no secure id variant is available])
+fi
+
+AC_MSG_CHECKING(for F_SETFD in fcntl.h)
+AC_EGREP_CPP(yes,
+[
+#define _GNU_SOURCE
+#include <fcntl.h>
+#ifdef F_SETFD
+yes
+#endif
+], [ AC_DEFINE(HAVE_SETFD, 1,
+ [Define if F_SETFD is defined in <fcntl.h>])
+ AC_MSG_RESULT(yes) ], AC_MSG_RESULT(no))
+
+needsignal=no
+if test "x$ac_cv_func_select" = "xyes" ; then
+ AC_LIBOBJ(select)
+ needsignal=yes
+fi
+
+if test "x$ac_cv_func_poll" = "xyes" ; then
+ AC_LIBOBJ(poll)
+ needsignal=yes
+fi
+
+haveepoll=no
+AC_CHECK_FUNCS(epoll_ctl, [haveepoll=yes], )
+if test "x$haveepoll" = "xyes" ; then
+ AC_DEFINE(HAVE_EPOLL, 1,
+ [Define if your system supports the epoll system calls])
+ AC_LIBOBJ(epoll)
+ needsignal=yes
+fi
+
+havedevpoll=no
+if test "x$ac_cv_header_sys_devpoll_h" = "xyes"; then
+ AC_DEFINE(HAVE_DEVPOLL, 1,
+ [Define if /dev/poll is available])
+ AC_LIBOBJ(devpoll)
+fi
+
+havekqueue=no
+if test "x$ac_cv_header_sys_event_h" = "xyes"; then
+ AC_CHECK_FUNCS(kqueue, [havekqueue=yes], )
+ if test "x$havekqueue" = "xyes" ; then
+ AC_MSG_CHECKING(for working kqueue)
+ AC_TRY_RUN(
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/event.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int
+main(int argc, char **argv)
+{
+ int kq;
+ int n;
+ int fd[[2]];
+ struct kevent ev;
+ struct timespec ts;
+ char buf[[8000]];
+
+ if (pipe(fd) == -1)
+ exit(1);
+ if (fcntl(fd[[1]], F_SETFL, O_NONBLOCK) == -1)
+ exit(1);
+
+ while ((n = write(fd[[1]], buf, sizeof(buf))) == sizeof(buf))
+ ;
+
+ if ((kq = kqueue()) == -1)
+ exit(1);
+
+ ev.ident = fd[[1]];
+ ev.filter = EVFILT_WRITE;
+ ev.flags = EV_ADD | EV_ENABLE;
+ n = kevent(kq, &ev, 1, NULL, 0, NULL);
+ if (n == -1)
+ exit(1);
+
+ read(fd[[0]], buf, sizeof(buf));
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ n = kevent(kq, NULL, 0, &ev, 1, &ts);
+ if (n == -1 || n == 0)
+ exit(1);
+
+ exit(0);
+}, [AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_WORKING_KQUEUE, 1,
+ [Define if kqueue works correctly with pipes])
+ AC_LIBOBJ(kqueue)], AC_MSG_RESULT(no), AC_MSG_RESULT(no))
+ fi
+fi
+
+haveepollsyscall=no
+if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then
+ if test "x$haveepoll" = "xno" ; then
+ AC_MSG_CHECKING(for epoll system call)
+ AC_TRY_RUN(
+#include <stdint.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/epoll.h>
+#include <unistd.h>
+
+int
+epoll_create(int size)
+{
+ return (syscall(__NR_epoll_create, size));
+}
+
+int
+main(int argc, char **argv)
+{
+ int epfd;
+
+ epfd = epoll_create(256);
+ exit (epfd == -1 ? 1 : 0);
+}, [AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_EPOLL, 1,
+ [Define if your system supports the epoll system calls])
+ needsignal=yes
+ AC_LIBOBJ(epoll_sub)
+ AC_LIBOBJ(epoll)], AC_MSG_RESULT(no), AC_MSG_RESULT(no))
+ fi
+fi
+
+haveeventports=no
+AC_CHECK_FUNCS(port_create, [haveeventports=yes], )
+if test "x$haveeventports" = "xyes" ; then
+ AC_DEFINE(HAVE_EVENT_PORTS, 1,
+ [Define if your system supports event ports])
+ AC_LIBOBJ(evport)
+ needsignal=yes
+fi
+if test "x$needsignal" = "xyes" ; then
+ AC_LIBOBJ(signal)
+fi
+
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_CHECK_TYPE(uint64_t, unsigned long long)
+AC_CHECK_TYPE(uint32_t, unsigned int)
+AC_CHECK_TYPE(uint16_t, unsigned short)
+AC_CHECK_TYPE(uint8_t, unsigned char)
+AC_CHECK_TYPES([struct in6_addr], , ,
+[#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif])
+
+AC_MSG_CHECKING([for socklen_t])
+AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>],
+ [socklen_t x;],
+ AC_MSG_RESULT([yes]),
+ [AC_MSG_RESULT([no])
+ AC_DEFINE(socklen_t, unsigned int,
+ [Define to unsigned int if you dont have it])]
+)
+
+])
+
+
+dnl ------------------------------------------------------------------------
+dnl Macro: MYSQL_CHECK_LIBEVENT
+dnl
+dnl SYNOPSIS
+dnl MYSQL_CHECK_LIBEVENT
+dnl
+dnl ------------------------------------------------------------------------
+AC_DEFUN([MYSQL_CHECK_LIBEVENT], [
+
+ AC_CONFIG_FILES(extra/libevent/Makefile)
+
+ AC_MSG_CHECKING(for libevent)
+ AC_ARG_WITH([libevent],
+ [ --with-libevent use libevent and have connection pooling],
+ [with_libevent=$withval],
+ [with_libevent=no]
+ )
+
+ if test "$with_libevent" != "no"
+ then
+ MYSQL_USE_BUNDLED_LIBEVENT
+ fi
+ AM_CONDITIONAL([HAVE_LIBEVENT], [ test "$with_libevent" != "no" ])
+])

diff -Nrup a/configure.in b/configure.in
--- a/configure.in	2007-10-19 16:19:57 -04:00

+++ b/configure.in 2007-10-31 15:36:49 -04:00
@@ -49,6 +49,7 @@ sinclude(config/ac-macros/large_file.m4)
 sinclude(config/ac-macros/misc.m4)
 sinclude(config/ac-macros/readline.m4)
 sinclude(config/ac-macros/ssl.m4)

+sinclude(config/ac-macros/libevent.m4)

 sinclude(config/ac-macros/zlib.m4)  

 # Remember to add a directory sql/share/LANGUAGE @@ -2275,6 +2276,7 @@ MYSQL_CHECK_BIG_TABLES

 MYSQL_CHECK_MAX_INDEXES
 MYSQL_CHECK_VIO
 MYSQL_CHECK_SSL

+MYSQL_CHECK_LIBEVENT
 
 #--------------------------------------------------------------------
 # Declare our plugin modules
diff -Nrup a/extra/Makefile.am b/extra/Makefile.am
--- a/extra/Makefile.am	2007-08-30 19:23:48 -04:00

+++ b/extra/Makefile.am 2007-10-31 15:36:49 -04:00
@@ -23,8 +23,8 @@ BUILT_SOURCES= $(top_builddir)/include/ $(top_builddir)/include/mysqld_ername.h pkginclude_HEADERS= $(BUILT_SOURCES) DISTCLEANFILES = $(BUILT_SOURCES) -SUBDIRS = @yassl_dir@ -DIST_SUBDIRS = yassl
+SUBDIRS = @yassl_dir@ @libevent_dir@
+DIST_SUBDIRS = yassl libevent

 # This will build mysqld_error.h, mysqld_ername.h and sql_state.h  # NOTE Built files should depend on their sources to avoid diff -Nrup a/extra/libevent/Makefile.am b/extra/libevent/Makefile.am

--- /dev/null	Wed Dec 31 16:00:00 196900

+++ b/extra/libevent/Makefile.am 2007-10-31 15:36:50 -04:00
@@ -0,0 +1,20 @@
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+EXTRA_DIST = select.c poll.c epoll.c epoll_sub.c devpoll.c kqueue.c \
+ evport.c evsignal.h signal.c event-internal.h README compat/sys
+
+lib_LTLIBRARIES = libevent.la
+
+SYS_LIBS =
+SYS_SRC =
+SYS_INCLUDES =
+
+libevent_la_SOURCES = event.c buffer.c evbuffer.c log.c event_tagging.c \
+ http.c evhttp.h http-internal.h evdns.c evdns.h strlcpy.c \
+ strlcpy-internal.h strlcpy-internal.h
+libevent_la_LIBADD = @LTLIBOBJS@
+libevent_la_LDFLAGS = -release 1.3e -version-info 1:3:0
+
+include_HEADERS = event.h evhttp.h evdns.h log.h
+
+INCLUDES = -Icompat -I$(top_srcdir)/include
diff -Nrup a/extra/libevent/README b/extra/libevent/README
--- /dev/null	Wed Dec 31 16:00:00 196900

+++ b/extra/libevent/README 2007-10-31 15:36:50 -04:00
@@ -0,0 +1,53 @@
+To build libevent, type
+
+$ ./configure && make
+
+Install as root via
+
+# make install
+
+You can run the regression tests by
+
+$ make verify
+
+Before, reporting any problems, please run the regression tests.
+
+To enable the low-level tracing build the library as:
+
+CFLAGS=-DUSE_DEBUG ./configure [...]
+
+Acknowledgements:
+-----------------
+
+The following people have helped with suggestions, ideas, code or
+fixing bugs:
+
+ Alejo
+ Weston Andros Adamson
+ William Ahern
+ Stas Bekman
+ Andrew Danforth
+ Mike Davis
+ Shie Erlich
+ Alexander von Gernler
+ Artur Grabowski
+ Aaron Hopkins
+ Claudio Jeker
+ Scott Lamb
+ Adam Langley
+ Philip Lewis
+ David Libenzi
+ Nick Mathewson
+ Andrey Matveev
+ Richard Nyberg
+ Jon Oberheide
+ Phil Oleson
+ Dave Pacheco
+ Tassilo von Parseval
+ Pierre Phaneuf
+ Jon Poland
+ Bert JW Regeer
+ Dug Song
+ Taral
+
+If I have forgotten your name, please contact me.
diff -Nrup a/extra/libevent/buffer.c b/extra/libevent/buffer.c
--- /dev/null	Wed Dec 31 16:00:00 196900

+++ b/extra/libevent/buffer.c 2007-10-31 15:36:50 -04:00
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2002, 2003 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_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>
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "event.h"
+
+struct evbuffer *
+evbuffer_new(void)
+{
+ struct evbuffer *buffer;
+
+ buffer = calloc(1, sizeof(struct evbuffer));
+
+ return (buffer);
+}
+
+void
+evbuffer_free(struct evbuffer *buffer)
+{
+ if (buffer->orig_buffer != NULL)
+ free(buffer->orig_buffer);
+ free(buffer);
+}
+
+/*
+ * This is a destructive add. The data from one buffer moves into
+ * the other buffer.
+ */
+
+#define SWAP(x,y) do { \
+ (x)->buffer = (y)->buffer; \
+ (x)->orig_buffer = (y)->orig_buffer; \
+ (x)->misalign = (y)->misalign; \
+ (x)->totallen = (y)->totallen; \
+ (x)->off = (y)->off; \
+} while (0)
+
+int
+evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf)
+{
+ int res;
+
+ /* Short cut for better performance */
+ if (outbuf->off == 0) {
+ struct evbuffer tmp;
+ size_t oldoff = inbuf->off;
+
+ /* Swap them directly */
+ SWAP(&tmp, outbuf);
+ SWAP(outbuf, inbuf);
+ SWAP(inbuf, &tmp);
+
+ /*
+ * Optimization comes with a price; we need to notify the
+ * buffer if necessary of the changes. oldoff is the amount
+ * of data that we transfered from inbuf to outbuf
+ */
+ if (inbuf->off != oldoff && inbuf->cb != NULL)
+ (*inbuf->cb)(inbuf, oldoff, inbuf->off, inbuf->cbarg);
+ if (oldoff && outbuf->cb != NULL)
+ (*outbuf->cb)(outbuf, 0, oldoff, outbuf->cbarg);
+
+ return (0);
+ }
+
+ res = evbuffer_add(outbuf, inbuf->buffer, inbuf->off);
+ if (res == 0) {
+ /* We drain the input buffer on success */
+ evbuffer_drain(inbuf, inbuf->off);
+ }
+
+ return (res);
+}
+
+int
+evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
+{
+ char *buffer;
+ size_t space;
+ size_t oldoff = buf->off;
+ int sz;
+ va_list aq;
+
+ /* make sure that at least some space is available */
+ evbuffer_expand(buf, 64);
+ for (;;) {
+ size_t used = buf->misalign + buf->off;
+ buffer = (char *)buf->buffer + buf->off;
+ assert(buf->totallen >= used);
+ space = buf->totallen - used;
+
+#ifndef va_copy
+#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list))
+#endif
+ va_copy(aq, ap);
+
+#ifdef WIN32
+ sz = vsnprintf(buffer, space - 1, fmt, aq);
+ buffer[space - 1] = '\0';
+#else
+ sz = vsnprintf(buffer, space, fmt, aq);
+#endif
+
+ va_end(aq);
+
+ if (sz < 0)
+ return (-1);
+ if (sz < space) {
+ buf->off += sz;
+ if (buf->cb != NULL)
+ (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
+ return (sz);
+ }
+ if (evbuffer_expand(buf, sz + 1) == -1)
+ return (-1);
+
+ }
+ /* NOTREACHED */
+}
+
+int
+evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...)
+{
+ int res = -1;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = evbuffer_add_vprintf(buf, fmt, ap);
+ va_end(ap);
+
+ return (res);
+}
+
+/* Reads data from an event buffer and drains the bytes read */
+
+int
+evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen)
+{
+ size_t nread = datlen;
+ if (nread >= buf->off)
+ nread = buf->off;
+
+ memcpy(data, buf->buffer, nread);
+ evbuffer_drain(buf, nread);
+
+ 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)
+{
+ u_char *data = EVBUFFER_DATA(buffer);
+ size_t len = EVBUFFER_LENGTH(buffer);
+ char *line;
+ unsigned 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
+evbuffer_align(struct evbuffer *buf)
+{
+ memmove(buf->orig_buffer, buf->buffer, buf->off);
+ buf->buffer = buf->orig_buffer;
+ buf->misalign = 0;
+}
+
+/* Expands the available space in the event buffer to at least datlen */
+
+int
+evbuffer_expand(struct evbuffer *buf, size_t datlen)
+{
+ size_t need = buf->misalign + buf->off + datlen;
+
+ /* If we can fit all the data, then we don't have to do anything */
+ if (buf->totallen >= need)
+ return (0);
+
+ /*
+ * If the misalignment fulfills our data needs, we just force an
+ * alignment to happen. Afterwards, we have enough space.
+ */
+ if (buf->misalign >= datlen) {
+ evbuffer_align(buf);
+ } else {
+ void *newbuf;
+ size_t length = buf->totallen;
+
+ if (length < 256)
+ length = 256;
+ while (length < need)
+ length <<= 1;
+
+ if (buf->orig_buffer != buf->buffer)
+ evbuffer_align(buf);
+ if ((newbuf = realloc(buf->buffer, length)) == NULL)
+ return (-1);
+
+ buf->orig_buffer = buf->buffer = newbuf;
+ buf->totallen = length;
+ }
+
+ return (0);
+}
+
+int
+evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen)
+{
+ size_t need = buf->misalign + buf->off + datlen;
+ size_t oldoff = buf->off;
+
+ if (buf->totallen < need) {
+ if (evbuffer_expand(buf, datlen) == -1)
+ return (-1);
+ }
+
+ memcpy(buf->buffer + buf->off, data, datlen);
+ buf->off += datlen;
+
+ if (datlen && buf->cb != NULL)
+ (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
+
+ return (0);
+}
+
+void
+evbuffer_drain(struct evbuffer *buf, size_t len)
+{
+ size_t oldoff = buf->off;
+
+ if (len >= buf->off) {
+ buf->off = 0;
+ buf->buffer = buf->orig_buffer;
+ buf->misalign = 0;
+ goto done;
+ }
+
+ buf->buffer += len;
+ buf->misalign += len;
+
+ buf->off -= len;
+
+ done:
+ /* Tell someone about changes in this buffer */
+ if (buf->off != oldoff && buf->cb != NULL)
+ (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
+
+}
+
+/*
+ * Reads data from a file descriptor into a buffer.
+ */
+
+#define EVBUFFER_MAX_READ 4096
+
+int
+evbuffer_read(struct evbuffer *buf, int fd, int howmuch)
+{
+ u_char *p;
+ size_t oldoff = buf->off;
+ int n = EVBUFFER_MAX_READ;
+#ifdef WIN32
+ DWORD dwBytesRead;
+#endif
+
+#ifdef FIONREAD
+ if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) {
+ n = EVBUFFER_MAX_READ;
+ } else if (n > EVBUFFER_MAX_READ && n > howmuch) {
+ /*
+ * It's possible that a lot of data is available for
+ * reading. We do not want to exhaust resources
+ * before the reader has a chance to do something
+ * about it. If the reader does not tell us how much
+ * data we should read, we artifically limit it.
+ */
+ if (n > buf->totallen << 2)
+ n = buf->totallen << 2;
+ if (n < EVBUFFER_MAX_READ)
+ n = EVBUFFER_MAX_READ;
+ }
+#endif
+ if (howmuch < 0 || howmuch > n)
+ howmuch = n;
+
+ /* If we don't have FIONREAD, we might waste some space here */
+ if (evbuffer_expand(buf, howmuch) == -1)
+ return (-1);
+
+ /* We can append new data at this point */
+ p = buf->buffer + buf->off;
+
+#ifndef WIN32
+ n = read(fd, p, howmuch);
+ if (n == -1)
+ return (-1);
+ if (n == 0)
+ return (0);
+#else
+ n = ReadFile((HANDLE)fd, p, howmuch, &dwBytesRead, NULL);
+ if (n == 0)
+ return (-1);
+ if (dwBytesRead == 0)
+ return (0);
+ n = dwBytesRead;
+#endif
+
+ buf->off += n;
+
+ /* Tell someone about changes in this buffer */
+ if (buf->off != oldoff && buf->cb != NULL)
+ (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
+
+ return (n);
+}
+
+int
+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)
+ return (-1);
+ if (n == 0)
+ return (0);
+#else
+ n = WriteFile((HANDLE)fd, buffer->buffer, buffer->off, &dwBytesWritten, NULL);
+ if (n == 0)
+ return (-1);
+ if (dwBytesWritten == 0)
+ return (0);
+ n = dwBytesWritten;
+#endif
+ evbuffer_drain(buffer, n);
+
+ return (n);
+}
+
+u_char *
+evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len)
+{
+ u_char *search = buffer->buffer, *end = search + buffer->off;
+ u_char *p;
+
+ while (search < end &&
+ (p = memchr(search, *what, end - search)) != NULL) {
+ if (p + len > end)
+ break;
+ if (memcmp(p, what, len) == 0)
+ return (p);
+ search = p + 1;
+ }
+
+ return (NULL);
+}
+
+void evbuffer_setcb(struct evbuffer *buffer,
+ void (*cb)(struct evbuffer *, size_t, size_t, void *),
+ void *cbarg)
+{
+ buffer->cb = cb;
+ buffer->cbarg = cbarg;
+}

diff -Nrup a/extra/libevent/compat/sys/_time.h b/extra/libevent/compat/sys/_time.h
--- /dev/null	Wed Dec 31 16:00:00 196900

+++ b/extra/libevent/compat/sys/_time.h 2007-10-31 15:36:52 -04:00
@@ -0,0 +1,163 @@
+/* $OpenBSD: time.h,v 1.11 2000/10/10 13:36:48 itojun Exp $ */
+/* $NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)time.h 8.2 (Berkeley) 7/10/94
+ */
+
+#ifndef _SYS_TIME_H_
+#define _SYS_TIME_H_
+
+#include <sys/types.h>
+
+/*
+ * Structure returned by gettimeofday(2) system call,
+ * and used in other calls.
+ */
+struct timeval {
+ long tv_sec; /* seconds */
+ long tv_usec; /* and microseconds */
+};
+
+/*
+ * Structure defined by POSIX.1b to be like a timeval.
+ */
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* and nanoseconds */
+};
+
+#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
+ (ts)->tv_sec = (tv)->tv_sec; \
+ (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+}
+#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
+ (tv)->tv_sec = (ts)->tv_sec; \
+ (tv)->tv_usec = (ts)->tv_nsec / 1000; \
+}
+
+struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+#define DST_NONE 0 /* not on dst */
+#define DST_USA 1 /* USA style dst */
+#define DST_AUST 2 /* Australian style dst */
+#define DST_WET 3 /* Western European dst */
+#define DST_MET 4 /* Middle European dst */
+#define DST_EET 5 /* Eastern European dst */
+#define DST_CAN 6 /* Canada */
+
+/* Operations on timevals. */
+#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
+#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#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))
+#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)
+
+/* Operations on timespecs. */
+#define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0
+#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec)
+#define timespeccmp(tsp, usp, cmp) \
+ (((tsp)->tv_sec == (usp)->tv_sec) ? \
+ ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
+ ((tsp)->tv_sec cmp (usp)->tv_sec))
+#define timespecadd(tsp, usp, vsp) \
+ do { \
+ (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
+ (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
+ if ((vsp)->tv_nsec >= 1000000000L) { \
+ (vsp)->tv_sec++; \
+ (vsp)->tv_nsec -= 1000000000L; \
+ } \
+ } while (0)
+#define timespecsub(tsp, usp, vsp) \
+ do { \
+ (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
+ (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
+ if ((vsp)->tv_nsec < 0) { \
+ (vsp)->tv_sec--; \
+ (vsp)->tv_nsec += 1000000000L; \
+ } \
+ } while (0)
+
+/*
+ * Names of the interval timers, and structure
+ * defining a timer setting.
+ */
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+
+/*
+ * Getkerninfo clock information structure
+ */
+struct clockinfo {
+ int hz; /* clock frequency */
+ int tick; /* micro-seconds per hz tick */
+ int tickadj; /* clock skew rate for adjtime() */
+ int stathz; /* statistics clock frequency */
+ int profhz; /* profiling clock frequency */
+};
+
+#define CLOCK_REALTIME 0
+#define CLOCK_VIRTUAL 1
+#define CLOCK_PROF 2
+
+#define TIMER_RELTIME 0x0 /* relative timer */
+#define TIMER_ABSTIME 0x1 /* absolute timer */
+
+/* --- stuff got cut here - niels --- */
+
+#endif /* !_SYS_TIME_H_ */

diff -Nrup a/extra/libevent/compat/sys/queue.h b/extra/libevent/compat/sys/queue.h
--- /dev/null	Wed Dec 31 16:00:00 196900

+++ b/extra/libevent/compat/sys/queue.h 2007-10-31 15:36:52 -04:00
@@ -0,0 +1,488 @@
+/* $OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art Exp $ */
+/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues, and circular queues.
+ *
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction. Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#ifndef WIN32
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+#endif
+
+/*
+ * Singly-linked List access methods.
+ */
+#define SLIST_FIRST(head) ((head)->slh_first)
+#define SLIST_END(head) NULL
+#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#define SLIST_FOREACH(var, head, field) \
+ for((var) = SLIST_FIRST(head); \
+ (var) != SLIST_END(head); \
+ (var) = SLIST_NEXT(var, field))
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_INIT(head) { \
+ SLIST_FIRST(head) = SLIST_END(head); \
+}
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (0)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (0)
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List access methods
+ */
+#define LIST_FIRST(head) ((head)->lh_first)
+#define LIST_END(head) NULL
+#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#define LIST_FOREACH(var, head, field) \
+ for((var) = LIST_FIRST(head); \
+ (var)!= LIST_END(head); \
+ (var) = LIST_NEXT(var, field))
+
+/*
+ * List functions.
+ */
+#define LIST_INIT(head) do { \
+ LIST_FIRST(head) = LIST_END(head); \
+} while (0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (0)
+
+#define LIST_REMOVE(elm, field) do { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+} while (0)
+
+#define LIST_REPLACE(elm, elm2, field) do { \
+ if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
+ (elm2)->field.le_next->field.le_prev = \
+ &(elm2)->field.le_next; \
+ (elm2)->field.le_prev = (elm)->field.le_prev; \
+ *(elm2)->field.le_prev = (elm2); \
+} while (0)
+
+/*
+ * Simple queue definitions.
+ */
+#define SIMPLEQ_HEAD(name, type) \
+struct name { \
+ struct type *sqh_first; /* first element */ \
+ struct type **sqh_last; /* addr of last next element */ \
+}
+
+#define SIMPLEQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).sqh_first }
+
+#define SIMPLEQ_ENTRY(type) \
+struct { \
+ struct type *sqe_next; /* next element */ \
+}
+
+/*
+ * Simple queue access methods.
+ */
+#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
+#define SIMPLEQ_END(head) NULL
+#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
+#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
+
+#define SIMPLEQ_FOREACH(var, head, field) \
+ for((var) = SIMPLEQ_FIRST(head); \
+ (var) != SIMPLEQ_END(head); \
+ (var) = SIMPLEQ_NEXT(var, field))
+
+/*
+ * Simple queue functions.
+ */
+#define SIMPLEQ_INIT(head) do { \
+ (head)->sqh_first = NULL; \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (0)
+
+#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (head)->sqh_first = (elm); \
+} while (0)
+
+#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.sqe_next = NULL; \
+ *(head)->sqh_last = (elm); \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+} while (0)
+
+#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (listelm)->field.sqe_next = (elm); \
+} while (0)
+
+#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \
+ if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (0)
+
+/*
+ * Tail queue definitions.
+ */
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+}
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+}
+
+/*
+ * tail queue access methods
+ */
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#define TAILQ_END(head) NULL
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+/* XXX */
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+#define TAILQ_EMPTY(head) \
+ (TAILQ_FIRST(head) == TAILQ_END(head))
+
+#define TAILQ_FOREACH(var, head, field) \
+ for((var) = TAILQ_FIRST(head); \
+ (var) != TAILQ_END(head); \
+ (var) = TAILQ_NEXT(var, field))
+
+#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \
+ for((var) = TAILQ_LAST(head, headname); \
+ (var) != TAILQ_END(head); \
+ (var) = TAILQ_PREV(var, headname, field))
+
+/*
+ * Tail queue functions.
+ */
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (0)
+
+#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)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_REPLACE(head, elm, elm2, field) do { \
+ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
+ (elm2)->field.tqe_next->field.tqe_prev = \
+ &(elm2)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm2)->field.tqe_next; \
+ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
+ *(elm2)->field.tqe_prev = (elm2); \
+} while (0)
+
+/*
+ * Circular queue definitions.
+ */
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_HEAD_INITIALIZER(head) \
+ { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue access methods
+ */
+#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
+#define CIRCLEQ_LAST(head) ((head)->cqh_last)
+#define CIRCLEQ_END(head) ((void *)(head))
+#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
+#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
+#define CIRCLEQ_EMPTY(head) \
+ (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
+
+#define CIRCLEQ_FOREACH(var, head, field) \
+ for((var) = CIRCLEQ_FIRST(head); \
+ (var) != CIRCLEQ_END(head); \
+ (var) = CIRCLEQ_NEXT(var, field))
+<