>
> Recently I've been investigating the mysterious termination of my event
> dispatch loop on a Windows system, with libevent 2.0.21. This has happened
> extremely rarely, and only in an EC2 virtualized environment. The system is
> not OOMing, so I suspect an error return from select in win32_dispatch
> (which is the only place that dispatch could return an error). Assume for
> the sake of discussion that I'm
>
Ok, I have tracked this down to a call to `bufferevent_free` on a
bufferevent that is outstanding in win32_dispatch's invocation of select.
This is happening at the behest of an application-level timeout. The
algorithm looks roughly like this:
bufev = bufferevent_socket_new(...);
bufferevent_setcb(..., connectionCb, ...);
bufferevent_socket_connect_hostname(...);
// Above repeated for several alternative connections
// ...
// Register application-level global timeout
timeout = evtimer_new(base, timeoutCb, ...);
evtimer_add(timeout, tv)
// ...
void timeoutCb(int, short, arg) {
bufferevent_free(bufev); // <-- this is the bufferevent for the
connection above (really several are processed)
}
If the timeout fires while we're still waiting for a response on the
connect for the underlying fd and we're using a select-based backend, the
close will cause select to return an error and the dispatch loop will bail
out. This is certainly the case for both select and win32select backends; I
have not checked whether closing the descriptor also causes the kqueue or
*poll interfaces to bail out.
Is what I am doing even reasonable? The documentation for bufferevent_free
implicitly suggests that it's ok to call while an operation is outstanding,
but it looks to me like doing so will break any select-based implementation.
Best,
--nate