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
+