summaryrefslogtreecommitdiffstats
path: root/src/vcl/vcl_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vcl/vcl_event.c')
-rw-r--r--src/vcl/vcl_event.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/src/vcl/vcl_event.c b/src/vcl/vcl_event.c
index b706a93e56a..65d28707607 100644
--- a/src/vcl/vcl_event.c
+++ b/src/vcl/vcl_event.c
@@ -69,14 +69,14 @@ vce_clear_event (vce_event_thread_t *evt, vce_event_t *ev)
vce_event_t *
vce_get_event_from_index(vce_event_thread_t *evt, u32 ev_idx)
{
- vce_event_t *ev;
+ vce_event_t *ev = 0;
clib_spinlock_lock (&(evt->events_lockp));
- ev = pool_elt_at_index (evt->vce_events, ev_idx);
+ if ( ! pool_is_free_index (evt->vce_events, ev_idx))
+ ev = pool_elt_at_index (evt->vce_events, ev_idx);
clib_spinlock_unlock (&(evt->events_lockp));
return ev;
-
}
vce_event_handler_reg_t *
@@ -87,16 +87,13 @@ vce_register_handler (vce_event_thread_t *evt, vce_event_key_t *evk,
vce_event_handler_reg_t *old_handler = 0;
uword *p;
u32 handler_index;
- u64 adj_key;
/* TODO - multiple handler support. For now we can replace
* and re-instate, which is useful for event recycling */
- adj_key = evk->as_u64 | (1LL << 63); //evk can be 0, which won't hash
-
clib_spinlock_lock (&evt->handlers_lockp);
- p = hash_get (evt->handlers_index_by_event_key, adj_key);
+ p = hash_get (evt->handlers_index_by_event_key, evk->as_u64);
if (p)
{
old_handler = pool_elt_at_index (evt->vce_event_handlers, p[0]);
@@ -121,8 +118,10 @@ vce_register_handler (vce_event_thread_t *evt, vce_event_key_t *evk,
handler->handler_fn = cb;
handler->replaced_handler_idx = (p) ? p[0] : ~0;
+ handler->ev_idx = ~0; //This will be set by the event thread if event happens
+ handler->evk = evk->as_u64;
- hash_set (evt->handlers_index_by_event_key, adj_key, handler_index);
+ hash_set (evt->handlers_index_by_event_key, evk->as_u64, handler_index);
pthread_cond_init (&(handler->handler_cond), NULL);
pthread_mutex_init (&(handler->handler_lock), NULL);
@@ -139,20 +138,19 @@ vce_register_handler (vce_event_thread_t *evt, vce_event_key_t *evk,
}
int
-vce_unregister_handler (vce_event_thread_t *evt, vce_event_t *ev)
+vce_unregister_handler (vce_event_thread_t *evt,
+ vce_event_handler_reg_t *handler)
{
- vce_event_handler_reg_t *handler;
uword *p;
- u64 adj_key = ev->evk.as_u64 | (1LL << 63);
+ u64 evk = handler->evk;
u8 generate_signal = 0;
clib_spinlock_lock (&evt->handlers_lockp);
- p = hash_get (evt->handlers_index_by_event_key, adj_key);
+ p = hash_get (evt->handlers_index_by_event_key, evk);
if (!p)
{
clib_spinlock_unlock (&evt->handlers_lockp);
-
return VNET_API_ERROR_NO_SUCH_ENTRY;
}
@@ -161,13 +159,13 @@ vce_unregister_handler (vce_event_thread_t *evt, vce_event_t *ev)
/* If this handler replaced another handler, re-instate it */
if (handler->replaced_handler_idx != ~0)
{
- hash_set (evt->handlers_index_by_event_key, adj_key,
+ hash_set (evt->handlers_index_by_event_key, evk,
handler->replaced_handler_idx);
generate_signal = 1;
}
else
{
- hash_unset (evt->handlers_index_by_event_key, adj_key);
+ hash_unset (evt->handlers_index_by_event_key, evk);
}
pthread_mutex_destroy (&(handler->handler_lock));
@@ -196,7 +194,6 @@ vce_event_thread_fn (void *arg)
u32 ev_idx;
vce_event_handler_reg_t *handler;
uword *p;
- u64 adj_key;
evt->recycle_event = 1; // Used for recycling events with no handlers
@@ -221,11 +218,10 @@ vce_event_thread_fn (void *arg)
clib_spinlock_unlock (&(evt->events_lockp));
ASSERT(ev);
- adj_key = ev->evk.as_u64 | (1LL << 63);
clib_spinlock_lock (&evt->handlers_lockp);
- p = hash_get (evt->handlers_index_by_event_key, adj_key);
+ p = hash_get (evt->handlers_index_by_event_key, ev->evk.as_u64);
if (!p)
{
/* If an event falls in the woods, and there is no handler to hear it,