]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Event: fixed race condition between ev_send and ev_postpone
authorMaria Matejka <mq@ucw.cz>
Tue, 27 Feb 2024 13:25:04 +0000 (14:25 +0100)
committerMaria Matejka <mq@ucw.cz>
Sat, 6 Apr 2024 16:28:43 +0000 (18:28 +0200)
lib/event.c

index 68888a4cdef57a7445d2793f425c72099afc19dd..1eb1ad0a02ce12c4808833b9951cf621b6e3fa52 100644 (file)
@@ -160,7 +160,11 @@ ev_postpone(event *e)
   ASSERT_DIE(birdloop_inside(sl->loop));
 
   /* Remove from one of these lists. */
-  ASSERT(ev_remove_from(e, &sl->_executor) || ev_remove_from(e, &sl->receiver));
+  while (
+      !ev_remove_from(e, &sl->_executor) &&
+      !ev_remove_from(e, &sl->receiver))
+    /* We may need to wait until the sender actually puts the event inside */
+    birdloop_yield();
 
   /* Mark as inactive */
   ASSERT_DIE(sl == atomic_exchange_explicit(&e->list, NULL, memory_order_acq_rel));
@@ -242,7 +246,7 @@ ev_send(event_list *l, event *e)
     else
       bug("Queuing an already queued event to another queue is not supported.");
 
-  /* Here should be no concurrent senders */
+  /* Here should be no concurrent senders of this event */
   event *next = atomic_load_explicit(&l->receiver, memory_order_acquire);
   edlog(l, e, next, 2, EDL_SEND);
   event *old_next = NULL;