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

Re: [Libevent-users] Multithreading and breaking out of the event loop



În mar., 12 feb. 2019 la 15:10, <azat@xxxxxxxxxxxx> a scris:
>
> On Tue, Feb 12, 2019 at 02:44:35PM +0200, George-Theodor Serbana wrote:
> > For ease, I will copy and paste the StackOverflow question here as well:
>
> Thanks!

Actually I thank you for being so responsive ;)

>
> > I have one thread (Thread A) in a C static library that's creating the
> > libevent event_base after doing this:
> >
> > #ifdef WIN32
> >     evthread_use_windows_threads();
> > #else
> >     evthread_use_pthreads();
> > #endif
> >
> > This C static library is all single threaded and it's doing all the
> > libevent work itself: adding events, dispatching, main loop, etc, all
> > these being done from Thread A.
> >
> > Now I have a C++ program that I link with the library above, calling
> > the entrance function into the C library from a boost::thread called
> > Thread B.
>
> You should not call evthread_use_*() functions multiple times (although
> this will not break anything).

evthread_use_* functions are only called once (from the C++ program
via the C library), just before creating the event_base as mentioned.

>
> > At some point into my C++ program, I have yet another boost::thread
> > called Thread C which will attempt to event_add using the C library
> > into Thread A's event loop and then immediately call event_active.
> >
> > What I'd like to see after doing stuff from Thread C is this:
> >
> > calling event_add from Thread C
> > calling event_active from Thread C
> > Processing events from Thread A
> > calling the event's handler from Thread A
> >
> > Possibly we could have Processing events from Thread A anywhere else
> > between those lines, but for sure we must have at least 1 such line
> > between event_active and event handler execution, right?
>
> It depends on what "Processing events from Thread A" means, if this is
> entering the loop and handling events from it (insice Thread A), the the
> answer is "definitelly yes".

Yes, that is exactly what I meant.

>
> > What I see instead is this:
> >
> > calling event_add from Thread X
> > calling event_active from Thread X
> > calling the event's handler from Thread A
> >
> > Thread X is a different ID than Thread C but I guess that's just
> > because of using boost threads in the C++ calling site and pthreads in
> > the C library or something, anyways it doesn't bother me.
> >
> > I also like the fact that my main purpose here is OK: firing the event
> > from a thread and handling it from another.
> >
> > But for my own curiosity what I don't understand is why I don't see a
> > line "processing events from Thread A" before the handler callback is
> > called?
>
> Where did you put this printf?

"Processing events from Thread A" looks like this:

do {
  printf("Processing events from Thread A");
  loop_result = run_main_loop_once();
} while (loop_result == 1);

Taking a second look now, I just figured out the reason why I wouldn't
see the printf between event_active and event handler execution.

This code is from the Tor project:
https://github.com/torproject/tor/blob/7f59b9fb1fdc4519e663fa82e416eccae88e8934/src/core/mainloop/mainloop.c#L2987

And the issue is that in function run_main_loop_once(), after calling
event_base_loop(), right before exiting run_main_loop_once(), we have
these lines:

if (main_loop_should_exit)
  return 0;

which makes the do...while loop exit as well and that's why I wouldn't
see the print. But now I realize that the program is actually correct,
threads execution being very well defined: thread B inserts event into
thread's A processing queue which eventually makes thread A exit the
main event loop, without any synchronization issues.

Anyways sorry for the mess up, it was my mistake for not checking the
do...while loop correctly, libevent is working perfectly fine :)

>
> P.S. consider using event_enable_debug_logging() to see debug
> information (that includes when libevent enters the loop and when it
> process event).

Thanks for this heads-up as well, will use it in the future if I have
other issues with libevent.

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