Browse Source

Add `sync.One_Shot_Event`

gingerBill 1 year ago
parent
commit
f989f4df3e
1 changed files with 24 additions and 0 deletions
  1. 24 0
      core/sync/extended.odin

+ 24 - 0
core/sync/extended.odin

@@ -417,4 +417,28 @@ unpark :: proc "contextless" (p: ^Parker)  {
 	if atomic_exchange_explicit(&p.state, NOTIFIED, .Release) == PARKED {
 	if atomic_exchange_explicit(&p.state, NOTIFIED, .Release) == PARKED {
 		futex_signal(&p.state)
 		futex_signal(&p.state)
 	}
 	}
+}
+
+
+
+// A One_Shot_Event is an associated token which is initially not present:
+//     * The `one_shot_event_wait` blocks the current thread until the event
+//       is made available
+//     * The `one_shot_event_signal` procedure automatically makes the token
+//       available if its was not already.
+One_Shot_Event :: struct #no_copy {
+	state: Futex,
+}
+
+// Blocks the current thread until the event is made available with `one_shot_event_signal`.
+one_shot_event_wait :: proc "contextless" (e: ^One_Shot_Event) {
+	for atomic_load_explicit(&e.state, .Acquire) == 0 {
+		futex_wait(&e.state, 1)
+	}
+}
+
+// Releases any threads that are currently blocked by this event with `one_shot_event_wait`.
+one_shot_event_signal :: proc "contextless" (e: ^One_Shot_Event) {
+	atomic_store_explicit(&e.state, 1, .Release)
+	futex_broadcast(&e.state)
 }
 }