diff options
Diffstat (limited to 'src/vcl')
-rw-r--r-- | src/vcl/vcl_event.c | 28 |
1 files 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; |