On this page:
sync/ timeout
sync/ enable-break
sync/ timeout/ enable-break
prop: evt
10.2.1 Events

A synchronizable event (or just event for short) works with the sync procedure to coordinate synchronization among threads. Certain kinds of objects double as events, including ports and threads. Other kinds of objects exist only for their use as events.

At any point in time, an event is either ready for synchronization, or it is not; depending on the kind of event and how it is used by other threads, an event can switch from not ready to ready (or back), at any time. If a thread synchronizes on an event when it is ready, then the event produces a particular synchronization result.

Synchronizing an event may affect the state of the event. For example, when synchronizing a semaphore, then the semaphore’s internal count is decremented, just as with semaphore-wait. For most kinds of events, however (such as a port), synchronizing does not modify the event’s state.

The following act as events in Racket. An extension or embedding application can extend the set of primitive events — in particular, an eventspace in GRacket is an event — and new structure types can generate events (see prop:evt).

(evt? v)  boolean?
  v : any/c
Returns #t if v is a synchronizable event, #f otherwise.

(sync evt ...+)  any
  evt : evt?
Blocks as long as none of the synchronizable events evts are ready, as defined above.

When at least one evt is ready, its synchronization result (often evt itself) is returned. If multiple evts are ready, one of the evts is chosen pseudo-randomly for the result; the current-evt-pseudo-random-generator parameter sets the random-number generator that controls this choice.

(sync/timeout timeout evt ...+)  any
  timeout : (or/c #f (and/c real? (not/c negative?)) (-> any))
  evt : evt?
Like sync if timeout is #f. If timeout is a real number, then the result is #f if timeout seconds pass without a successful synchronization. If timeout is a procedure, then it is called in tail position if polling the evts discovers no ready events.

A zero value for timeout is equivalent to (lambda () #f). In either case, each evt is checked at least once before returning #f or calling timeout.

See also alarm-evt for an alternative timeout mechanism.

(sync/enable-break evt ...+)  any
  evt : evt?
Like sync, but breaking is enabled (see Breaks) while waiting on the evts. If breaking is disabled when sync/enable-break is called, then either all evts remain unchosen or the exn:break exception is raised, but not both.

(sync/timeout/enable-break timeout evt ...+)  any
  timeout : (or/c #f (and/c real? (not/c negative?)) (-> any))
  evt : evt?
Like sync/enable-break, but with a timeout as for sync/timeout.

(choice-evt evt ...)  evt?
  evt : evt?
Creates and returns a single event that combines the evts. Supplying the result to sync is the same as supplying each evt to the same call.

(wrap-evt evt wrap)  evt?
  evt : (and/c evt? (not/c handle-evt?))
  wrap : (any/c . -> . any)
Creates an event that is in a ready when evt is ready, but whose result is determined by applying wrap to the result of evt. The call to wrap is parameterize-breaked to disable breaks initially. The evt cannot be an event created by handle-evt or any combination of choice-evt involving an event from handle-evt.

(handle-evt evt handle)  handle-evt?
  evt : (and/c evt? (not/c handle-evt?))
  handle : (any/c . -> . any)
Like wrap, except that handle is called in tail position with respect to the synchronization request, and without breaks explicitly disabled.

(guard-evt generator)  evt?
  generator : (-> evt?)
Creates a value that behaves as an event, but that is actually an event generator. For details, see the overview.

(nack-guard-evt generator)  evt?
  generator : (evt? . -> . evt?)
Creates a value that behaves as an event, but that is actually an event generator; the generator procedure receives an event that becomes ready with a #<void> value if the generated event was not ultimately chosen. For details, see the overview.

(poll-guard-evt generator)  evt?
  generator : (boolean? . -> . evt?)
Creates a value that behaves as an event, but that is actually an event generator; the generator procedure receives a boolean indicating whether the event is used for polling. For details, see the overview.

A constant event that is always ready, with itself as its result.

A constant event that is never ready.

Returns an event that is ready when the system is otherwise idle; see the overview for more information. The result of the system-idle-evt procedure is always the same event.

(alarm-evt msecs)  evt
  msecs : nonnegative-number?
Returns a synchronizable event that is not ready when (current-inexact-milliseconds) would return a value that is less than msecs, and it is ready when (current-inexact-milliseconds) would return a value that is more than msecs.

(handle-evt? evt)  boolean?
  evt : evt?
Returns #t if evt was created by handle-evt or by choice-evt applied to another event for which handle-evt? produces #t. Such events are illegal as an argument to handle-evt or wrap-evt, because they cannot be wrapped further. For any other event, handle-evt? produces #f, and the event is a legal argument to handle-evt or wrap-evt for further wrapping.

A structure type property that identifies structure types whose instances can serve as synchronizable events. The property value can be any of the following:

Instances of a structure type with the prop:input-port or prop:output-port property are also synchronizable by virtue of being a port. If the structure type has more than one of prop:evt, prop:input-port, and prop:output-port, then the prop:evt value (if any) takes precedence for determing the instance’s behavior as an event, and the prop:input-port property takes precedence over prop:output-port for synchronization.


> (define-struct wt (base val)
                 #:property prop:evt (struct-field-index base))
> (define sema (make-semaphore))
> (sync/timeout 0 (make-wt sema #f))


> (semaphore-post sema)
> (sync/timeout 0 (make-wt sema #f))


> (semaphore-post sema)
> (sync/timeout 0 (make-wt (lambda (self) (wt-val self)) sema))


> (semaphore-post sema)
> (define my-wt (make-wt (lambda (self) (wrap-evt
                                         (wt-val self)
                                         (lambda (x) self)))
> (sync/timeout 0 my-wt)


> (sync/timeout 0 my-wt)


A parameter that determines the pseudo-random number generator used by sync for events created by choice-evt.