--- libev/ev.pod 2008/04/06 14:34:52 1.143 +++ libev/ev.pod 2008/04/07 12:33:29 1.144 @@ -258,13 +258,6 @@ types of such loops, the I loop, which supports signals and child events, and dynamically created loops which do not. -If you use threads, a common model is to run the default event loop -in your main thread (or in a separate thread) and for each thread you -create, you also create another event loop. Libev itself does no locking -whatsoever, so if you mix calls to the same event loop in different -threads, make sure you lock (this is usually a bad idea, though, even if -done correctly, because it's hideous and inefficient). - =over 4 =item struct ev_loop *ev_default_loop (unsigned int flags) @@ -3069,6 +3062,63 @@ #include "ev.c" +=head1 THREADS AND COROUTINES + +=head2 THREADS + +Libev itself is completely threadsafe, but it uses no locking. This +means that you can use as many loops as you want in parallel, as long as +only one thread ever calls into one libev function with the same loop +parameter. + +Or put differently: calls with different loop parameters can be done in +parallel from multiple threads, calls with the same loop parameter must be +done serially (but can be done from different threads, as long as only one +thread ever is inside a call at any point in time, e.g. by using a mutex +per loop). + +If you want to know which design is best for your problem, then I cannot +help you but by giving some generic advice: + +=over 4 + +=item * most applications have a main thread: use the default libev loop +in that thread, or create a seperate thread running only the default loop. + +This helps integrating other libraries or software modules that use libev +themselves and don't care/know about threading. + +=item * one loop per thread is usually a good model. + +Doing this is almost never wrong, sometimes a better-performance model +exists, but it is always a good start. + +=item * other models exist, such as the leader/follower pattern, where one +loop is handed through multiple threads in a kind of round-robbin fashion. + +Chosing a model is hard - look around, learn, know that usually you cna do +better than you currently do :-) + +=item * often you need to talk to some other thread which blocks in the +event loop - C watchers can be used to wake them up from other +threads safely (or from signal contexts...). + +=back + +=head2 COROUTINES + +Libev is much more accomodating to coroutines ("cooperative threads"): +libev fully supports nesting calls to it's functions from different +coroutines (e.g. you can call C on the same loop from two +different coroutines and switch freely between both coroutines running the +loop, as long as you don't confuse yourself). The only exception is that +you must not do this from C reschedule callbacks. + +Care has been invested into making sure that libev does not keep local +state inside C, and other calls do not usually allow coroutine +switches. + + =head1 COMPLEXITIES In this section the complexities of (many of) the algorithms used inside