Scheme 48 Manual | Contents | In Chapter: Threads
Previous: Writing custom synchronization abstractions | Next: Writing custom synchronization abstractions

Writing custom synchronization abstractions

The bindings explained in this section are part of the threads-internal structure. They are concerned with suspending threads and making them runnable again upon some later event.

Typically, a suspended thread needs to be recorded in a queue somewhere for later waking-up. To allow a thread to be recorded in multiple queues (say, when it waits for one of a number of events), such thread queues are ordinary queues containing cells that, in turn, contain the thread objects themselves. Each thread has at most one such cell associated with it which is shared among all queues (or other data structures) holding on to the suspended thread. The cell is cleared when the thread is woken up.

Thread-queue-empty? atomically checks whether the thread-queue thread queue is empty, i.e., if it does not contain non-empty cells. Maybe-dequeue-thread! provisionally dequeues a thread from thread-queue if it contains one. It returns the dequeued thread or #f if the queue is empty. Maybe-commit-and-block attempts to commit the current proposal. If this succeeds, the current thread is blocked, the thread's cell is set to cell, and #t is returned. Otherwise, #f is returned. Maybe-commit-and-block-on-queue is like maybe-commit-and-block, excepts that it creates a fresh cell for the thread and enqueues it in thread-queue if the commit succeeds.

Maybe-commit-and-make-ready accepts either a thread object or a thread queue as an argument. In either case, maybe-commit-and-make-ready tries to commit the current proposal. If that succeeds, it maybe-commit-and-make-ready makes its argument runnable: if thread-or-queue is a thread, that thread is made runnable, if it is a thread queue, all threads on the queue are made runnable. (In the latter case, none of the threads actually runs until all have been made runnable.) Marybe-commit-and-make-ready returns #t if it succeeded, and #f otherwise.

Previous: Writing custom synchronization abstractions | Next: Writing custom synchronization abstractions