2424// check if the event is allocaded by user - event address is outside queues internal buffer address range
2525#define EQUEUE_IS_USER_ALLOCATED_EVENT (e ) ((q->buffer == NULL) || ((uintptr_t)(e) < (uintptr_t)q->buffer) || ((uintptr_t)(e) > ((uintptr_t)q->slab.data)))
2626
27+ // for user allocated events use event id to track event state
28+ enum {
29+ EQUEUE_USER_ALLOCATED_EVENT_STATE_INPROGRESS = 1 ,
30+ EQUEUE_USER_ALLOCATED_EVENT_STATE_DONE = 0 // event canceled or dispatching done
31+ };
32+
2733// calculate the relative-difference between absolute times while
2834// correctly handling overflow conditions
2935static inline int equeue_tickdiff (unsigned a , unsigned b )
@@ -229,7 +235,9 @@ void equeue_dealloc(equeue_t *q, void *p)
229235 e -> dtor (e + 1 );
230236 }
231237
232- if (!EQUEUE_IS_USER_ALLOCATED_EVENT (e )) {
238+ if (EQUEUE_IS_USER_ALLOCATED_EVENT (e )) {
239+ e -> id = EQUEUE_USER_ALLOCATED_EVENT_STATE_DONE ;
240+ } else {
233241 equeue_mem_dealloc (q , e );
234242 }
235243}
@@ -402,6 +410,7 @@ void equeue_post_user_allocated(equeue_t *q, void (*cb)(void *), void *p)
402410 unsigned tick = equeue_tick ();
403411 e -> cb = cb ;
404412 e -> target = tick + e -> target ;
413+ e -> id = EQUEUE_USER_ALLOCATED_EVENT_STATE_INPROGRESS ;
405414
406415 equeue_enqueue (q , e , tick );
407416 equeue_sema_signal (& q -> eventsema );
@@ -424,7 +433,7 @@ bool equeue_cancel(equeue_t *q, int id)
424433
425434bool equeue_cancel_user_allocated (equeue_t * q , void * e )
426435{
427- if (!e ) {
436+ if (!e || (( struct equeue_event * ) e ) -> id == EQUEUE_USER_ALLOCATED_EVENT_STATE_DONE ) {
428437 return false;
429438 }
430439
0 commit comments