[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [Libevent-users] WaitForMultipleObjects backend?
On Wed, Mar 13, 2013 at 9:01 PM, Patrick Pelletier
<ppelletier@xxxxxxxxxx> wrote:
> I was perusing whatsnew-2.0.txt and saw:
>
> Libevent 2.1 may add a multithreaded WaitForMultipleEvents-based
> backend for better performance with many inactive sockets and better
> integration with Windows events.
>
> Although that hasn't been added yet, I was wondering if anyone had thought
> about it, and had any suggestions on how hard writing such a backend would
> be, or how best to approach it.
>
> I have some existing code which uses WaitForMultipleObjects to wait on a
> combination of sockets and "manual reset events" created with CreateEvent().
> I'd like to port this code to libevent, but I'm not sure how to handle the
> manual reset events. It seems like the "correct" solution would be to write
> a new backend as suggested in whatsnew-2.0.txt, but I'm not sure how big of
> a project I'd be getting myself into if I set out to do that. Any other
> approach I can think of feels like a horrible hack, though. (Such as having
> a separate thread to do WaitForMultipleObjects on the manual reset events,
> and then write a byte to a socketpair that libevent is waiting on.)
>
> Any thoughts/suggestions?
Oh, this is going to be a *fun* one!
Here's a brain-dump. I'm not an expert on Windows APIs, so there may
be errors or omissions.
**
Any WaitForMultipleObjects-based solution is going to run into the
fact that WSAEventSelect doesn't really do a sensible thing on write
events. It considers a socket to have a write event trigger when the
socket that was not previously writeable becomes writeable. So it's
not meaningful to ask for write events on a socket until after you
have gotten a WSAEWOULDBLOCK when attempting to write on that socket.
It's a little tricky to simulate EV_WRITE as-is with this.
**
One idea that I had for solving that problem was to give the EV_WRITE
event flag an alternative API, such that the user is required to say
call a function (maybe event_clear_write_event()) on an EV_WRITE event
upon receiving EV_WRITE on a socket.
This alternative API would be optional; you'd turn it on while setting
up your event_config for your event_base.
To implement this, you'd need EV_WRITE events to be 'sticky' : to have
them *start* active, and stay acti eeven after triggering, and only
become inactive once a client calls event_clear_write_event. You
could do this in libevent 2.1 in terms of the new internal notion of
"active_later" events.
**
Another thing you could look at for starters is the branch that Chris
Davis tried to write to handle this code. I don't think it wound up
working completely, but it had some good ideas. I have it archived in
branch "hybrid-loop2" in my personal repository at
https://github.com/nmathewson/libevent/tree/hybrid-loop2
It probably has some good ideas!
**
Integration with IOCP could be a clever thing here. IOCP->Event and
Event->IOCP signals seem to go pretty fast on windows, whereas mucking
around with stuff like evutil_socketpair() is less so.
**
evutil_socketpair() fails on some hosts because of overzealous AV
software. Any solution that depends on it will sometimes have to fall
back to plain old select(). :(
**
You're going to run into the 64-event (or is it 63?) limitation of
WaitForMultipleEvents. Your options are:
* You can use WSAEventSelect to assign multiple sockets' events to a
single Event, and use WSAEnumNetworkEvents a lot on sockets that
aren't really ready. I am assured by one competent programmer that
this works better for him than it would sound.
* You can use RegisterWaitForSingleObject and friends to do a
threadpool-backed implementation
* You can roll your own threadpool.
* You can max out at 64 events. That's a nonstarter IMO.
**
The interface for libevent backends is straightforward but
underdocumented. I would be more than happy to answer any questions
you have. The shortest backend of general interest is poll.c; the
longest is epoll.c.
yrs,
--
Nick
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users in the body.