struct ring_storage *storage; // the mapped part
struct mt_list waiters; // list of waiters, for now, CLI "show event"
int readers_count;
- uint flags; // RING_FL_*
+ uint flags; // RING_FL_*
+ uint pending; // new writes that have not yet been subject to a wakeup
+ uint waking; // indicates a thread is currently waking up readers
};
#endif /* _HAPROXY_RING_T_H */
ring->readers_count = 0;
ring->flags = 0;
ring->storage = area;
+ ring->pending = 0;
+ ring->waking = 0;
if (reset) {
ring->storage->size = size - sizeof(*ring->storage);
/* notify potential readers */
if (sent && HA_ATOMIC_LOAD(&ring->readers_count)) {
- struct mt_list *elt1, elt2;
- struct appctx *appctx;
-
- mt_list_for_each_entry_safe(appctx, &ring->waiters, wait_entry, elt1, elt2)
- appctx_wakeup(appctx);
+ HA_ATOMIC_INC(&ring->pending);
+ while (HA_ATOMIC_LOAD(&ring->pending) && HA_ATOMIC_XCHG(&ring->waking, 1) == 0) {
+ struct mt_list *elt1, elt2;
+ struct appctx *appctx;
+
+ HA_ATOMIC_STORE(&ring->pending, 0);
+ mt_list_for_each_entry_safe(appctx, &ring->waiters, wait_entry, elt1, elt2)
+ appctx_wakeup(appctx);
+ HA_ATOMIC_STORE(&ring->waking, 0);
+ }
}
leave: