You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2009/12/18 18:57:52 UTC

svn commit: r892325 [2/8] - in /incubator/trafficserver/traffic/branches/dev: ./ install/ iocore/cache/ iocore/cluster/ iocore/dns/ iocore/eventsystem/ iocore/hostdb/ iocore/net/ libev/ libev/CVS/ libinktomi++/ proxy/ proxy/config/ proxy/congest/ proxy...

Modified: incubator/trafficserver/traffic/branches/dev/iocore/net/UnixUDPConnection.cc
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/iocore/net/UnixUDPConnection.cc?rev=892325&r1=892324&r2=892325&view=diff
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/iocore/net/UnixUDPConnection.cc (original)
+++ incubator/trafficserver/traffic/branches/dev/iocore/net/UnixUDPConnection.cc Fri Dec 18 17:57:46 2009
@@ -136,3 +136,22 @@
   get_UDPNetHandler(conn->ethread)->udpOutQueue.send(p);
   return ACTION_RESULT_NONE;
 }
+
+void
+UDPConnection::Release() 
+{
+  UnixUDPConnection *p = (UnixUDPConnection *) this;
+
+  p->ep.stop();
+
+  if (ink_atomic_increment(&p->refcount, -1) == 1) {
+    ink_debug_assert(p->callback_link.next == NULL);
+    ink_debug_assert(p->callback_link.prev == NULL);
+    ink_debug_assert(p->polling_link.next == NULL);
+    ink_debug_assert(p->polling_link.prev == NULL);
+    ink_debug_assert(p->newconn_alink.next == NULL);
+
+    delete this;
+  }
+}
+

Modified: incubator/trafficserver/traffic/branches/dev/iocore/net/UnixUDPNet.cc
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/iocore/net/UnixUDPNet.cc?rev=892325&r1=892324&r2=892325&view=diff
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/iocore/net/UnixUDPNet.cc (original)
+++ incubator/trafficserver/traffic/branches/dev/iocore/net/UnixUDPNet.cc Fri Dec 18 17:57:46 2009
@@ -48,7 +48,7 @@
 //
 
 UDPNetProcessorInternal udpNetInternal;
-UDPNetProcessor & udpNet = udpNetInternal;
+UDPNetProcessor &udpNet = udpNetInternal;
 
 inku64 g_udp_bytesPending;
 ink32 g_udp_periodicCleanupSlots;
@@ -74,6 +74,11 @@
   new((ink_dummy_for_new *) get_UDPPollCont(thread)) PollCont(thread->mutex);
   new((ink_dummy_for_new *) get_UDPNetHandler(thread)) UDPNetHandler;
 
+#if defined(USE_LIBEV)
+  PollCont *pc = get_UDPPollCont(thread);
+  PollDescriptor *pd = pc->pollDescriptor;
+  pd->eio = ev_loop_new(0);
+#endif
   // These are hidden variables that control the amount of memory used by UDP
   // packets.  As usual, defaults are in RecordsConfig.cc
 
@@ -207,8 +212,8 @@
     return event;
   }
   void setupPollDescriptor();
-private:
 
+private:
   Event * event;                // the completion event token created
   // on behalf of the client
   Ptr<IOBufferBlock> readbuf;
@@ -217,63 +222,27 @@
   socklen_t *fromaddrlen;
   int fd;                       // fd we are reading from
   int ifd;                      // poll fd index
-
-  int ifd_seq_num;              // some assertable information
-
   ink_hrtime period;            // polling period
   ink_hrtime elapsed_time;
   ink_hrtime timeout_interval;
-
-#ifdef DEBUG_UDP
-  DynArray<ink_hrtime> *eventStamp;
-  DynArray<int>*eventType;
-  int nevents;
-#endif
-  // some i/o information
 };
 
-#ifdef DEBUG_UDP
-static ink_hrtime default_hrtime = NULL;
-static int default_event = 0;
-#endif
-
 ClassAllocator<UDPReadContinuation> udpReadContAllocator("udpReadContAllocator");
 
 UDPReadContinuation::UDPReadContinuation(Event * completionToken)
-:Continuation(NULL),
-event(completionToken),
-readbuf(NULL),
-readlen(0), fromaddrlen(0), fd(-1), ifd(-1), ifd_seq_num(-1), period(0), elapsed_time(0), timeout_interval(0)
-#ifdef DEBUG_UDP
-  , nevents(0)
-#endif
+: Continuation(NULL), event(completionToken), readbuf(NULL),
+  readlen(0), fromaddrlen(0), fd(-1), ifd(-1), period(0), elapsed_time(0), timeout_interval(0)
 {
-#ifdef DEBUG_UDP
-  eventStamp = NEW(new DynArray<ink_hrtime> (&default_hrtime));
-  eventType = NEW(new DynArray<int>(&default_event));
-#endif
-
-  if (completionToken->continuation) {
+  if (completionToken->continuation)
     this->mutex = completionToken->continuation->mutex;
-  } else {
+  else
     this->mutex = new_ProxyMutex();
-  }
 }
 
 UDPReadContinuation::UDPReadContinuation()
-:Continuation(NULL),
-event(0),
-readbuf(NULL),
-readlen(0), fromaddrlen(0), fd(-1), ifd(-1), ifd_seq_num(-1), period(0), elapsed_time(0), timeout_interval(0)
-#ifdef DEBUG_UDP
-  , nevents(0)
-#endif
+: Continuation(NULL), event(0), readbuf(NULL),
+  readlen(0), fromaddrlen(0), fd(-1), ifd(-1), period(0), elapsed_time(0), timeout_interval(0)
 {
-#ifdef DEBUG_UDP
-  eventStamp = NEW(new DynArray<ink_hrtime> (&default_hrtime));
-  eventType = NEW(new DynArray<int>(&default_event));
-#endif
-
 }
 
 inline void
@@ -287,14 +256,10 @@
   fromaddrlen = 0;
   fd = -1;
   ifd = -1;
-  ifd_seq_num = 0;
   period = 0;
   elapsed_time = 0;
   timeout_interval = 0;
   mutex = NULL;
-#ifdef DEBUG_UDP
-  nevents = 0;
-#endif
   udpReadContAllocator.free(this);
 }
 
@@ -312,11 +277,6 @@
 inline void
 UDPReadContinuation::init_read(int rfd, IOBufferBlock * buf, int len, struct sockaddr *fromaddr_, socklen_t *fromaddrlen_)
 {
-#ifdef DEBUG_UDP
-  (*eventStamp) (nevents) = ink_get_hrtime();
-  (*eventType) (nevents) = 0;
-  nevents++;
-#endif
   ink_assert(rfd >= 0 && buf != NULL && fromaddr_ != NULL && fromaddrlen_ != NULL);
   fd = rfd;
   readbuf = buf;
@@ -346,6 +306,7 @@
 void
 UDPReadContinuation::setupPollDescriptor()
 {
+#ifdef USE_EPOLL
   Pollfd *pfd;
   EThread *et = (EThread *) this_thread();
   PollCont *pc = get_PollCont(et);
@@ -353,9 +314,9 @@
   pfd->fd = fd;
   ifd = pfd - pc->nextPollDescriptor->pfd;
   ink_assert(pc->nextPollDescriptor->nfds > ifd);
-  ifd_seq_num = pc->nextPollDescriptor->seq_num;
   pfd->events = POLLIN;
   pfd->revents = 0;
+#endif
 }
 
 int
@@ -365,15 +326,9 @@
   (void) e;
   int res;
 
-  PollCont *pc = get_PollCont(e->ethread);
+  //PollCont *pc = get_PollCont(e->ethread);
   Continuation *c;
 
-#ifdef DEBUG_UDP
-  (*eventStamp) (nevents) = ink_get_hrtime();
-  (*eventType) (nevents) = event_;
-  nevents++;
-#endif
-
   if (event->cancelled) {
     e->cancel();
     free();
@@ -392,11 +347,9 @@
       return EVENT_DONE;
     }
   }
