[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] event_add from a different thread while event loop is running



On Mon, May 2, 2011 at 7:18 PM, D.P. <pizdes@xxxxxxxxx> wrote:
> Hi, I have a question regarding adding an event from a different thread
> (different from the one event_base_dispatch was called).
> Initially I create an event_base, add a listener socket to it, and do
> event_base_dispatch. When a listener socket gets an incoming connection, it
> will add the new client socket (from inside the callback) to event_base.
> Everything works as expected up to this point (i.e. client socket callback
> is invoked whenever there is data
> to read, and listener socket is invoked whenever there is another client
> trying to connect.) Now I add another socket using event_add, but from a
> different
> thread. Now let's say some data arrives at this socket that I have just
> added. It seems that a callback for this socket will only get invoked
> *after* there
> is some activity on the other two sockets (listener or client from before).
> So if there is no activity at all on the two sockets that were added before,
> the callback
> for this new socket will never get called. I tested the same code on OS X
> with kqueue and poll backends, and on Linux with epoll and poll. This does
> not happen
> with epoll (the new socket callback will be fired even if there is no
> activity on the other two), but does happen with kqueue and poll. Is there
> anything I can do
> to "force" an immediate refresh (while the event loop is running) of the set
> of watched sockets for systems that use kqueue or poll?

This sounds a lot like what would happen if you didn't enable
threading support.  Check out the "Locks and Threading" part of
http://www.wangafu.net/~nickm/libevent-book/Ref1_libsetup.html .

Basically, before you create any event_base that you're going to
access from more than one thread, you need to tell Libevent about your
threading library.  On Windows, just call
    int evthread_use_windows_threads(void);
On Linux or OS X or any place with pthreads, call
    int evthread_use_pthreads(void);
If you're using some weird threading library, you'll need to teach
Libevent how to use it.

Setting up threading performs two functions: it tells Libevent how to
do locking in order to protect data structures that are accessed from
multiple threads, and it also tells Libevent how to alert an
event_base whose dispatch function is running in one thread that it
needs to wake up and change the set of events that it's listening to.

These functions are new in Libevent 2.0; in earlier versions there was
no realistic safe way to use an event_base from multiple threads
simultaneously.

I'm starting to think that we need a FAQ.  ;)

-- 
Nick
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.