Does libevent process two events concurrently which means I need mutex?

358 Views Asked by At

I am experimenting with the libevent library. I defined a few events and I do not create any threads in my code.

My question is, if a few events can access/modify the same shared struct, do I need a mutex to lock the critical section to avoid race condition? Or is libevent designed in a way that events can only be executed consecutively, never concurrently?

Notes:

  1. But of course the question is only about the case in which my events do not spawn new threads themselves
  2. My concern is mainly from my experience with JavaScript: JavaScript uses event loop design as well but we can still corrupt data even if there is only one thread. The reason is that JavaScript can, as I understand, "pause" the execution of one event and start a second event, then resume the paused event. If the pause happens right between lines that modify a shared object, it can corrupt my object.
  3. RTFM already but does not find the definite answer I am looking for
2

There are 2 best solutions below

4
takaki On

Libevent is designed to be single-threaded by default. It provides a mechanism for asynchronous event notification, which means it handles the events in a non-blocking, event-driven way. If you have multiple events that can potentially modify the same data structure and you are not creating any threads yourself, you generally don't need to use a mutex to avoid race conditions because these events will not be executed concurrently, but rather one after another.

However, it's important to be aware that libevent does support multi-threaded mode, where multiple threads can be created and events handled concurrently. If you were to use this mode, you would indeed need to ensure proper synchronization (like using mutexes) when accessing shared data to avoid race conditions.

To further clarify, in a single-threaded event-driven model like the default mode in libevent, there is a single event loop that processes events one at a time in the order they are triggered. While an event handler is running, no other event can be processed. This effectively prevents race conditions without the need for additional synchronization.

Remember that this holds true as long as your events don't spawn new threads themselves and you're using libevent in its default, single-threaded mode. If your application or the library is configured to use multiple threads, then you would need to ensure proper synchronization.

3
John Bollinger On

My concern is mainly from my experience with JavaScript: JavaScript uses event loop design as well but we can still corrupt data even if there is only one thread. The reason is that JavaScript can, as I understand, "pause" the execution of one event and start a second event, then resume the paused event.

What you describe is atypical of event loops. They usually rely on a queue of events, processed one after another.

And what you describe is not really supportable in C's model of operation. The only way C defines for a thread's work to be preempted to perform different work in the same thread is if the thread receives a signal that causes a signal handler function to run. But signal handlers are not suitable for performing arbitrary processing, so although it's conceivable that libevent might use a signal handler to enqueue events, it is not plausible that it would call associated callbacks within the signal handler.

Rest at ease, then. Provided that you have only one thread, your event callbacks will not be preempted to run other event callbacks, and no two callbacks can run concurrently.