11.2.1 Events (original) (raw)

11.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. Racket’s event system is based on Concurrent ML [Reppy99].

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 particularsynchronization 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 includeasynchronous channels,channels,custodian boxes,log receivers,place channels,ports,semaphores,subprocesses,TCP listeners,threads, andwill executors. Libraries can define new synchronizable events, especially though prop:evt.

Returns #t if v is a synchronizable event,#f otherwise.

Examples:

(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 multipleevts are ready, one of the evts is chosen pseudo-randomly for the result; thecurrent-evt-pseudo-random-generator parameter sets the random-number generator that controls this choice.

Examples:

Changed in version 6.1.0.3 of package base: Allow 0 arguments instead of 1 or more.

Like sync if timeout is #f. Iftimeout is a real number, then the result is #fif 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.

Examples:

; times out before waking up
#f
no ready events

Changed in version 6.1.0.3 of package base: Allow 1 argument instead of 2 or more.

Like sync, but breaking is enabled (seeBreaks) while waiting on the evts. If breaking is disabled when sync/enable-break is called, then either all evts remain unchosen or the exn:breakexception is raised, but not both.

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 theevts. 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 tochoice-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 chosenevt’s synchronization result.

Examples:

Creates an event that is ready for synchronization whenevt is ready for synchronization, but whosesynchronization result is determined by applying wrapto the synchronization result of evt. The number of arguments accepted by wrap must match the number of values for the synchronization result of evt.

The call to wrap isparameterize-breaked to disable breaks initially.

Examples:

Like wrap-evt, except that handle is called in tail position with respect to the synchronization request—and without breaks explicitly disabled—when it is not wrapped by wrap-evt,chaperone-evt, or another handle-evt.

Examples:

Creates a value that behaves as an event, but that is actually an event maker.

An event guard returned by guard-evt generates an event when guard is used with sync(or whenever it is part of a choice event used with sync, etc.), where the generated event is the result of callingmaker. The maker procedure may be called bysync at most once for a given call to sync, butmaker may not be called if a ready event is chosen beforeguard is even considered.

If maker returns a non-event, then maker’s result is replaced with an event that is ready for synchronization and whose synchronization result isguard.

Like guard-evt, but when maker is called, it is given a NACK (“negative acknowledgment”) event. After starting the call to maker, if the event from maker is not ultimately chosen as the ready event, then the NACK event supplied tomaker becomes ready for synchronization with a# value.

The 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 maker has not yet returned a value). If the event returned by maker is chosen, then the NACK event never becomes ready for synchronization.

Like guard-evt, but when maker is called, it is provided a boolean value that indicates whether the event will be used for a poll, #t, or for a blocking synchronization,#f.

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

Like guard-evt, but maker is called only afterevt becomes ready for synchronization, and thesynchronization result of evt is passed to maker.

The attempt to synchronize on evt proceeds concurrently as the attempt to synchronize on the result guard fromreplace-evt; despite that concurrency, if maker is called, it is called in the thread that is synchronizing onguard. Synchronization can succeed for both evt and another synchronized with guard at the same time; the single-choice guarantee of synchronization applies only to the result of maker and other events synchronized with guard.

If maker returns a non-event, then maker’s result is replaced with an event that is ready for synchronization and whose synchronization result isguard.

Added in version 6.1.0.3 of package base.

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

Example:

> (sync always-evt)
#

A constant event that is never ready for synchronization.

Example:

> (sync/timeout 0.1 never-evt)
#f

Returns an event that is ready for synchronization when the system is otherwise idle: if the result event were replaced bynever-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’ssynchronization result is #. The result of thesystem-idle-evt procedure is always the same event.

Examples:

(alarm-evt msecs [monotonic?]) → evt?
msecs : real?
monotonic? : any/c = #f

Returns a synchronizable event that is not ready for synchronization when(milliseconds) would return a value that is less than msecs, and it is ready for synchronization when(milliseconds) would return a value that is more than msecs. The value of milliseconds iscurrent-inexact-milliseconds when monotonic? is #f, or current-inexact-monotonic-milliseconds otherwise. The synchronization result of a alarm event is the alarm event itself.

Examples:

Changed in version 8.3.0.9 of package base: Added the monotonic? argument.

Returns #t if evt was created by handle-evtor by choice-evt applied to another event for whichhandle-evt? produces #t. For any other event,handle-evt? produces #f.

Examples:

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

For working with foreign libraries, a prop:evtvalue can also be a result of unsafe-poller, although that possibility is omitted from the safe contract of prop:evt.

Instances of a structure type with the prop:input-port orprop:output-port property are also synchronizable events by virtue of being a port. If the structure type has more than one ofprop:evt, prop:input-port, andprop: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 overprop:output-port for synchronization.

Examples:

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