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