On this page:
evt?
sync
sync/ timeout
sync/ enable-break
sync/ timeout/ enable-break
choice-evt
wrap-evt
handle-evt
guard-evt
nack-guard-evt
poll-guard-evt
always-evt
never-evt
system-idle-evt
alarm-evt
handle-evt?
prop: evt
current-evt-pseudo-random-generator
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.

Racket values that act as synchronizable events include semaphores, channels, asynchronous channels, ports, TCP listeners, threads, subprocesses, will executors, and custodian boxes. Libraries can define new synchronizable events, especially though prop:evt.

procedure

(evt? v)  boolean?

  v : any/c
Returns #t if v is a synchronizable event, #f otherwise.

procedure

(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.

procedure

(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.

procedure

(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.

procedure

(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.

procedure

(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.

That is, an event returned by choice-evt is ready for synchronization when one or more of the evts supplied to choice-evt are ready for synchronization. If the choice event is chosen, one of its ready evts is chosen pseudo-randomly, and the synchronization result is the chosen evt’s synchronization result.

procedure

(wrap-evt evt wrap)  evt?

  evt : (and/c evt? (not/c handle-evt?))
  wrap : (any/c . -> . any)
Creates an event that is ready for synchronization when evt is ready for synchronization, but whose synchronization result is determined by applying wrap to the synchronization 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.

procedure

(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.

procedure

(guard-evt generator)  evt?

  generator : (-> evt?)
Creates a value that behaves as an event, but that is actually an event generator.

An event guard returned by guard-evt generates a new event every time that guard is used with sync (or whenever it is part of a choice event used with sync, etc.). The generated event is the result of calling generator when the synchronization begins; if generator returns a non-event, then generator’s result is replaced with an event that is ready for synchronization and whose synchronization result is guard.

procedure

(nack-guard-evt generator)  evt?

  generator : (evt? . -> . evt?)
Creates a value that behaves as an event, but that is actually an event generator.

An event nack-guard returned by nack-guard-evt applied to proc generates a new event every time that nack-guard is used with sync (or whenever it is part of a choice event used with sync, etc.). The generated event is the result of calling generator with a NACK (“negative acknowledgment”) event when the synchronization begins; if generator returns a non-event, then generator’s result is replaced with an event that is ready and whose result is nack-guard.

If the event from generator is not ultimately chosen as the unblocked event, then the NACK event supplied to generator becomes ready for synchronization with a #<void> value. This NACK event becomes ready for synchronization when the event is abandoned when either some other event is chosen, the synchronizing thread is dead, or control escapes from the call to sync (even if nack-guard’s generator has not yet returned a value). If the event returned by generator is chosen, then the NACK event never becomes ready for synchronization.

procedure

(poll-guard-evt generator)  evt?

  generator : (boolean? . -> . evt?)
Creates a value that behaves as an event, but that is actually an event generator.

An event poll-guardreturned by poll-guard-evt generates a new event every time that poll-guard is used with sync (or whenever it is part of a choice event used with sync, etc.). The generated event is the result of calling generator with a boolean: #t if the event will be used for a poll, #f for a blocking synchronization.

If #t is supplied to generator, if breaks are disabled, if the polling thread is not terminated, and if polling the resulting event produces a synchronization result, the event will certainly be chosen for its result.

value

always-evt : evt?

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

value

never-evt : evt?

A constant event that is never ready for synchronization.

procedure

(system-idle-evt)  evt?

Returns an event that is ready for synchronization when the system is otherwise idle: if the result event were replaced by never-evt, no thread in the system would be available to run. In other words, all threads must be suspended or blocked on events with timeouts that have not yet expired. The system-idle event’s synchronization result is #<void>. The result of the system-idle-evt procedure is always the same event.

procedure

(alarm-evt msecs)  evt

  msecs : nonnegative-number?
Returns a synchronizable event that is not ready for synchronization when (current-inexact-milliseconds) would return a value that is less than msecs, and it is ready for synchronization when (current-inexact-milliseconds) would return a value that is more than msecs. The synchronization result of a alarm event is the alarm event itself.

procedure

(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 events 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 determining the instance’s behavior as an event, and the prop:input-port property takes precedence over prop:output-port for synchronization.

Examples:

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

#f

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

#<semaphore>

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

#<semaphore>

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

#<wt>

> (sync/timeout 0 my-wt)

#f

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