Skip to content

Instantly share code, notes, and snippets.

@samdphillips
Last active July 27, 2022 23:00
Show Gist options
  • Save samdphillips/23eb5c17a033e6c12b4249d00be7df1d to your computer and use it in GitHub Desktop.
Save samdphillips/23eb5c17a033e6c12b4249d00be7df1d to your computer and use it in GitHub Desktop.
One-shot type condition variable
#lang racket/base
(require racket/async-channel
racket/function)
(struct waiter (thd req-ch notify-ch))
(define (make-waiter)
(define req-ch (make-channel))
(define notify-ch (make-channel))
(define (run clients)
(sync (handle-evt req-ch
(lambda (ch) (run (cons ch clients))))
(handle-evt notify-ch
(lambda (ignore)
(for ([c clients]) (async-channel-put c #t))))))
(define thd
(thread (lambda () (run null))))
(waiter thd req-ch notify-ch))
(define (wait a-waiter)
(define ch (make-async-channel))
(channel-put (waiter-req-ch a-waiter) ch)
(void (async-channel-get ch)))
(define (notify-all a-waiter)
(channel-put (waiter-notify-ch a-waiter) #t)
(thread-wait (waiter-thd a-waiter)))
(define w (make-waiter))
(define t1 (thread (thunk (wait w)
(displayln "first"))))
(define t2 (thread (thunk (wait w)
(displayln "second"))))
(sleep 1)
(notify-all w)
(thread-wait t1)
(thread-wait t2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment