aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDave Wallace <dwallacelf@gmail.com>2018-03-13 19:42:02 -0400
committerDave Wallace <dwallacelf@gmail.com>2018-03-13 19:42:02 -0400
commit49c13c71939fafa2d7d113a6a6d2062df5825a89 (patch)
treeb413fa8bb6ce7ab992bb465945a31776c75f4649 /src
parent3e9b4656a264066f572dc73f091b3583153b05e2 (diff)
VCL: Fix race condition in event thread function
Change-Id: I8586faee0b3a40932cd711b60cebe1a23ff82a56 Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/vcl/vcl_event.c28
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;