On Fri, Apr 22, 2011 at 11:43 AM, Nick Mathewson <ni...@freehaven.net>wrote:

> On Thu, Apr 21, 2011 at 6:29 PM, Scott Dorr <j.scott.d...@gmail.com>
> wrote:
> > I've got a server with multiple threads, each with their own event base.
> >  Works wonderfully.  I have a new situation that would be solved quite
> > easily if I could have all threads (but one) push events onto the event
> base
> > for the final thread.  That final thread will process events as they come
> > up.
> > Reading through some of the additional libevent documentation, I'm
> wondering
> > if I'm going to need to engage the various locking bits
> > (evthread_set_id_callback, evthread_set_lock_callbacks, etc) to preserve
> the
> > sanctity of that one event base?
>
> Probably.  If you want to do anything that affects an event_base from
> multiple threads (and this includes touching events that are
> associated with an event_base), you need to enable locking before you
> do anything else with libevent, or construct any event_bases.
>
> Most people don't want to call the "evthread_set_*_callback()"
> functions on their own: evthread_use_windows_threads() and
> evthread_use_pthreads() are what you'll probably want, unless you need
> to interface with an existing locking library that isn't one of those.
>

Yeah, after posting my question, I continued to do a bit of digging and came
to the conclusion that probably all I'd need was evthread_use_pthreads() --
the other, more manual, evthread*callback() functions were in place in case
you didn't use one of the already supported thread libraries (eg. pthreads).


>
> > So far, I've been able to avoid any kind of locking in this server and
> would
> > be quite reluctant to add any at this point.
>
> Well, if you want to communicate between threads without any locking,
> you can't use changes to Libevent data structures to do it: Libevent's
> data structures are only safe to access from multiple concurrent
> threads if locking is enabled.
>
> You might be able to achieve what you want by some other means, like
> using pipe() or socketpair() to create a communications channel
> between threads.  Have the thread that receives all the information
> listen for EV_READ on the pipe/socketpair, and have other threads use
> write to send it information.  You'd either need to give each sending
> thread its own pipe to write on, or you'd need to figure out a way to
> prevent messages from getting mixed up -- maybe by using one-byte
> messages, or datagram-based socketpairs, or some such.
>

For now, I'll stick with the locking. :(  It's really only to handle an
edge-condition that will rarely ever happen, so the chance of serializing
behind a lock is greatly mitigated.  I'll probably convert to some kind of
pipe()/socketpair() solution when I've got more time to work on efficiency
updates for edge cases. ;)

Thanks for the response!

- scott

Reply via email to