From 49c13c71939fafa2d7d113a6a6d2062df5825a89 Mon Sep 17 00:00:00 2001 From: Dave Wallace Date: Tue, 13 Mar 2018 19:42:02 -0400 Subject: VCL: Fix race condition in event thread function Change-Id: I8586faee0b3a40932cd711b60cebe1a23ff82a56 Signed-off-by: Dave Wallace --- src/vcl/vcl_event.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/vcl/vcl_event.c b/src/vcl/vcl_event.c index f6e20de2769..d8bd8c74e36 100644 --- a/src/vcl/vcl_event.c +++ b/src/vcl/vcl_event.c @@ -211,16 +211,19 @@ vce_event_thread_fn (void *arg) vce_event_handler_reg_t *handler; uword *p; + pthread_mutex_lock (&(evt->generator_lock)); + clib_spinlock_lock (&(evt->events_lockp)); evt->recycle_event = 1; // Used for recycling events with no handlers - + clib_spinlock_unlock (&(evt->events_lockp)); do { - pthread_mutex_lock (&(evt->generator_lock)); while ( (clib_fifo_elts (evt->event_index_fifo) == 0) || evt->recycle_event) { + clib_spinlock_lock (&(evt->events_lockp)); evt->recycle_event = 0; + clib_spinlock_unlock (&(evt->events_lockp)); pthread_cond_wait (&(evt->generator_cond), &(evt->generator_lock)); } @@ -231,8 +234,6 @@ vce_event_thread_fn (void *arg) clib_fifo_sub1 (evt->event_index_fifo, ev_idx); ev = pool_elt_at_index (evt->vce_events, ev_idx); - clib_spinlock_unlock (&(evt->events_lockp)); - ASSERT(ev); clib_spinlock_lock (&evt->handlers_lockp); @@ -245,18 +246,23 @@ vce_event_thread_fn (void *arg) * I don't know either, so lets try recycling the event */ clib_fifo_add1 (evt->event_index_fifo, ev_idx); evt->recycle_event = 1; + clib_spinlock_unlock (&(evt->events_lockp)); clib_spinlock_unlock (&evt->handlers_lockp); - goto unlock; + pthread_mutex_unlock (&(evt->generator_lock)); } - handler = pool_elt_at_index (evt->vce_event_handlers, p[0]); - handler->ev_idx = ev_idx; + else + { + handler = pool_elt_at_index (evt->vce_event_handlers, p[0]); + handler->ev_idx = ev_idx; - clib_spinlock_unlock (&evt->handlers_lockp); + clib_spinlock_unlock (&(evt->events_lockp)); + clib_spinlock_unlock (&evt->handlers_lockp); + pthread_mutex_unlock (&(evt->generator_lock)); - (handler->handler_fn)(handler); + (handler->handler_fn)(handler); + } - unlock: - pthread_mutex_unlock (&(evt->generator_lock)); + pthread_mutex_lock (&(evt->generator_lock)); } while (1); return NULL; -- cgit 1.2.3-korg