mirror of
https://github.com/cuberite/libevent.git
synced 2025-08-04 01:36:23 -04:00
Return from event_del() after the last event callback termination
Delete the event from the queue before blocking for the current event callback termination. Ensures that no callback is being executed when event_del() returns, hence making this function a secure mechanism to access data which is handled in the event callack. Fixes: #236 Fixes: #225 Refs: 6b4b77a Fixes: del_wait (cherry picked from commit 0b4b0efdb8ee710ccae5bad320fc24843fd428e5)
This commit is contained in:
parent
23db747652
commit
876c7ac7ff
29
event.c
29
event.c
@ -2780,21 +2780,7 @@ event_del_nolock_(struct event *ev, int blocking)
|
||||
}
|
||||
}
|
||||
|
||||
/* If the main thread is currently executing this event's callback,
|
||||
* and we are not the main thread, then we want to wait until the
|
||||
* callback is done before we start removing the event. That way,
|
||||
* when this function returns, it will be safe to free the
|
||||
* user-supplied argument. */
|
||||
base = ev->ev_base;
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
if (blocking != EVENT_DEL_NOBLOCK &&
|
||||
base->current_event == event_to_event_callback(ev) &&
|
||||
!EVBASE_IN_THREAD(base) &&
|
||||
(blocking == EVENT_DEL_BLOCK || !(ev->ev_events & EV_FINALIZE))) {
|
||||
++base->current_event_waiters;
|
||||
EVTHREAD_COND_WAIT(base->current_event_cond, base->th_base_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
EVUTIL_ASSERT(!(ev->ev_flags & ~EVLIST_ALL));
|
||||
|
||||
@ -2841,6 +2827,21 @@ event_del_nolock_(struct event *ev, int blocking)
|
||||
|
||||
event_debug_note_del_(ev);
|
||||
|
||||
/* If the main thread is currently executing this event's callback,
|
||||
* and we are not the main thread, then we want to wait until the
|
||||
* callback is done before returning. That way, when this function
|
||||
* returns, it will be safe to free the user-supplied argument.
|
||||
*/
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
if (blocking != EVENT_DEL_NOBLOCK &&
|
||||
base->current_event == event_to_event_callback(ev) &&
|
||||
!EVBASE_IN_THREAD(base) &&
|
||||
(blocking == EVENT_DEL_BLOCK || !(ev->ev_events & EV_FINALIZE))) {
|
||||
++base->current_event_waiters;
|
||||
EVTHREAD_COND_WAIT(base->current_event_cond, base->th_base_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user