-  ink_assert(ifd < 0 || event_ == EVENT_INTERVAL ||
-             (event_ == EVENT_POLL &&
-              ifd_seq_num == pc->pollDescriptor->seq_num &&
-              pc->pollDescriptor->nfds > ifd && pc->pollDescriptor->pfd[ifd].fd == fd));
-  if (ifd < 0 || event_ == EVENT_INTERVAL || (pc->pollDescriptor->pfd[ifd].revents & POLLIN)) {
+  //ink_assert(ifd < 0 || event_ == EVENT_INTERVAL || (event_ == EVENT_POLL && pc->pollDescriptor->nfds > ifd && pc->pollDescriptor->pfd[ifd].fd == fd));
+  //if (ifd < 0 || event_ == EVENT_INTERVAL || (pc->pollDescriptor->pfd[ifd].revents & POLLIN)) {
+  ink_debug_assert(!"incomplete");
     c = completionUtil::getContinuation(event);
     // do read
     socklen_t tmp_fromlen = *fromaddrlen;
@@ -410,11 +363,6 @@
       *fromaddrlen = tmp_fromlen;
       completionUtil::setInfo(event, fd, readbuf, rlen, errno);
       readbuf->fill(rlen);
-#ifdef DEBUG_UDP
-      (*eventStamp) (nevents) = ink_get_hrtime();
-      (*eventType) (nevents) = NET_EVENT_DATAGRAM_READ_COMPLETE;
-      nevents++;
-#endif
       res = c->handleEvent(NET_EVENT_DATAGRAM_READ_COMPLETE, event);
       e->cancel();
       free();
@@ -425,11 +373,6 @@
       *fromaddrlen = tmp_fromlen;
       completionUtil::setInfo(event, fd, (IOBufferBlock *) readbuf, rlen, errno);
       c = completionUtil::getContinuation(event);
-#ifdef DEBUG_UDP
-      (*eventStamp) (nevents) = ink_get_hrtime();
-      (*eventType) (nevents) = NET_EVENT_DATAGRAM_READ_ERROR;
-      nevents++;
-#endif
       res = c->handleEvent(NET_EVENT_DATAGRAM_READ_ERROR, event);
       e->cancel();
       free();
@@ -438,7 +381,7 @@
     } else {
       completionUtil::setThread(event, NULL);
     }
-  }
+//}
   if (event->cancelled) {
     e->cancel();
     free();
@@ -1246,36 +1189,6 @@
   return EVENT_CONT;
 }
 
