event_reinit() removes the event, but only evsig_add puts it back. So any
signals set up before event_reinit will be ignored until another signal is
added.
Fixes: #307
Before this patch event_reinit() only closes the signal socketpair fds and
recreates them if signals have been added, but this is wrong, since socketpair
fds created on backend init, and if we will not re-create them bad things in
child/parent signal handling will happens (and indeed this is what happens for
non-reinit backends like select).
Fixes: #307
For finalizers we can register yet another finalizer out from finalizer, and
iff finalizer will be in active_later_queue we can add finalizer to
activequeues, and we will have events in activequeues after event_base_free()
returns, which is not what we want (we even have an assertion for this).
A simple case is bufferevent with underlying (i.e. filters) in inactive queue.
Fixes: regress bufferevent/bufferevent_socket_filter_inactive
The following command failed before:
$ ./configure --disable-debug-mode
Fixes: dcfb19a27b7760299bc9e7291c9abd88c59fd91a ("Debug mode option to error on
evthread init AFTER other event calls.")
- A handy event_enable_debug_mode() feature which will error and abort the
application if any thread-aware libevent functions are called BEFORE the
evthread API has been initialized (manually, or through
evthread_use_windows_threads() / evthread_use_pthreads()
- This is done by setting the global debug variable
'event_debug_created_threadable_ctx_' whenever the following functions
are called:
evthreadimpl_lock_alloc_()
evthreadimpl_cond_alloc_()
event_base_new_with_config() <- this checks to see if the thread
callbacks are enabled first, so we
have to manually set the variable.
- Example:
int main(int argc, char ** argv) {
struct event_base * base;
event_enable_debug_mode();
base = event_base_new();
evthread_use_pthreads();
return 0;
}
When executed, the program will throw an error and exit:
[err] evthread initialization must be called BEFORE anything else!
This will avoid leaking of event_debug_map_HT_GROW
I buildin it into libevent_glboal_shutdown() because
event_disable_debug_mode() -> event_free_debug_globals() ->
event_free_debug_globals_locks() will clean event_debug_map_lock_ that
used in event_disable_debug_mode().
There is a race between manual event_active and natural event activation. If both happen at the same time on the same FD, they would both be protected by the same event base lock except for 1 LoC where the fields of struct event are read without any kind of lock. This commit does those reads into local variables inside the lock and then invokes the callback with those local arguments outside the lock. In 2.0-stable, none of this is inside the lock; in HEAD, only the callback is read inside the lock. This gets the callback and all 3 arguments inside the lock before calling it outside the lock.
After running the callback, we were checking evcb->evcb_closure to
decide whether to call mm_free(ev). But the callback itself might
have freed ev, so we need to grab that field first
Found with AddressSanitizer
This commit provides an interface for accessing and resetting the maximum
number of events in a given period. This information provides better insight
into event queue pressure.
In event_process_active_single_queue, EVLIST_INIT must be set on any
event that uses one of the event-only closures, and so "ev" will be
set in those cases. But coverity's worried here (CIDs numerous). So
instead, just add the assertions that should make it happy.
There was actually a bug in the original version of this: it tried to
run the finalizers after (potentially) setting current_base to NULL;
but those finalizers could themselves (potentially) be invoking stuff
that needed to know about the current event_base. So the right time to
do it is _before_ clearing current_base.
When resuming the system from a suspended state, the ev_timeout field
of a scheduled timer event may be in the past. This leads to
unexpected behavior when scheduling a short-duration timer event
immediately after returning from suspension, because the new event
does not land on top of the timeout minheap and so the event loop
(blocked on a possibly long-duration timeout) is not notified.
This patch checks for this condition and, if it obtains, notifies the
event loop.