-inline PollDescriptor *
-UDPNetHandler::build_one_udpread_poll(int fd, UnixUDPConnection * uc, PollDescriptor * pd)
-{
-  // XXX: just hack until figure things out
-  ink_assert(uc->getFd() > 0);
-  Pollfd *pfd = pd->alloc();
-  pfd->fd = fd;
-  pfd->events = POLLIN;
-  pfd->revents = 0;
-  return pd;
-}
-
-PollDescriptor *
-UDPNetHandler::build_poll(PollDescriptor * pd)
-{
-  // build read poll for UDP connections.
-  ink_assert(pd->empty());
-  int i = 0;
-  forl_LL(UnixUDPConnection, uc, udp_polling) {
-    if (uc->recvActive) {
-      pd = build_one_udpread_poll(uc->getFd(), uc, pd);
-      i++;
-    }
-  }
-  if (i > 500) {
-    Debug("udpnet-poll", "%d fds", i);
-  }
-  return pd;
-}
-
 int
 UDPNetHandler::mainNetEvent(int event, Event * e)
 {
@@ -1293,11 +1206,11 @@
   int i;
   int nread = 0;
 
-  struct epoll_data_ptr *temp_eptr = NULL;
+  EventIO *temp_eptr = NULL;
   for (i = 0; i < pc->pollDescriptor->result; i++) {
-    temp_eptr = (struct epoll_data_ptr *) get_ev_data(pc->pollDescriptor,i);
-    if ((get_ev_events(pc->pollDescriptor,i) & INK_EVP_IN)
-        && temp_eptr->type == EPOLL_UDP_CONNECTION) {
+    temp_eptr = (EventIO*) get_ev_data(pc->pollDescriptor,i);
+    if ((get_ev_events(pc->pollDescriptor,i) & EVENTIO_READ) 
+        && temp_eptr->type == EVENTIO_UDP_CONNECTION) {
       uc = temp_eptr->data.uc;
       ink_assert(uc && uc->mutex && uc->continuation);
       ink_assert(uc->refcount >= 1);
@@ -1459,44 +1372,20 @@
   // to call destroy(); the thread to which the UDPConnection will
   // remove the connection from a linked list and call delete.
 
-#if defined(USE_EPOLL)
-  struct epoll_event ev;
-#elif defined(USE_KQUEUE)
-  struct kevent ev;
-#else
-#error port me
-#endif
-  //changed by YTS Team, yamsat
   for (i = 0; i < numUdpPorts; i++) {
     udpConns[i]->bindToThread(cont);
-    //epoll changes
     pc = get_UDPPollCont(udpConns[i]->ethread);
-    udpConns[i]->ep.type = 5;             //UDP
-    udpConns[i]->ep.data.uc = udpConns[i];
-
-#if defined(USE_EPOLL)
-    memset(&ev, 0, sizeof(struct epoll_event));
-    ev.events = EPOLLIN | EPOLLET;
-    ev.data.ptr = &udpConns[i]->ep;
-    epoll_ctl(pc->pollDescriptor->epoll_fd, EPOLL_CTL_ADD, udpConns[i]->getFd(), &ev);
-#elif defined(USE_KQUEUE)
-    EV_SET(&ev, udpConns[i]->getFd(), EVFILT_READ, EV_ADD, 0, 0, &udpConns[i].ep);
-    kevent(pc->pollDescriptor->kqueue_fd, &ev, 1, NULL, 0, NULL);
-#else
-#error port me
-#endif
-    //epoll changes ends here
-  }                             //for
+    udpConns[i]->ep.start(pc->pollDescriptor, udpConns[i], EVENTIO_READ);
+  }
 
   resultCode = NET_EVENT_DATAGRAM_OPEN;
   goto out;
 
 Lerror:
   resultCode = NET_EVENT_DATAGRAM_ERROR;
-  for (i = 0; i < numUdpPorts; i++) {
+  for (i = 0; i < numUdpPorts; i++)
     delete udpConns[i];
-  }
-  delete[]udpConns;
+  delete[] udpConns;
   udpConns = NULL;
 
 out:

Added: incubator/trafficserver/traffic/branches/dev/libev/CVS/Entries
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/CVS/Entries?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/CVS/Entries (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/CVS/Entries Fri Dec 18 17:57:46 2009
@@ -0,0 +1,30 @@
+/ev.c/1.320/Result of merge//
+/Changes/1.153/Fri Dec 18 17:21:18 2009//
+/LICENSE/1.9/Fri Dec 18 17:21:18 2009//
+/Makefile.am/1.5/Fri Dec 18 17:21:18 2009//
+/README/1.20/Fri Dec 18 17:21:18 2009//
+/README.embed/1.29/Fri Dec 18 17:21:18 2009//
+/Symbols.ev/1.9/Fri Dec 18 17:21:18 2009//
+/Symbols.event/1.3/Fri Dec 18 17:21:18 2009//
+/autogen.sh/1.1/Fri Dec 18 17:21:18 2009//
+/configure.ac/1.25/Fri Dec 18 17:21:18 2009//
+/ev++.h/1.46/Fri Dec 18 17:21:18 2009//
+/ev.3/1.80/Fri Dec 18 17:21:18 2009//
+/ev.h/1.128/Fri Dec 18 17:21:18 2009//
+/ev.pod/1.274/Fri Dec 18 17:21:18 2009//
+/ev_epoll.c/1.49/Fri Dec 18 17:21:18 2009//
+/ev_kqueue.c/1.40/Fri Dec 18 17:21:18 2009//
+/ev_poll.c/1.31/Fri Dec 18 17:21:18 2009//
+/ev_port.c/1.18/Fri Dec 18 17:21:18 2009//
+/ev_select.c/1.46/Fri Dec 18 17:21:18 2009//
+/ev_vars.h/1.38/Fri Dec 18 17:21:18 2009//
+/ev_win32.c/1.13/Fri Dec 18 17:21:18 2009//
+/ev_wrap.h/1.28/Fri Dec 18 17:21:18 2009//
+/event.c/1.41/Fri Dec 18 17:21:18 2009//
+/event.h/1.20/Fri Dec 18 17:21:18 2009//
+/event_compat.h/1.7/Fri Dec 18 17:21:18 2009//
+/import_libevent/1.29/Fri Dec 18 17:21:18 2009//
+/libev.m4/1.11/Fri Dec 18 17:21:18 2009//
+/update_ev_wrap/1.4/Fri Dec 18 17:21:18 2009//
+/update_symbols/1.1/Fri Dec 18 17:21:18 2009//
+D

Added: incubator/trafficserver/traffic/branches/dev/libev/CVS/Repository
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/CVS/Repository?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/CVS/Repository (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/CVS/Repository Fri Dec 18 17:57:46 2009
@@ -0,0 +1 @@
+libev

Added: incubator/trafficserver/traffic/branches/dev/libev/CVS/Root
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/CVS/Root?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/CVS/Root (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/CVS/Root Fri Dec 18 17:57:46 2009
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.schmorp.de:636/schmorpforge

Added: incubator/trafficserver/traffic/branches/dev/libev/Changes
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/Changes?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/Changes (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/Changes Fri Dec 18 17:57:46 2009
@@ -0,0 +1,297 @@
+Revision history for libev, a high-performance and full-featured event loop.
+
+TODO: somehow unblock procmask?
+	- backport inotify code to C89.
+        - inotify file descriptors could leak into child processes.
+        - ev_stat watchers could keep an errornous extra ref on the loop,
+          preventing exit when unregistering all watchers (testcases
+          provided by ry@tinyclouds.org).
+        - implement EV_WIN32_HANDLE_TO_FD and EV_WIN32_CLOSE_FD configuration
+          symbols to make it easier for apps to do their own fd management.
+        - support EV_IDLE_ENABLE being disabled in ev++.h
+          (patch by Didier Spezia).
+        - point out the unspecified signal mask in the documentation.
+        - take advantage of inotify_init1, if available, to set cloexec/nonblock
+          on fd creation, to avoid races.
+        - the signal handling pipe wasn't always initialised under windows
+          (analysed by lekma).
+        - changed minimum glibc requirement from glibc 2.9 to 2.7, for
+          signalfd.
+        - add missing string.h include (Denis F. Latypoff).
+        - only replace ev_stat.prev when we detect an actual difference,
+          so prev is (almost) always different to attr. this might
+          have caused the probems with 04_stat.t.
+
+3.8  Sun Aug  9 14:30:45 CEST 2009
+	- incompatible change: do not necessarily reset signal handler
+          to SIG_DFL when a sighandler is stopped.
+        - ev_default_destroy did not properly free or zero some members,
+          potentially causing crashes and memory corruption on repated
+          ev_default_destroy/ev_default_loop calls.
+	- take advantage of signalfd on GNU/Linux systems.
+	- document that the signal mask might be in an unspecified
+          state when using libev's signal handling.
+        - take advantage of some GNU/Linux calls to set cloexec/nonblock
+          on fd creation, to avoid race conditions.
+
+3.7  Fri Jul 17 16:36:32 CEST 2009
+	- ev_unloop and ev_loop wrongly used a global variable to exit loops,
+          instead of using a per-loop variable (bug caught by accident...).
+	- the ev_set_io_collect_interval interpretation has changed.
+        - add new functionality: ev_set_userdata, ev_userdata,
+          ev_set_invoke_pending_cb, ev_set_loop_release_cb,
+          ev_invoke_pending, ev_pending_count, together with a long example
+          about thread locking.
+        - add ev_timer_remaining (as requested by Denis F. Latypoff).
+        - add ev_loop_depth.
+        - calling ev_unloop in fork/prepare watchers will no longer poll
+          for new events.
+	- Denis F. Latypoff corrected many typos in example code snippets.
+        - honor autoconf detection of EV_USE_CLOCK_SYSCALL, also double-
+          check that the syscall number is available before trying to
+          use it (reported by ry@tinyclouds).
+        - use GetSystemTimeAsFileTime instead of _timeb on windows, for
+          slightly higher accuracy.
+        - properly declare ev_loop_verify and ev_now_update even when
+          !EV_MULTIPLICITY.
+        - do not compile in any priority code when EV_MAXPRI == EV_MINPRI.
+        - support EV_MINIMAL==2 for a reduced API.
+        - actually 0-initialise struct sigaction when installing signals.
+        - add section on hibernate and stopped processes to ev_timer docs.
+
+3.6  Tue Apr 28 02:49:30 CEST 2009
+	- multiple timers becoming ready within an event loop iteration
+          will be invoked in the "correct" order now.
+	- do not leave the event loop early just because we have no active
+          watchers, fixing a problem when embedding a kqueue loop
+          that has active kernel events but no registered watchers
+          (reported by blacksand blacksand).
+	- correctly zero the idx values for arrays, so destroying and
+          reinitialising the default loop actually works (patch by
+          Malek Hadj-Ali).
+        - implement ev_suspend and ev_resume.
+        - new EV_CUSTOM revents flag for use by applications.
+        - add documentation section about priorites.
+        - add a glossary to the dcoumentation.
+        - extend the ev_fork description slightly.
+        - optimize a jump out of call_pending.
+
+3.53 Sun Feb 15 02:38:20 CET 2009
+	- fix a bug in event pipe creation on win32 that would cause a
+          failed assertion on event loop creation (patch by Malek Hadj-Ali).
+	- probe for CLOCK_REALTIME support at runtime as well and fall
+          back to gettimeofday if there is an error, to support older
+          operating systems with newer header files/libraries.
+        - prefer gettimeofday over clock_gettime with USE_CLOCK_SYSCALL
+          (default most everywhere), otherwise not.
+
+3.52 Wed Jan  7 21:43:02 CET 2009
+	- fix compilation of select backend in fd_set mode when NFDBITS is
+          missing (to get it to compile on QNX, reported by Rodrigo Campos).
+        - better select-nfds handling when select backend is in fd_set mode.
+        - diagnose fd_set overruns when select backend is in fd_set mode.
+        - due to a thinko, instead of disabling everything but
+          select on the borked OS X platform, everything but select was
+          allowed (reported by Emanuele Giaquinta).
+        - actually verify that local and remote port are matching in
+          libev's socketpair emulation, which makes denial-of-service
+          attacks harder (but not impossible - it's windows). Make sure
+          it even works under vista, which thinks that getpeer/sockname
+          should return fantasy port numbers.
+        - include "libev" in all assertion messages for potentially
+          clearer diagnostics.
+        - event_get_version (libevent compatibility) returned
+          a useless string instead of the expected version string
+          (patch by W.C.A. Wijngaards).
+
+3.51 Wed Dec 24 23:00:11 CET 2008
+        - fix a bug where an inotify watcher was added twice, causing
+          freezes on hash collisions (reported and analysed by Graham Leggett).
+	- new config symbol, EV_USE_CLOCK_SYSCALL, to make libev use
+          a direct syscall - slower, but no dependency on librt et al.
+        - assume negative return values != -1 signals success of port_getn
+          (http://cvs.epicsol.org/cgi/viewcvs.cgi/epic5/source/newio.c?rev=1.52)
+          (no known failure reports, but it doesn't hurt).
+        - fork detection in ev_embed now stops and restarts the watcher
+          automatically.
+        - EXPERIMENTAL: default the method to operator () in ev++.h,
+          to make it nicer to use functors (requested by Benedek László).
+        - fixed const object callbacks in ev++.h.
+        - replaced loop_ref argument of watcher.set (loop) by a direct
+          ev_loop * in ev++.h, to avoid clashes with functor patch.
+        - do not try to watch the empty string via inotify.
+        - inotify watchers could be leaked under certain circumstances.
+        - OS X 10.5 is actually even more broken than earlier versions,
+          so fall back to select on that piece of garbage.
+        - fixed some weirdness in the ev_embed documentation.
+
+3.49 Wed Nov 19 11:26:53 CET 2008
+	- ev_stat watchers will now use inotify as a mere hint on
+          kernels <2.6.25, or if the filesystem is not in the
+          "known to be good" list.
+        - better mingw32 compatibility (it's not as borked as native win32)
+          (analysed by Roger Pack).
+        - include stdio.h in the example program, as too many people are
+          confused by the weird C language otherwise. I guess the next thing
+          I get told is that the "..." ellipses in the examples don't compile
+          with their C compiler.
+
+3.48 Thu Oct 30 09:02:37 CET 2008
+	- further optimise away the EPOLL_CTL_ADD/MOD combo in the epoll
+          backend by assuming the kernel event mask hasn't changed if
+          ADD fails with EEXIST.
+        - work around spurious event notification bugs in epoll by using
+          a 32-bit generation counter. recreate kernel state if we receive
+          spurious notifications or unwanted events. this is very costly,
+          but I didn't come up with this horrible design.
+        - use memset to initialise most arrays now and do away with the
+          init functions.
+        - expand time-out strategies into a "Be smart about timeouts" section.
+        - drop the "struct" from all ev_watcher declarations in the
+          documentation and did other clarifications (yeah, it was a mistake
+          to have a struct AND a function called ev_loop).
+	- fix a bug where ev_default would not initialise the default
+          loop again after it was destroyed with ev_default_destroy.
+        - rename syserr to ev_syserr to avoid name clashes when embedding,
+          do similar changes for event.c.
+
+3.45 Tue Oct 21 21:59:26 CEST 2008
+	- disable inotify usage on linux <2.6.25, as it is broken
+          (reported by Yoann Vandoorselaere).
+        - ev_stat errornously would try to add inotify watchers
+          even when inotify wasn't available (this should only
+          have a performance impact).
+	- ev_once now passes both timeout and io to the callback if both
+          occur concurrently, instead of giving timeouts precedence.
+	- disable EV_USE_INOTIFY when sys/inotify.h is too old.
+
+3.44 Mon Sep 29 05:18:39 CEST 2008
+	- embed watchers now automatically invoke ev_loop_fork on the
+          embedded loop when the parent loop forks.
+	- new function: ev_now_update (loop).
+	- verify_watcher was not marked static.
+        - improve the "associating..." manpage section.
+        - documentation tweaks here and there.
+
+3.43 Sun Jul  6 05:34:41 CEST 2008
+	- include more include files on windows to get struct _stati64
+          (reported by Chris Hulbert, but doesn't quite fix his issue).
+	- add missing #include <io.h> in ev.c on windows (reported by
+          Matt Tolton).
+
+3.42 Tue Jun 17 12:12:07 CEST 2008
+	- work around yet another windows bug: FD_SET actually adds fd's
+          multiple times to the fd_*SET*, despite official MSN docs claiming
+          otherwise. Reported and well-analysed by Matt Tolton.
+	- define NFDBITS to 0 when EV_SELECT_IS_WINSOCKET to make it compile
+          (reported any analysed by Chris Hulbert).
+        - fix a bug in ev_ebadf (this function is only used to catch
+          programming errors in the libev user). reported by Matt Tolton.
+        - fix a bug in fd_intern on win32 (could lead to compile errors
+          under some circumstances, but would work correctly if it compiles).
+          reported by Matt Tolton.
+        - (try to) work around missing lstat on windows.
+	- pass in the write fd set as except fd set under windows. windows
+          is so uncontrollably lame that it requires this. this means that
+          switching off oobinline is not supported (but tcp/ip doesn't
+          have oob, so that would be stupid anyways.
+        - use posix module symbol to auto-detect monotonic clock presence
+          and some other default values.
+
+3.41 Fri May 23 18:42:54 CEST 2008
+	- work around an obscure bug in winsocket select: if you
+          provide only empty fd sets then select returns WSAEINVAL. how sucky.
+        - improve timer scheduling stability and reduce use of time_epsilon.
+        - use 1-based 2-heap for EV_MINIMAL, simplifies code, reduces
+          codesize and makes for better cache-efficiency.
+        - use 3-based 4-heap for !EV_MINIMAL. this makes better use
+          of cpu cache lines and gives better growth behaviour than
+          2-based heaps.
+        - cache timestamp within heap for !EV_MINIMAL, to avoid random
+          memory accesses.
+        - document/add EV_USE_4HEAP and EV_HEAP_CACHE_AT.
+        - fix a potential aliasing issue in ev_timer_again.
+        - add/document ev_periodic_at, retract direct access to ->at.
+        - improve ev_stat docs.
+        - add portability requirements section.
+	- fix manpage headers etc.
+        - normalise WSA error codes to lower range on windows.
+        - add consistency check code that can be called automatically
+          or on demand to check for internal structures (ev_loop_verify).
+
+3.31 Wed Apr 16 20:45:04 CEST 2008
+	- added last minute fix for ev_poll.c by Brandon Black.
+
+3.3  Wed Apr 16 19:04:10 CEST 2008
+        - event_base_loopexit should return 0 on success
+          (W.C.A. Wijngaards).
+	- added linux eventfd support.
+        - try to autodetect epoll and inotify support
+          by libc header version if not using autoconf.
+        - new symbols: EV_DEFAULT_UC and EV_DEFAULT_UC_.
+        - declare functions defined in ev.h as inline if
+          C99 or gcc are available.
+        - enable inlining with gcc versions 2 and 3.
+        - work around broken poll implementations potentially
+          not clearing revents field in ev_poll (Brandon Black)
+          (no such systems are known at this time).
+        - work around a bug in realloc on openbsd and darwin,
+          also makes the errornous valgrind complaints
+          go away (noted by various people).
+        - fix ev_async_pending, add c++ wrapper for ev_async
+          (based on patch sent by Johannes Deisenhofer.
+        - add sensible set method to ev::embed.
+        - made integer constants type int in ev.h.
+
+3.2  Wed Apr  2 17:11:19 CEST 2008
+	- fix a 64 bit overflow issue in the select backend,
+          by using fd_mask instead of int for the mask.
+        - rename internal sighandler to avoid clash with very old perls.
+        - entering ev_loop will not clear the ONESHOT or NONBLOCKING
+          flags of any outer loops anymore.
+        - add ev_async_pending.
+
+3.1  Thu Mar 13 13:45:22 CET 2008
+	- implement ev_async watchers.
+        - only initialise signal pipe on demand.
+	- make use of sig_atomic_t configurable.
+        - improved documentation.
+
+3.0  Mon Jan 28 13:14:47 CET 2008
+	- API/ABI bump to version 3.0.
+	- ev++.h includes "ev.h" by default now, not <ev.h>.
+	- slightly improved documentation.
+	- speed up signal detection after a fork.
+        - only optionally return trace status changed in ev_child
+          watchers.
+        - experimental (and undocumented) loop wrappers for ev++.h.
+
+2.01 Tue Dec 25 08:04:41 CET 2007
+	- separate Changes file.
+	- fix ev_path_set => ev_stat_set typo.
+        - remove event_compat.h from the libev tarball.
+        - change how include files are found.
+        - doc updates.
+        - update licenses, explicitly allow for GPL relicensing.
+
+2.0  Sat Dec 22 17:47:03 CET 2007
+        - new ev_sleep, ev_set_(io|timeout)_collect_interval.
+        - removed epoll from embeddable fd set.
+        - fix embed watchers.
+	- renamed ev_embed.loop to other.
+	- added exported Symbol tables.
+        - undefine member wrapper macros at the end of ev.c.
+        - respect EV_H in ev++.h.
+
+1.86 Tue Dec 18 02:36:57 CET 2007
+	- fix memleak on loop destroy (not relevant for perl).
+
+1.85 Fri Dec 14 20:32:40 CET 2007
+        - fix some aliasing issues w.r.t. timers and periodics
+          (not relevant for perl).
+
+(for historic versions refer to EV/Changes, found in the Perl interface)
+
+0.1  Wed Oct 31 21:31:48 CET 2007
+	- original version; hacked together in <24h.
+

Added: incubator/trafficserver/traffic/branches/dev/libev/LICENSE
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/LICENSE?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/LICENSE (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/LICENSE Fri Dec 18 17:57:46 2009
@@ -0,0 +1,36 @@
+All files in libev are Copyright (C)2007,2008,2009 Marc Alexander Lehmann.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * 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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+OWNER 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.
+
+Alternatively, the contents of this package may be used under the terms
+of the GNU General Public License ("GPL") version 2 or any later version,
+in which case the provisions of the GPL are applicable instead of the
+above. If you wish to allow the use of your version of this package only
+under the terms of the GPL and not to allow others to use your version of
+this file under the BSD license, indicate your decision by deleting the
+provisions above and replace them with the notice and other provisions
+required by the GPL in this and the other files of this package. If you do
+not delete the provisions above, a recipient may use your version of this
+file under either the BSD or the GPL.

Added: incubator/trafficserver/traffic/branches/dev/libev/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/Makefile.am?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/Makefile.am (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/Makefile.am Fri Dec 18 17:57:46 2009
@@ -0,0 +1,18 @@
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+VERSION_INFO = 3:0
+
+EXTRA_DIST = LICENSE Changes libev.m4 autogen.sh \
+	     ev_vars.h ev_wrap.h \
+	     ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c \
+	     ev.3 ev.pod
+
+man_MANS = ev.3
+
+include_HEADERS = ev.h ev++.h event.h
+
+lib_LTLIBRARIES = libev.la
+
+libev_la_SOURCES = ev.c event.c
+libev_la_LDFLAGS = -version-info $(VERSION_INFO)
+

Added: incubator/trafficserver/traffic/branches/dev/libev/README
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/README?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/README (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/README Fri Dec 18 17:57:46 2009
@@ -0,0 +1,58 @@
+libev is a high-performance event loop/event model with lots of features.
+(see benchmark at http://libev.schmorp.de/bench.html)
+
+
+ABOUT
+
+   Homepage: http://software.schmorp.de/pkg/libev
+   Mailinglist: libev@lists.schmorp.de
+                http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
+   Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
+
+   Libev is modelled (very losely) after libevent and the Event perl
+   module, but is faster, scales better and is more correct, and also more
+   featureful. And also smaller. Yay.
+
+   Some of the specialties of libev not commonly found elsewhere are:
+   
+   - extensive and detailed, readable documentation (not doxygen garbage).
+   - fully supports fork, can detect fork in various ways and automatically
+     re-arms kernel mechanisms that do not support fork.
+   - highly optimised select, poll, epoll, kqueue and event ports backends.
+   - filesystem object (path) watching (with optional linux inotify support).
+   - wallclock-based times (using absolute time, cron-like).
+   - relative timers/timeouts (handle time jumps).
+   - fast intra-thread communication between multiple
+     event loops (with optional fast linux eventfd backend).
+   - extremely easy to embed.
+   - very small codebase, no bloated library.
+   - fully extensible by being able to plug into the event loop,
+     integrate other event loops, integrate other event loop users.
+   - very little memory use (small watchers, small event loop data).
+   - optional C++ interface allowing method and function callbacks
+     at no extra memory or runtime overhead.
+   - optional Perl interface with similar characteristics (capable
+     of running Glib/Gtk2 on libev, interfaces with Net::SNMP and
+     libadns).
+   - support for other languages (multiple C++ interfaces, D, Ruby,
+     Python) available from third-parties.
+
+   Examples of programs that embed libev: the EV perl module,
+   rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the Deliantra MMORPG
+   server (http://www.deliantra.net/), Rubinius (a next-generation Ruby
+   VM), the Ebb web server, the Rev event toolkit.
+
+
+CONTRIBUTORS
+
+   libev was written and designed by Marc Lehmann and Emanuele Giaquinta.
+
+   The following people sent in patches or made other noteworthy
+   contributions to the design (for minor patches, see the Changes
+   file. If I forgot to include you, please shout at me, it was an
+   accident):
+
+   W.C.A. Wijngaards
+   Christopher Layne
+   Chris Brody
+

Added: incubator/trafficserver/traffic/branches/dev/libev/README.embed
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/README.embed?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/README.embed (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/README.embed Fri Dec 18 17:57:46 2009
@@ -0,0 +1,3 @@
+This file is now included in the main libev documentation, see
+
+   http://cvs.schmorp.de/libev/ev.html

Added: incubator/trafficserver/traffic/branches/dev/libev/README.trafficserver
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/README.trafficserver?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/README.trafficserver (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/README.trafficserver Fri Dec 18 17:57:46 2009
@@ -0,0 +1,6 @@
+Slightly modified to expose an internal function
+
+Steps:
+1. autoreconf -i
+2. run configure.trafficserver to build with defaults
+3. install normally

Added: incubator/trafficserver/traffic/branches/dev/libev/Symbols.ev
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/Symbols.ev?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/Symbols.ev (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/Symbols.ev Fri Dec 18 17:57:46 2009
@@ -0,0 +1,72 @@
+ev_async_send
+ev_async_start
+ev_async_stop
+ev_backend
+ev_check_start
+ev_check_stop
+ev_child_start
+ev_child_stop
+ev_clear_pending
+ev_default_destroy
+ev_default_fork
+ev_default_loop_init
+ev_default_loop_ptr
+ev_embed_start
+ev_embed_stop
+ev_embed_sweep
+ev_embeddable_backends
+ev_feed_event
+ev_feed_fd_event
+ev_feed_signal_event
+ev_fork_start
+ev_fork_stop
+ev_idle_start
+ev_idle_stop
+ev_invoke
+ev_invoke_pending
+ev_io_start
+ev_io_stop
+ev_loop
+ev_loop_count
+ev_loop_depth
+ev_loop_destroy
+ev_loop_fork
+ev_loop_new
+ev_loop_verify
+ev_now
+ev_now_update
+ev_once
+ev_pending_count
+ev_periodic_again
+ev_periodic_start
+ev_periodic_stop
+ev_prepare_start
+ev_prepare_stop
+ev_recommended_backends
+ev_ref
+ev_resume
+ev_set_allocator
+ev_set_invoke_pending_cb
+ev_set_io_collect_interval
+ev_set_loop_release_cb
+ev_set_syserr_cb
+ev_set_timeout_collect_interval
+ev_set_userdata
+ev_signal_start
+ev_signal_stop
+ev_sleep
+ev_stat_start
+ev_stat_stat
+ev_stat_stop
+ev_supported_backends
+ev_suspend
+ev_time
+ev_timer_again
+ev_timer_remaining
+ev_timer_start
+ev_timer_stop
+ev_unloop
+ev_unref
+ev_userdata
+ev_version_major
+ev_version_minor

Added: incubator/trafficserver/traffic/branches/dev/libev/Symbols.event
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/Symbols.event?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/Symbols.event (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/Symbols.event Fri Dec 18 17:57:46 2009
@@ -0,0 +1,21 @@
+event_active
+event_add
+event_base_dispatch
+event_base_free
+event_base_loop
+event_base_loopexit
+event_base_once
+event_base_priority_init
+event_base_set
+event_del
+event_dispatch
+event_get_method
+event_get_version
+event_init
+event_loop
+event_loopexit
+event_once
+event_pending
+event_priority_init
+event_priority_set
+event_set

Added: incubator/trafficserver/traffic/branches/dev/libev/autogen.sh
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/autogen.sh?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/autogen.sh (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/autogen.sh Fri Dec 18 17:57:46 2009
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+libtoolize --force
+automake --add-missing
+autoreconf
+

Added: incubator/trafficserver/traffic/branches/dev/libev/configure.ac
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/configure.ac?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/configure.ac (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/configure.ac Fri Dec 18 17:57:46 2009
@@ -0,0 +1,18 @@
+AC_INIT
+AC_CONFIG_SRCDIR([ev_epoll.c])
+
+AM_INIT_AUTOMAKE(libev,3.8) dnl also update ev.h!
+AC_CONFIG_HEADERS([config.h])
+AM_MAINTAINER_MODE
+
+AC_PROG_INSTALL
+AC_PROG_LIBTOOL
+
+if test "x$GCC" = xyes ; then
+  CFLAGS="$CFLAGS -O3"
+fi
+
+m4_include([libev.m4])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT

Added: incubator/trafficserver/traffic/branches/dev/libev/configure.trafficserver
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/configure.trafficserver?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/configure.trafficserver (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/configure.trafficserver Fri Dec 18 17:57:46 2009
@@ -0,0 +1,2 @@
+#!/bin/sh
+./configure CFLAGS="$CFLAGS -Dinline_size= -DEV_MINPRI=0 -DEV_MAXPRI=0"

Propchange: incubator/trafficserver/traffic/branches/dev/libev/configure.trafficserver
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/trafficserver/traffic/branches/dev/libev/ev++.h
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libev/ev%2B%2B.h?rev=892325&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libev/ev++.h (added)
+++ incubator/trafficserver/traffic/branches/dev/libev/ev++.h Fri Dec 18 17:57:46 2009
@@ -0,0 +1,795 @@
+/*
+ * libev simple C++ wrapper classes
+ *
+ * Copyright (c) 2007,2008 Marc Alexander Lehmann <li...@schmorp.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, 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.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, 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 OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ */
+
+#ifndef EVPP_H__
+#define EVPP_H__
+
+#ifdef EV_H
+# include EV_H
+#else
+# include "ev.h"
+#endif
+
+#ifndef EV_USE_STDEXCEPT
+# define EV_USE_STDEXCEPT 1
+#endif
+
+#if EV_USE_STDEXCEPT
+# include <stdexcept>
+#endif
+
+namespace ev {
+
+  typedef ev_tstamp tstamp;
+
+  enum
+  {
+    UNDEF    = EV_UNDEF,
+    NONE     = EV_NONE,
+    READ     = EV_READ,
+    WRITE    = EV_WRITE,
+    TIMEOUT  = EV_TIMEOUT,
+    PERIODIC = EV_PERIODIC,
+    SIGNAL   = EV_SIGNAL,
+    CHILD    = EV_CHILD,
+    STAT     = EV_STAT,
+    IDLE     = EV_IDLE,
+    CHECK    = EV_CHECK,
+    PREPARE  = EV_PREPARE,
+    FORK     = EV_FORK,
+    ASYNC    = EV_ASYNC,
+    EMBED    = EV_EMBED,
+#   undef ERROR // some systems stupidly #define ERROR
+    ERROR    = EV_ERROR,
+  };
+
+  enum
+  {
+    AUTO      = EVFLAG_AUTO,
+    NOENV     = EVFLAG_NOENV,
+    FORKCHECK = EVFLAG_FORKCHECK,
+
+    SELECT    = EVBACKEND_SELECT,
+    POLL      = EVBACKEND_POLL,
+    EPOLL     = EVBACKEND_EPOLL,
+    KQUEUE    = EVBACKEND_KQUEUE,
+    DEVPOLL   = EVBACKEND_DEVPOLL,
+    PORT      = EVBACKEND_PORT
+  };
+
+  enum
+  {
+    NONBLOCK = EVLOOP_NONBLOCK,
+    ONESHOT  = EVLOOP_ONESHOT
+  };
+
+  enum how_t
+  {
+    ONE = EVUNLOOP_ONE,
+    ALL = EVUNLOOP_ALL
+  };
+
+  struct bad_loop
+#if EV_USE_STDEXCEPT
+  : std::runtime_error
+#endif
+  {
+#if EV_USE_STDEXCEPT
+    bad_loop ()
+    : std::runtime_error ("libev event loop cannot be initialized, bad value of LIBEV_FLAGS?")
+    {
+    }
+#endif
+  };
+
+#ifdef EV_AX
+#  undef EV_AX
+#endif
+
+#ifdef EV_AX_
+#  undef EV_AX_
+#endif
+
+#if EV_MULTIPLICITY
+#  define EV_AX  raw_loop
+#  define EV_AX_ raw_loop,
+#else
+#  define EV_AX
+#  define EV_AX_
+#endif
+
+  struct loop_ref
+  {
+    loop_ref (EV_P) throw ()
+#if EV_MULTIPLICITY
+    : EV_AX (EV_A)
+#endif
+    {
+    }
+
+    bool operator == (const loop_ref &other) const throw ()
+    {
+#if EV_MULTIPLICITY
+      return EV_AX == other.EV_AX;
+#else
+      return true;
+#endif
+    }
+
+    bool operator != (const loop_ref &other) const throw ()
+    {
+#if EV_MULTIPLICITY
+      return ! (*this == other);
+#else
+      return false;
+#endif
+    }
+
+#if EV_MULTIPLICITY
+    bool operator == (const EV_P) const throw ()
+    {
+      return this->EV_AX == EV_A;
+    }
+
+    bool operator != (const EV_P) const throw ()
+    {
+      return (*this == EV_A);
+    }
+
+    operator struct ev_loop * () const throw ()
+    {
+      return EV_AX;
+    }
+
+    operator const struct ev_loop * () const throw ()
+    {
+      return EV_AX;
+    }
+
+    bool is_default () const throw ()
+    {
+      return EV_AX == ev_default_loop (0);
+    }
+#endif
+
+    void loop (int flags = 0)
+    {
+      ev_loop (EV_AX_ flags);
+    }
+
+    void unloop (how_t how = ONE) throw ()
+    {
+      ev_unloop (EV_AX_ how);
+    }
+
+    void post_fork () throw ()
+    {
+#if EV_MULTIPLICITY
+      ev_loop_fork (EV_AX);
+#else
+      ev_default_fork ();
+#endif
+    }
+
+    unsigned int backend () const throw ()
+    {
+      return ev_backend (EV_AX);
+    }
+
+    tstamp now () const throw ()
+    {
+      return ev_now (EV_AX);
+    }
+
+    void ref () throw ()
+    {
+      ev_ref (EV_AX);
+    }
+
+    void unref () throw ()
+    {
+      ev_unref (EV_AX);
+    }
+
+#if EV_MINIMAL < 2
+    unsigned int count () const throw ()
+    {
+      return ev_loop_count (EV_AX);
+    }
+
+    unsigned int depth () const throw ()
+    {
+      return ev_loop_depth (EV_AX);
+    }
+
+    void set_io_collect_interval (tstamp interval) throw ()
+    {
+      ev_set_io_collect_interval (EV_AX_ interval);
+    }
+
+    void set_timeout_collect_interval (tstamp interval) throw ()
+    {
+      ev_set_timeout_collect_interval (EV_AX_ interval);
+    }
+#endif
+
+    // function callback
+    void once (int fd, int events, tstamp timeout, void (*cb)(int, void *), void *arg = 0) throw ()
+    {
+      ev_once (EV_AX_ fd, events, timeout, cb, arg);
+    }
+
+    // method callback
+    template<class K, void (K::*method)(int)>
+    void once (int fd, int events, tstamp timeout, K *object) throw ()
+    {
+      once (fd, events, timeout, method_thunk<K, method>, object);
+    }
+
+    // default method == operator ()
+    template<class K>
+    void once (int fd, int events, tstamp timeout, K *object) throw ()
+    {
+      once (fd, events, timeout, method_thunk<K, &K::operator ()>, object);
+    }
+
+    template<class K, void (K::*method)(int)>
+    static void method_thunk (int revents, void *arg)
+    {
+      static_cast<K *>(arg)->*method
+        (revents);
+    }
+
+    // no-argument method callback
+    template<class K, void (K::*method)()>
+    void once (int fd, int events, tstamp timeout, K *object) throw ()
+    {
+      once (fd, events, timeout, method_noargs_thunk<K, method>, object);
+    }
+
+    template<class K, void (K::*method)()>
+    static void method_noargs_thunk (int revents, void *arg)
+    {
+      static_cast<K *>(arg)->*method
+        ();
+    }
+
+    // simpler function callback
+    template<void (*cb)(int)>
+    void once (int fd, int events, tstamp timeout) throw ()
+    {
+      once (fd, events, timeout, simpler_func_thunk<cb>);
+    }
+
+    template<void (*cb)(int)>
+    static void simpler_func_thunk (int revents, void *arg)
+    {
+      (*cb)
+        (revents);
+    }
+
+    // simplest function callback
+    template<void (*cb)()>
+    void once (int fd, int events, tstamp timeout) throw ()
+    {
+      once (fd, events, timeout, simplest_func_thunk<cb>);
+    }
+
+    template<void (*cb)()>
+    static void simplest_func_thunk (int revents, void *arg)
+    {
+      (*cb)
+        ();
+    }
+
+    void feed_fd_event (int fd, int revents) throw ()
+    {
+      ev_feed_fd_event (EV_AX_ fd, revents);
+    }
+
+    void feed_signal_event (int signum) throw ()
+    {
+      ev_feed_signal_event (EV_AX_ signum);
+    }
+
+#if EV_MULTIPLICITY
+    struct ev_loop* EV_AX;
+#endif
+
+  };
+
+#if EV_MULTIPLICITY
+  struct dynamic_loop : loop_ref
+  {
+
+    dynamic_loop (unsigned int flags = AUTO) throw (bad_loop)
+    : loop_ref (ev_loop_new (flags))
+    {
+      if (!EV_AX)
+        throw bad_loop ();
+    }
+
+    ~dynamic_loop () throw ()
+    {
+      ev_loop_destroy (EV_AX);
+      EV_AX = 0;
+    }
+
+  private:
+
+    dynamic_loop (const dynamic_loop &);
+
+    dynamic_loop & operator= (const dynamic_loop &);
+
+  };
+#endif
+
+  struct default_loop : loop_ref
+  {
+    default_loop (unsigned int flags = AUTO) throw (bad_loop)
+#if EV_MULTIPLICITY
+    : loop_ref (ev_default_loop (flags))
+#endif
+    {
+      if (
+#if EV_MULTIPLICITY
+          !EV_AX
+#else
+          !ev_default_loop (flags)
+#endif
+      )
+        throw bad_loop ();
+    }
+
+    ~default_loop () throw ()
+    {
+      ev_default_destroy ();
+    }
+
+  private:
+    default_loop (const default_loop &);
+    default_loop &operator = (const default_loop &);
+  };
+
+  inline loop_ref get_default_loop () throw ()
+  {
+#if EV_MULTIPLICITY
+    return ev_default_loop (0);
+#else
+    return loop_ref ();
+#endif
+  }
+
+#undef EV_AX
+#undef EV_AX_
+
+#undef EV_PX
+#undef EV_PX_
+#if EV_MULTIPLICITY
+#  define EV_PX  loop_ref EV_A
+#  define EV_PX_ loop_ref EV_A_
+#else
+#  define EV_PX
+#  define EV_PX_
+#endif
+
+  template<class ev_watcher, class watcher>
+  struct base : ev_watcher
+  {
+    #if EV_MULTIPLICITY
+      EV_PX;
+
+      void set (EV_P) throw ()
+      {
+        this->EV_A = EV_A;
+      }
+    #endif
+
+    base (EV_PX) throw ()
+    #if EV_MULTIPLICITY
+      : EV_A (EV_A)
+    #endif
+    {
+      ev_init (this, 0);
+    }
+
+    void set_ (const void *data, void (*cb)(EV_P_ ev_watcher *w, int revents)) throw ()
+    {
+      this->data = (void *)data;
+      ev_set_cb (static_cast<ev_watcher *>(this), cb);
+    }
+
+    // function callback
+    template<void (*function)(watcher &w, int)>
+    void set (void *data = 0) throw ()
+    {
+      set_ (data, function_thunk<function>);
+    }
+
+    template<void (*function)(watcher &w, int)>
+    static void function_thunk (EV_P_ ev_watcher *w, int revents)
+    {
+      function
+        (*static_cast<watcher *>(w), revents);
+    }
+
+    // method callback
+    template<class K, void (K::*method)(watcher &w, int)>
+    void set (K *object) throw ()
+    {
+      set_ (object, method_thunk<K, method>);
+    }
+
+    // default method == operator ()
+    template<class K>
+    void set (K *object) throw ()
+    {
+      set_ (object, method_thunk<K, &K::operator ()>);
+    }
+
+    template<class K, void (K::*method)(watcher &w, int)>
+    static void method_thunk (EV_P_ ev_watcher *w, int revents)
+    {
+      (static_cast<K *>(w->data)->*method)
+        (*static_cast<watcher *>(w), revents);
+    }
+
+    // no-argument callback
+    template<class K, void (K::*method)()>
+    void set (K *object) throw ()
+    {
+      set_ (object, method_noargs_thunk<K, method>);
+    }
+
+    template<class K, void (K::*method)()>
+    static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents)
+    {
+      static_cast<K *>(w->data)->*method
+        ();
+    }
+
+    void operator ()(int events = EV_UNDEF)
+    {
+      return
+        ev_cb (static_cast<ev_watcher *>(this))
+          (static_cast<ev_watcher *>(this), events);
+    }
+
+    bool is_active () const throw ()
+    {
+      return ev_is_active (static_cast<const ev_watcher *>(this));
+    }
+
+    bool is_pending () const throw ()
+    {
+      return ev_is_pending (static_cast<const ev_watcher *>(this));
+    }
+
+    void feed_event (int revents) throw ()
+    {
+      ev_feed_event (EV_A_ static_cast<const ev_watcher *>(this), revents);
+    }
+  };
+
+  inline tstamp now () throw ()
+  {
+    return ev_time ();
+  }
+
+  inline void delay (tstamp interval) throw ()
+  {
+    ev_sleep (interval);
+  }
+
+  inline int version_major () throw ()
+  {
+    return ev_version_major ();
+  }
+
+  inline int version_minor () throw ()
+  {
+    return ev_version_minor ();
+  }
+
+  inline unsigned int supported_backends () throw ()
+  {
+    return ev_supported_backends ();
+  }
+
+  inline unsigned int recommended_backends () throw ()
+  {
+    return ev_recommended_backends ();
+  }
+
+  inline unsigned int embeddable_backends () throw ()
+  {
+    return ev_embeddable_backends ();
+  }
+
+  inline void set_allocator (void *(*cb)(void *ptr, long size)) throw ()
+  {
+    ev_set_allocator (cb);
+  }
+
+  inline void set_syserr_cb (void (*cb)(const char *msg)) throw ()
+  {
+    ev_set_syserr_cb (cb);
+  }
+
+  #if EV_MULTIPLICITY
+    #define EV_CONSTRUCT(cppstem,cstem)	                                                \
+      (EV_PX = get_default_loop ()) throw ()                                            \
+        : base<ev_ ## cstem, cppstem> (EV_A)                                            \
+      {                                                                                 \
+      }
+  #else
+    #define EV_CONSTRUCT(cppstem,cstem)                                                 \
+      () throw ()                                                                       \
+      {                                                                                 \
+      }
+  #endif
+
+  /* using a template here would require quite a bit more lines,
+   * so a macro solution was chosen */
+  #define EV_BEGIN_WATCHER(cppstem,cstem)	                                        \
+                                                                                        \
+  struct cppstem : base<ev_ ## cstem, cppstem>                                          \
+  {                                                                                     \
+    void start () throw ()                                                              \
+    {                                                                                   \
+      ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this));                 \
+    }                                                                                   \
+                                                                                        \
+    void stop () throw ()                                                               \
+    {                                                                                   \
+      ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this));                  \
+    }                                                                                   \
+                                                                                        \
+    cppstem EV_CONSTRUCT(cppstem,cstem)                                                 \
+                                                                                        \
+    ~cppstem () throw ()                                                                \
+    {                                                                                   \
+      stop ();                                                                          \
+    }                                                                                   \
+                                                                                        \
+    using base<ev_ ## cstem, cppstem>::set;                                             \
+                                                                                        \
+  private:                                                                              \
+                                                                                        \
+    cppstem (const cppstem &o);                                                         \
+                                                                                        \
+    cppstem &operator =(const cppstem &o);                                              \
+                                                                                        \
+  public:
+
+  #define EV_END_WATCHER(cppstem,cstem)	                                                \
+  };
+
+  EV_BEGIN_WATCHER (io, io)
+    void set (int fd, int events) throw ()
+    {
+      int active = is_active ();
+      if (active) stop ();
+      ev_io_set (static_cast<ev_io *>(this), fd, events);
+      if (active) start ();
+    }
+
+    void set (int events) throw ()
+    {
+      int active = is_active ();
+      if (active) stop ();
+      ev_io_set (static_cast<ev_io *>(this), fd, events);
+      if (active) start ();
+    }
+
+    void start (int fd, int events) throw ()
+    {
+      set (fd, events);
+      start ();
+    }
+  EV_END_WATCHER (io, io)
+
+  EV_BEGIN_WATCHER (timer, timer)
+    void set (ev_tstamp after, ev_tstamp repeat = 0.) throw ()
+    {
+      int active = is_active ();
+      if (active) stop ();
+      ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
+      if (active) start ();
+    }
+
+    void start (ev_tstamp after, ev_tstamp repeat = 0.) throw ()
+    {
+      set (after, repeat);
+      start ();
+    }
+
+    void again () throw ()
+    {
+      ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
+    }
+  EV_END_WATCHER (timer, timer)
+
+  #if EV_PERIODIC_ENABLE
+  EV_BEGIN_WATCHER (periodic, periodic)
+    void set (ev_tstamp at, ev_tstamp interval = 0.) throw ()
+    {
+      int active = is_active ();
+      if (active) stop ();
+      ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
+      if (active) start ();
+    }
+
+    void start (ev_tstamp at, ev_tstamp interval = 0.) throw ()
+    {
+      set (at, interval);
+      start ();
+    }
+
+    void again () throw ()
+    {
+      ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
+    }
+  EV_END_WATCHER (periodic, periodic)
+  #endif
+
+  EV_BEGIN_WATCHER (sig, signal)
+    void set (int signum) throw ()
+    {
+      int active = is_active ();
+      if (active) stop ();
+      ev_signal_set (static_cast<ev_signal *>(this), signum);
+      if (active) start ();
+    }
+
+    void start (int signum) throw ()
+    {
+      set (signum);
+      start ();
+    }
+  EV_END_WATCHER (sig, signal)
+
+  EV_BEGIN_WATCHER (child, child)
+    void set (int pid, int trace = 0) throw ()
+    {
+      int active = is_active ();
+      if (active) stop ();
+      ev_child_set (static_cast<ev_child *>(this), pid, trace);
+      if (active) start ();
+    }
+
+    void start (int pid, int trace = 0) throw ()
+    {
+      set (pid, trace);
+      start ();
+    }
+  EV_END_WATCHER (child, child)
+
+  #if EV_STAT_ENABLE
+  EV_BEGIN_WATCHER (stat, stat)
+    void set (const char *path, ev_tstamp interval = 0.) throw ()
+    {
+      int active = is_active ();
+      if (active) stop ();
+      ev_stat_set (static_cast<ev_stat *>(this), path, interval);
+      if (active) start ();
+    }
+
+    void start (const char *path, ev_tstamp interval = 0.) throw ()
+    {
+      stop ();
+      set (path, interval);
+      start ();
+    }
+
+    void update () throw ()
+    {
+      ev_stat_stat (EV_A_ static_cast<ev_stat *>(this));
+    }
+  EV_END_WATCHER (stat, stat)
+  #endif
+
+#if EV_IDLE_ENABLE
+  EV_BEGIN_WATCHER (idle, idle)
+    void set () throw () { }
+  EV_END_WATCHER (idle, idle)
+#endif
+
+  EV_BEGIN_WATCHER (prepare, prepare)
+    void set () throw () { }
+  EV_END_WATCHER (prepare, prepare)
+
+  EV_BEGIN_WATCHER (check, check)
+    void set () throw () { }
+  EV_END_WATCHER (check, check)
+
+  #if EV_EMBED_ENABLE
+  EV_BEGIN_WATCHER (embed, embed)
+    void set (struct ev_loop *embedded_loop) throw ()
+    {
+      int active = is_active ();
+      if (active) stop ();
+      ev_embed_set (static_cast<ev_embed *>(this), embedded_loop);
+      if (active) start ();
+    }
+
+    void start (struct ev_loop *embedded_loop) throw ()
+    {
+      set (embedded_loop);
+      start ();
+    }
+
+    void sweep ()
+    {
+      ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
+    }
+  EV_END_WATCHER (embed, embed)
+  #endif
+
+  #if EV_FORK_ENABLE
+  EV_BEGIN_WATCHER (fork, fork)
+    void set () throw () { }
+  EV_END_WATCHER (fork, fork)
+  #endif
+
+  #if EV_ASYNC_ENABLE
+  EV_BEGIN_WATCHER (async, async)
+    void set () throw () { }
+
+    void send () throw ()
+    {
+      ev_async_send (EV_A_ static_cast<ev_async *>(this));
+    }
+
+    bool async_pending () throw ()
+    {
+      return ev_async_pending (static_cast<ev_async *>(this));
+    }
+  EV_END_WATCHER (async, async)
+  #endif
+
+  #undef EV_PX
+  #undef EV_PX_
+  #undef EV_CONSTRUCT
+  #undef EV_BEGIN_WATCHER
+  #undef EV_END_WATCHER
+}
+
+#endif
+