reference: rerrange docs on synchronizable events
Put the details consistently with event datatypes, instead of trying to put them all in `sync', which better reflects the extensibility of the set of synchronizable events.
This commit is contained in:
parent
c162657685
commit
b69573277c
|
@ -13,6 +13,17 @@
|
||||||
|
|
||||||
@margin-note/ref{See also @secref["threadmbox"].}
|
@margin-note/ref{See also @secref["threadmbox"].}
|
||||||
|
|
||||||
|
An @deftech{asynchronous channel} is like a @tech{channel}, but it buffers
|
||||||
|
values so that a send operation does not wait on a receive operation.
|
||||||
|
|
||||||
|
In addition to its use with procedures that are specific to
|
||||||
|
asynchronous channels, an asynchronous channel can be used as a
|
||||||
|
@tech{synchronizable event} (see @secref["sync"]). An asynchronous
|
||||||
|
channel is @tech{ready for synchronization} when
|
||||||
|
@racket[async-channel-get] would not block; the asynchronous channel's
|
||||||
|
@tech{synchronization result} is the same as the
|
||||||
|
@racket[async-channel-get] result.
|
||||||
|
|
||||||
@defproc[(async-channel? [v any/c]) boolean?]{
|
@defproc[(async-channel? [v any/c]) boolean?]{
|
||||||
|
|
||||||
Returns @racket[#t] if @racket[v] is an asynchronous channel,
|
Returns @racket[#t] if @racket[v] is an asynchronous channel,
|
||||||
|
@ -26,11 +37,7 @@ Returns an asynchronous channel with a buffer limit of @racket[limit]
|
||||||
items. A get operation blocks when the channel is empty, and a put
|
items. A get operation blocks when the channel is empty, and a put
|
||||||
operation blocks when the channel has @racket[limit] items already.
|
operation blocks when the channel has @racket[limit] items already.
|
||||||
If @racket[limit] is @racket[#f], the channel buffer has no limit (so
|
If @racket[limit] is @racket[#f], the channel buffer has no limit (so
|
||||||
a put never blocks).
|
a put never blocks).}
|
||||||
|
|
||||||
The asynchronous channel value can be used directly with
|
|
||||||
@racket[sync]. The channel blocks until @racket[async-channel-get]
|
|
||||||
would return a value, and the unblock result is the received value.}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(async-channel-get [ach async-channel?]) any/c]{
|
@defproc[(async-channel-get [ach async-channel?]) any/c]{
|
||||||
|
@ -56,9 +63,10 @@ is full until space is available.}
|
||||||
@defproc[(async-channel-put-evt [ach async-channel?] [v any/c])
|
@defproc[(async-channel-put-evt [ach async-channel?] [v any/c])
|
||||||
evt?]{
|
evt?]{
|
||||||
|
|
||||||
Returns a @tech{synchronizable event} that is blocked while
|
Returns a @tech{synchronizable event} that is @tech{ready for
|
||||||
@racket[(async-channel-put ach v)] would block. The unblock result is
|
synchronization} when @racket[(async-channel-put ach v)] would return
|
||||||
the event itself. See also @racket[sync].}
|
a value (i.e., when the channel holds fewer values already than its
|
||||||
|
limit); @resultItself{asychronous channel-put event}.}
|
||||||
|
|
||||||
@defexamples[#:eval (async-eval)
|
@defexamples[#:eval (async-eval)
|
||||||
(define (server input-channel output-channel)
|
(define (server input-channel output-channel)
|
||||||
|
|
|
@ -13,6 +13,13 @@ Channel synchronization is @defterm{fair}: if a thread is blocked on a
|
||||||
channel and transaction opportunities for the channel occur infinitely
|
channel and transaction opportunities for the channel occur infinitely
|
||||||
often, then the thread eventually participates in a transaction.
|
often, then the thread eventually participates in a transaction.
|
||||||
|
|
||||||
|
In addition to its use with channel-specific procedures, a channel can
|
||||||
|
be used as a @tech{synchronizable event} (see @secref["sync"]). A
|
||||||
|
channel is @tech{ready for synchronization} when @racket[make-channel]
|
||||||
|
is ready when @racket[channel-get] would not block; the channel's
|
||||||
|
@tech{synchronization result} is the same as the @racket[channel-get]
|
||||||
|
result.
|
||||||
|
|
||||||
For buffered asynchronous channels, see @secref["async-channel"].
|
For buffered asynchronous channels, see @secref["async-channel"].
|
||||||
|
|
||||||
@defproc[(channel? [v any/c]) boolean?]{
|
@defproc[(channel? [v any/c]) boolean?]{
|
||||||
|
@ -48,9 +55,9 @@ through @racket[ch].}
|
||||||
@defproc[(channel-put-evt [ch channel?] [v any/c]) channel-put-evt?]{
|
@defproc[(channel-put-evt [ch channel?] [v any/c]) channel-put-evt?]{
|
||||||
|
|
||||||
Returns a fresh @tech{synchronizable event} for use with
|
Returns a fresh @tech{synchronizable event} for use with
|
||||||
@racket[sync]. The event is ready when @racket[(channel-put ch v)]
|
@racket[sync]. The event is @tech{ready for synchronization} when
|
||||||
would not block, and the event's synchronization result is the event
|
@racket[(channel-put ch v)] would not block, and the event's
|
||||||
itself.}
|
@tech{synchronization result} is the event itself.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(channel-put-evt? [v any/c]) boolean?]{
|
@defproc[(channel-put-evt? [v any/c]) boolean?]{
|
||||||
|
|
|
@ -108,14 +108,16 @@ must be the same as @racket[limit-cust], so that excessively large
|
||||||
immediate allocations can be rejected with an
|
immediate allocations can be rejected with an
|
||||||
@racket[exn:fail:out-of-memory] exception.}
|
@racket[exn:fail:out-of-memory] exception.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(make-custodian-box [cust custodian?] [v any/c]) custodian-box?]{
|
@defproc[(make-custodian-box [cust custodian?] [v any/c]) custodian-box?]{
|
||||||
|
|
||||||
Returns a @tech{custodian box} that contains @racket[v] as long as
|
Returns a @tech{custodian box} that contains @racket[v] as long as
|
||||||
@racket[cust] has not been shut down.
|
@racket[cust] has not been shut down.
|
||||||
|
|
||||||
A @tech{custodian box} is a @tech{synchronizable event} for use with
|
A @tech{custodian box} is a @tech{synchronizable event} (see @secref["sync"]).
|
||||||
functions like @racket[sync]. The @tech{custodian box} becomes ready
|
The @tech{custodian box} becomes ready when its custodian is shut down;
|
||||||
when its custodian is shut down.}
|
@resultItself{@tech{custodian box}}.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(custodian-box? [v any/c]) boolean?]{Returns @racket[#t] if
|
@defproc[(custodian-box? [v any/c]) boolean?]{Returns @racket[#t] if
|
||||||
@racket[v] is a @tech{custodian box} produced by
|
@racket[v] is a @tech{custodian box} produced by
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
#lang scribble/doc
|
#lang scribble/doc
|
||||||
@(require scribble/struct "mz.rkt" (for-label racket/async-channel))
|
@(require scribble/struct "mz.rkt" (for-label racket/async-channel))
|
||||||
|
|
||||||
@(define-syntax-rule (ResultItself x)
|
|
||||||
(make-element #f (list "The "
|
|
||||||
(tech "synchronization result")
|
|
||||||
" of " @racket[x] " is " @racket[x] " itself")))
|
|
||||||
|
|
||||||
@title[#:tag "sync"]{Events}
|
@title[#:tag "sync"]{Events}
|
||||||
|
|
||||||
@section-index["select"]
|
@section-index["select"]
|
||||||
|
@ -17,8 +12,8 @@ among threads. Certain kinds of objects double as events, including
|
||||||
ports and threads. Other kinds of objects exist only for their use as
|
ports and threads. Other kinds of objects exist only for their use as
|
||||||
events.
|
events.
|
||||||
|
|
||||||
At any point in time, an event is either @defterm{ready} for
|
At any point in time, an event is either @deftech{ready for
|
||||||
synchronization, or it is not; depending on the kind of event and how
|
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
|
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
|
ready (or back), at any time. If a thread synchronizes on an event
|
||||||
when it is ready, then the event produces a particular
|
when it is ready, then the event produces a particular
|
||||||
|
@ -30,187 +25,12 @@ decremented, just as with @racket[semaphore-wait]. For most kinds of
|
||||||
events, however (such as a port), synchronizing does not modify the
|
events, however (such as a port), synchronizing does not modify the
|
||||||
event's state.
|
event's state.
|
||||||
|
|
||||||
The following act as events in Racket. An extension or embedding
|
Racket values that act as @tech{synchronizable events} include
|
||||||
application can extend the set of primitive events --- in particular,
|
@tech{semaphores}, @tech{channels}, @tech{asynchronous channels},
|
||||||
an eventspace in GRacket is an event --- and new structure types can
|
@tech{ports}, @tech{TCP listeners}, @tech{threads},
|
||||||
generate events (see @racket[prop:evt]).
|
@tech{subprocess}es, @tech{will executors}, and @tech{custodian
|
||||||
|
box}es. Libraries can define new synchronizable events, especially
|
||||||
@itemize[
|
though @racket[prop:evt].
|
||||||
|
|
||||||
@item{@racket[_semaphore] --- a semaphore is ready when
|
|
||||||
@racket[semaphore-wait] would not block. @ResultItself[_semaphore].}
|
|
||||||
|
|
||||||
@item{@racket[_semaphore-peek] --- a semaphore-peek event returned by
|
|
||||||
@racket[semaphore-peek-evt] applied to @racket[_semaphore] is ready
|
|
||||||
exactly when @racket[_semaphore] is
|
|
||||||
ready. @ResultItself[_semaphore-peek].}
|
|
||||||
|
|
||||||
@item{@racket[_channel] --- a channel returned by
|
|
||||||
@racket[make-channel] is ready when @racket[channel-get] would not
|
|
||||||
block. The channel's result as an event is the same as the
|
|
||||||
@racket[channel-get] result.}
|
|
||||||
|
|
||||||
@item{@racket[_channel-put] --- an event returned by
|
|
||||||
@racket[channel-put-evt] applied to @racket[_channel] is ready when
|
|
||||||
@racket[channel-put] would not block on
|
|
||||||
@racket[_channel]. @ResultItself[_channel-put].}
|
|
||||||
|
|
||||||
@item{@racket[_async-channel] --- a channel returned by
|
|
||||||
@racket[make-async-channel] is ready when @racket[async-channel-get] would not
|
|
||||||
block. The channel's result as an event is the same as the
|
|
||||||
@racket[async-channel-get] result.}
|
|
||||||
|
|
||||||
@item{@racket[_async-channel-put] --- an event returned by
|
|
||||||
@racket[async-channel-put-evt] applied to @racket[_async-channel] is ready when
|
|
||||||
@racket[async-channel-put] would not block on
|
|
||||||
@racket[_async-channel]. @ResultItself[_async-channel-put].}
|
|
||||||
|
|
||||||
@item{@racket[_input-port] --- an input port is ready as an event when
|
|
||||||
@racket[read-byte] would not block. @ResultItself[_input-port].}
|
|
||||||
|
|
||||||
@item{@racket[_output-port] --- an output port is ready when
|
|
||||||
@racket[write-bytes-avail] would not block or
|
|
||||||
when the port contains buffered characters and
|
|
||||||
@racket[write-bytes-avail*] can flush part of the buffer (although
|
|
||||||
@racket[write-bytes-avail] might block). @ResultItself[_output-port].}
|
|
||||||
|
|
||||||
@item{@racket[_closed] --- an event produced by
|
|
||||||
@racket[port-closed-evt] applied to @racket[_port] is ready after
|
|
||||||
@racket[_port] is closed. @ResultItself[_closed].}
|
|
||||||
|
|
||||||
@item{@racket[_progress] --- an event produced by
|
|
||||||
@racket[port-progress-evt] applied to @racket[_input-port] is ready after
|
|
||||||
any subsequent read from @racket[_input-port]. @ResultItself[_progress].}
|
|
||||||
|
|
||||||
@item{@racket[_tcp-listener] --- a TCP listener is ready when
|
|
||||||
@racket[tcp-accept] would not block. @ResultItself[_listener].}
|
|
||||||
|
|
||||||
@item{@racket[_thd] --- a thread is ready when @racket[thread-wait]
|
|
||||||
would not block. @ResultItself[_thread].}
|
|
||||||
|
|
||||||
@item{@racket[_thread-dead] --- an event returned by
|
|
||||||
@racket[thread-dead-evt] applied to @racket[thd] is ready when
|
|
||||||
@racket[thd] has terminated. @ResultItself[_thread-dead].}
|
|
||||||
|
|
||||||
@item{@racket[_thread-resume] --- an event returned by
|
|
||||||
@racket[thread-resume-evt] applied to @racket[thd] is ready when
|
|
||||||
@racket[thd] subsequently resumes execution (if it was not already
|
|
||||||
running). The event's result is @racket[thd].}
|
|
||||||
|
|
||||||
@item{@racket[_thread-suspend] --- an event returned by
|
|
||||||
@racket[thread-suspend-evt] applied to @racket[thd] is ready when
|
|
||||||
@racket[thd] subsequently suspends execution (if it was not already
|
|
||||||
suspended). The event's result is @racket[thd].}
|
|
||||||
|
|
||||||
@item{@racket[_thread-receive] --- an event returned by
|
|
||||||
@racket[thread-receive-evt] is ready
|
|
||||||
when the synchronizing thread has a message to
|
|
||||||
receive. @ResultItself[_thread-receive].}
|
|
||||||
|
|
||||||
@item{@racket[_alarm] --- an event returned by @racket[alarm-evt] is
|
|
||||||
ready after a particular date and time. @ResultItself[_alarm].}
|
|
||||||
|
|
||||||
@item{@racket[_subprocess] --- a subprocess is ready when
|
|
||||||
@racket[subprocess-wait] would not block.
|
|
||||||
@ResultItself[_subprocess].}
|
|
||||||
|
|
||||||
@item{@racket[_will-executor] --- a @tech{will executor} is ready when
|
|
||||||
@racket[will-execute] would not block.
|
|
||||||
@ResultItself[_will-executor].}
|
|
||||||
|
|
||||||
@item{@racket[_custodian-box] --- a @tech{custodian box} is ready when
|
|
||||||
its custodian is shut down. @ResultItself[_custodian-box].}
|
|
||||||
|
|
||||||
@item{@racket[_udp] --- an event returned by @racket[udp-send-evt] or
|
|
||||||
@racket[udp-receive!-evt] is ready when a send or receive on the
|
|
||||||
original socket would block, respectively. @ResultItself[_udp].}
|
|
||||||
|
|
||||||
@item{@racket[_log-receiver] --- a @tech{log receiver} as produced by
|
|
||||||
@racket[make-log-receiver] is ready when a logged message is
|
|
||||||
available. The event's result is a vector, as described with
|
|
||||||
@racket[make-log-receiver].}
|
|
||||||
|
|
||||||
@item{@racket[_choice] --- an event returned by @racket[choice-evt] is
|
|
||||||
ready when one or more of the @racket[_evt]s supplied to
|
|
||||||
@racket[choice-evt] are ready. If the choice event is chosen, one of
|
|
||||||
its ready @racket[_evt]s is chosen pseudo-randomly, and the result is
|
|
||||||
the chosen @racket[_evt]'s result.}
|
|
||||||
|
|
||||||
@item{@racket[_wrap] --- an event returned by @racket[wrap-evt]
|
|
||||||
applied to @racket[_evt] and @racket[_proc] is ready when @racket[_evt] is
|
|
||||||
ready. The event's result is obtained by a call to @racket[_proc] (with
|
|
||||||
breaks disabled) on the result of @racket[evt].}
|
|
||||||
|
|
||||||
@item{@racket[_handle] --- an event returned by @racket[handle-evt]
|
|
||||||
applied to @racket[_evt] and @racket[_proc] is ready when @racket[_evt] is
|
|
||||||
ready. The event's result is obtained by a tail call to @racket[_proc] on
|
|
||||||
the result of @racket[_evt].}
|
|
||||||
|
|
||||||
@item{@elemtag["guard-evt"]{@racket[_guard]} --- an event returned by @racket[guard-evt] applied
|
|
||||||
to @racket[_thunk] generates a new event every time that @racket[_guard] is
|
|
||||||
used with @racket[sync] (or whenever it is part of a choice event
|
|
||||||
used with @racket[sync], etc.); the generated event is the result of
|
|
||||||
calling @racket[_thunk] when the synchronization begins; if @racket[_thunk]
|
|
||||||
returns a non-event, then @racket[_thunk]'s result is replaced with an
|
|
||||||
event that is ready and whose result is @racket[_guard].}
|
|
||||||
|
|
||||||
@item{@elemtag["nack-guard-evt"]{@racket[_nack-guard]} --- an event
|
|
||||||
returned by @racket[nack-guard-evt] applied to @racket[_proc]
|
|
||||||
generates a new event every time that @racket[_nack-guard] is used
|
|
||||||
with @racket[sync] (or whenever it is part of a choice event used
|
|
||||||
with @racket[sync], etc.); the generated event is the result of
|
|
||||||
calling @racket[_proc] with a NACK (``negative acknowledgment'') event
|
|
||||||
when the synchronization begins; if @racket[_proc] returns a
|
|
||||||
non-event, then @racket[_proc]'s result is replaced with an event that
|
|
||||||
is ready and whose result is @racket[_nack-guard].
|
|
||||||
|
|
||||||
If the event from @racket[_proc] is not ultimately chosen as the
|
|
||||||
unblocked event, then the NACK event supplied to @racket[_proc]
|
|
||||||
becomes ready with a @|void-const| value. This NACK event becomes ready
|
|
||||||
when the event is abandoned because some other event is chosen,
|
|
||||||
because the synchronizing thread is dead, or because control escaped
|
|
||||||
from the call to @racket[sync] (even if @racket[_nack-guard]'s @racket[_proc]
|
|
||||||
has not yet returned a value). If the event returned by @racket[_proc] is
|
|
||||||
chosen, then the NACK event never becomes ready.}
|
|
||||||
|
|
||||||
@item{@elemtag["poll-guard-evt"]{@racket[_poll-guard]} --- an event
|
|
||||||
returned by @racket[poll-guard-evt] applied to @racket[_proc]
|
|
||||||
generates a new event every time that @racket[_poll-guard] is used
|
|
||||||
with @racket[sync] (or whenever it is part of a choice event used
|
|
||||||
with @racket[sync], etc.); the generated event is the result of
|
|
||||||
calling @racket[_proc] with a boolean: @racket[#t] if the event will
|
|
||||||
be used for a poll, @racket[#f] for a blocking synchronization.
|
|
||||||
|
|
||||||
If @racket[#t] is supplied to @racket[_proc], if breaks are disabled, if
|
|
||||||
the polling thread is not terminated, and if polling the resulting
|
|
||||||
event produces a result, the event will certainly be chosen for its
|
|
||||||
result.}
|
|
||||||
|
|
||||||
@item{@racket[_struct] --- a structure whose type has the
|
|
||||||
@racket[prop:evt] property identifies/generates an event through the
|
|
||||||
property.}
|
|
||||||
|
|
||||||
@item{@racket[always-evt] --- a constant event that is always
|
|
||||||
ready. @ResultItself[always-evt].}
|
|
||||||
|
|
||||||
@item{@racket[never-evt] --- a constant event that is never ready.}
|
|
||||||
|
|
||||||
@item{@elemtag["system-idle-evt"]{@racket[_idle]} --- an event
|
|
||||||
produced by @racket[system-idle-evt] is ready when, if this event
|
|
||||||
were replaced by @racket[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
|
|
||||||
event's result is @|void-const|.}
|
|
||||||
|
|
||||||
@item{@racket[_place-channel] --- a @tech{place channel} is ready when
|
|
||||||
@racket[place-channel-get] would not block. The channel's result as an
|
|
||||||
event is the same as the @racket[place-channel-get] result.}
|
|
||||||
|
|
||||||
@item{@racket[_place-dead] --- an event returned by
|
|
||||||
@racket[(place-dead-evt _p)] is ready when @racket[_p] has
|
|
||||||
terminated. @ResultItself[_place-dead].}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -271,69 +91,126 @@ Like @racket[sync/enable-break], but with a timeout as for @racket[sync/timeout]
|
||||||
|
|
||||||
Creates and returns a single event that combines the
|
Creates and returns a single event that combines the
|
||||||
@racket[evt]s. Supplying the result to @racket[sync] is the same as
|
@racket[evt]s. Supplying the result to @racket[sync] is the same as
|
||||||
supplying each @racket[evt] to the same call.}
|
supplying each @racket[evt] to the same call.
|
||||||
|
|
||||||
|
That is, an event returned by @racket[choice-evt] is @tech{ready for
|
||||||
|
synchronization} when one or more of the @racket[_evt]s supplied to
|
||||||
|
@racket[choice-evt] are @tech{ready for synchronization}. If the
|
||||||
|
choice event is chosen, one of its ready @racket[_evt]s is chosen
|
||||||
|
pseudo-randomly, and the @tech{synchronization result} is the chosen
|
||||||
|
@racket[_evt]'s @tech{synchronization result}.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(wrap-evt [evt (and/c evt? (not/c handle-evt?))]
|
@defproc[(wrap-evt [evt (and/c evt? (not/c handle-evt?))]
|
||||||
[wrap (any/c . -> . any)])
|
[wrap (any/c . -> . any)])
|
||||||
evt?]{
|
evt?]{
|
||||||
|
|
||||||
Creates an event that is in a ready when @racket[evt] is ready, but
|
Creates an event that is @tech{ready for synchronization} when
|
||||||
whose result is determined by applying @racket[wrap] to the result of
|
@racket[evt] is @tech{ready for synchronization}, but whose
|
||||||
@racket[evt]. The call to @racket[wrap] is
|
@tech{synchronization result} is determined by applying @racket[wrap]
|
||||||
|
to the @tech{synchronization result} of @racket[evt].
|
||||||
|
|
||||||
|
The call to @racket[wrap] is
|
||||||
@racket[parameterize-break]ed to disable breaks initially. The
|
@racket[parameterize-break]ed to disable breaks initially. The
|
||||||
@racket[evt] cannot be an event created by @racket[handle-evt] or any
|
@racket[evt] cannot be an event created by @racket[handle-evt] or any
|
||||||
combination of @racket[choice-evt] involving an event from
|
combination of @racket[choice-evt] involving an event from
|
||||||
@racket[handle-evt].}
|
@racket[handle-evt].}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(handle-evt [evt (and/c evt? (not/c handle-evt?))]
|
@defproc[(handle-evt [evt (and/c evt? (not/c handle-evt?))]
|
||||||
[handle (any/c . -> . any)])
|
[handle (any/c . -> . any)])
|
||||||
handle-evt?]{
|
handle-evt?]{
|
||||||
|
|
||||||
Like @racket[wrap], except that @racket[handle] is called in tail
|
Like @racket[wrap], except that @racket[handle] is called in @tech{tail
|
||||||
position with respect to the synchronization request, and without
|
position} with respect to the synchronization request, and without
|
||||||
breaks explicitly disabled.}
|
breaks explicitly disabled.}
|
||||||
|
|
||||||
@defproc[(guard-evt [generator (-> evt?)]) evt?]{
|
@defproc[(guard-evt [generator (-> evt?)]) evt?]{
|
||||||
|
|
||||||
Creates a value that behaves as an event, but that is actually an
|
Creates a value that behaves as an event, but that is actually an
|
||||||
event generator. For details, see @elemref["guard-evt"]{the
|
event generator.
|
||||||
overview}.}
|
|
||||||
|
An event @racket[_guard] returned by @racket[guard-evt] generates a
|
||||||
|
new event every time that @racket[_guard] is used with @racket[sync]
|
||||||
|
(or whenever it is part of a choice event used with @racket[sync],
|
||||||
|
etc.). The generated event is the result of calling
|
||||||
|
@racket[_generator] when the synchronization begins; if
|
||||||
|
@racket[_generator] returns a non-event, then @racket[_generator]'s
|
||||||
|
result is replaced with an event that is @tech{ready for
|
||||||
|
synchronization} and whose @tech{synchronization result} is
|
||||||
|
@racket[_guard].}
|
||||||
|
|
||||||
@defproc[(nack-guard-evt [generator (evt? . -> . evt?)]) evt?]{
|
@defproc[(nack-guard-evt [generator (evt? . -> . evt?)]) evt?]{
|
||||||
|
|
||||||
Creates a value that behaves as an event, but that is actually an
|
Creates a value that behaves as an event, but that is actually an
|
||||||
event generator; the generator procedure receives an event that
|
event generator.
|
||||||
becomes ready with a @|void-const| value if the generated event was
|
|
||||||
not ultimately chosen. For details, see
|
An event @racket[_nack-guard] returned by @racket[nack-guard-evt]
|
||||||
@elemref["nack-guard-evt"]{the overview}.}
|
applied to @racket[_proc] generates a new event every time that
|
||||||
|
@racket[_nack-guard] is used with @racket[sync] (or whenever it is
|
||||||
|
part of a choice event used with @racket[sync], etc.). The generated
|
||||||
|
event is the result of calling @racket[_generator] with a NACK (``negative
|
||||||
|
acknowledgment'') event when the synchronization begins; if
|
||||||
|
@racket[_generator] returns a non-event, then @racket[_generator]'s result is
|
||||||
|
replaced with an event that is ready and whose result is
|
||||||
|
@racket[_nack-guard].
|
||||||
|
|
||||||
|
If the event from @racket[_generator] is not ultimately chosen as the
|
||||||
|
unblocked event, then the NACK event supplied to @racket[_generator]
|
||||||
|
becomes @tech{ready for synchronization} with a @|void-const| value.
|
||||||
|
This NACK event becomes @tech{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
|
||||||
|
@racket[sync] (even if @racket[_nack-guard]'s @racket[_generator] has
|
||||||
|
not yet returned a value). If the event returned by
|
||||||
|
@racket[_generator] is chosen, then the NACK event never becomes
|
||||||
|
@tech{ready for synchronization}.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(poll-guard-evt [generator (boolean? . -> . evt?)]) evt?]{
|
@defproc[(poll-guard-evt [generator (boolean? . -> . evt?)]) evt?]{
|
||||||
|
|
||||||
Creates a value that behaves as an event, but that is actually an
|
Creates a value that behaves as an event, but that is actually an
|
||||||
event generator; the generator procedure receives a boolean indicating
|
event generator.
|
||||||
whether the event is used for polling. For details, see
|
|
||||||
@elemref["poll-guard-evt"]{the overview}.}
|
|
||||||
|
|
||||||
@defthing[always-evt evt?]{A constant event that is always ready, with
|
An event @racket[_poll-guard]returned by @racket[poll-guard-evt]
|
||||||
itself as its result.}
|
generates a new event every time that @racket[_poll-guard] is used
|
||||||
|
with @racket[sync] (or whenever it is part of a choice event used with
|
||||||
|
@racket[sync], etc.). The generated event is the result of calling
|
||||||
|
@racket[_generator] with a boolean: @racket[#t] if the event will be
|
||||||
|
used for a poll, @racket[#f] for a blocking synchronization.
|
||||||
|
|
||||||
@defthing[never-evt evt?]{A constant event that is never ready.}
|
If @racket[#t] is supplied to @racket[_generator], if breaks are
|
||||||
|
disabled, if the polling thread is not terminated, and if polling the
|
||||||
|
resulting event produces a @tech{synchronization result}, the event
|
||||||
|
will certainly be chosen for its result.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(system-idle-evt) evt?]{Returns an event that is ready when
|
@defthing[always-evt evt?]{A constant event that is always @tech{ready
|
||||||
the system is otherwise idle; see @elemref["system-idle-evt"]{the
|
for synchronization}, with itself as its @tech{synchronization result}.}
|
||||||
overview} for more information. The result of the
|
|
||||||
|
|
||||||
|
@defthing[never-evt evt?]{A constant event that is never @tech{ready
|
||||||
|
for synchronization}.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(system-idle-evt) evt?]{
|
||||||
|
|
||||||
|
Returns an event that is @tech{ready for synchronization} when the
|
||||||
|
system is otherwise idle: if the result event were replaced by
|
||||||
|
@racket[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
|
||||||
|
@tech{synchronization result} is @|void-const|. The result of the
|
||||||
@racket[system-idle-evt] procedure is always the same event.}
|
@racket[system-idle-evt] procedure is always the same event.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(alarm-evt [msecs nonnegative-number?]) evt]{
|
@defproc[(alarm-evt [msecs nonnegative-number?]) evt]{
|
||||||
|
|
||||||
Returns a synchronizable event that is not ready when
|
Returns a @tech{synchronizable event} that is not @tech{ready for synchronization} when
|
||||||
@racket[(current-inexact-milliseconds)] would return a value that is
|
@racket[(current-inexact-milliseconds)] would return a value that is
|
||||||
less than @racket[msecs], and it is ready when
|
less than @racket[msecs], and it is @tech{ready for synchronization} when
|
||||||
@racket[(current-inexact-milliseconds)] would return a value that is
|
@racket[(current-inexact-milliseconds)] would return a value that is
|
||||||
more than @racket[msecs].}
|
more than @racket[msecs]. @ResultItself{alarm event}.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(handle-evt? [evt evt?]) boolean?]{
|
@defproc[(handle-evt? [evt evt?]) boolean?]{
|
||||||
|
@ -350,7 +227,7 @@ produces @racket[#f], and the event is a legal argument to
|
||||||
@defthing[prop:evt struct-type-property?]{
|
@defthing[prop:evt struct-type-property?]{
|
||||||
|
|
||||||
A @tech{structure type property} that identifies structure types whose
|
A @tech{structure type property} that identifies structure types whose
|
||||||
instances can serve as synchronizable events. The property value can
|
instances can serve as @tech{synchronizable events}. The property value can
|
||||||
be any of the following:
|
be any of the following:
|
||||||
|
|
||||||
@itemize[
|
@itemize[
|
||||||
|
@ -376,7 +253,7 @@ A @tech{structure type property} that identifies structure types whose
|
||||||
]
|
]
|
||||||
|
|
||||||
Instances of a structure type with the @racket[prop:input-port] or
|
Instances of a structure type with the @racket[prop:input-port] or
|
||||||
@racket[prop:output-port] property are also synchronizable by virtue
|
@racket[prop:output-port] property are also @tech{synchronizable events} by virtue
|
||||||
of being a port. If the structure type has more than one of
|
of being a port. If the structure type has more than one of
|
||||||
@racket[prop:evt], @racket[prop:input-port], and
|
@racket[prop:evt], @racket[prop:input-port], and
|
||||||
@racket[prop:output-port], then the @racket[prop:evt] value (if any)
|
@racket[prop:output-port], then the @racket[prop:evt] value (if any)
|
||||||
|
|
|
@ -228,9 +228,9 @@ descendants, as long as either @racket[name] is @racket[#f] or the
|
||||||
reporting logger's name matches @racket[name].
|
reporting logger's name matches @racket[name].
|
||||||
|
|
||||||
A @tech{log receiver} is a @tech{synchronizable event}. It becomes
|
A @tech{log receiver} is a @tech{synchronizable event}. It becomes
|
||||||
ready as an @tech{synchronizable event} when a logging event is
|
@tech{ready for synchronization} when a logging event is
|
||||||
received, so use @racket[sync] to receive an logged event. The
|
received, so use @racket[sync] to receive an logged event. The
|
||||||
@tech{log receiver}'s synchronization value is a vector containing
|
@tech{log receiver}'s @tech{synchronization result} is a vector containing
|
||||||
three values: the level of the event as a symbol, an immutable string
|
three values: the level of the event as a symbol, an immutable string
|
||||||
for the event message, and an arbitrary value that was supplied as the
|
for the event message, and an arbitrary value that was supplied as the
|
||||||
last argument to @racket[log-message] when the event was logged.
|
last argument to @racket[log-message] when the event was logged.
|
||||||
|
@ -243,3 +243,4 @@ the last given @racket[level]). A @racket[level] for a @racket[#f]
|
||||||
provided @racket[name]. If the same @racket[name] is provided multiple
|
provided @racket[name]. If the same @racket[name] is provided multiple
|
||||||
times, the @racket[level] provided with the last instance in the
|
times, the @racket[level] provided with the last instance in the
|
||||||
argument list takes precedence.}
|
argument list takes precedence.}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,10 @@ executor, the weak box's content is not changed to @racket[#f] until
|
||||||
all wills have been executed for the value and the value has been
|
all wills have been executed for the value and the value has been
|
||||||
proven again reachable through only weak references.
|
proven again reachable through only weak references.
|
||||||
|
|
||||||
|
A will executor can be used as a @tech{synchronizable event} (see @secref["sync"]).
|
||||||
|
A will executor is @tech{ready for synchronization} when
|
||||||
|
@racket[will-execute] would not block; @resultItself{will executor}.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(make-will-executor) will-executor?]{
|
@defproc[(make-will-executor) will-executor?]{
|
||||||
|
|
||||||
|
|
|
@ -143,3 +143,11 @@
|
||||||
(t "An " (racket id) " application can provide better performance for "
|
(t "An " (racket id) " application can provide better performance for "
|
||||||
(elem what)
|
(elem what)
|
||||||
" iteration when it appears directly in a " (racket for) " clause.")]))
|
" iteration when it appears directly in a " (racket for) " clause.")]))
|
||||||
|
|
||||||
|
(provide resultItself ResultItself)
|
||||||
|
(define (esultItself T x)
|
||||||
|
(make-element #f (list T "he "
|
||||||
|
(tech "synchronization result")
|
||||||
|
" of a " x " is the " x " itself")))
|
||||||
|
(define (ResultItself x) (esultItself "T" x))
|
||||||
|
(define (resultItself x) (esultItself "t" x))
|
||||||
|
|
|
@ -60,7 +60,11 @@ listener}. This value can be used in future calls to
|
||||||
management of the current custodian (see @secref["custodians"]).
|
management of the current custodian (see @secref["custodians"]).
|
||||||
|
|
||||||
If the server cannot be started by @racket[tcp-listen], the
|
If the server cannot be started by @racket[tcp-listen], the
|
||||||
@exnraise[exn:fail:network].}
|
@exnraise[exn:fail:network].
|
||||||
|
|
||||||
|
A TCP listener can be used as a @tech{synchronizable event} (see @secref["sync"]).
|
||||||
|
A TCP listener is @tech{ready for synchronization} when
|
||||||
|
@racket[tcp-accept] would not block; @resultItself{TCP listener}.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(tcp-connect [hostname string?]
|
@defproc[(tcp-connect [hostname string?]
|
||||||
|
@ -200,11 +204,11 @@ Returns @racket[#t] if @racket[v] is a @tech{TCP listener} created by
|
||||||
|
|
||||||
@defproc[(tcp-accept-evt [listener tcp-listener?]) evt?]{
|
@defproc[(tcp-accept-evt [listener tcp-listener?]) evt?]{
|
||||||
|
|
||||||
Returns a @tech{synchronizable event} (see @secref["sync"]) that is in
|
Returns a @tech{synchronizable event} (see @secref["sync"]) that is
|
||||||
a blocking state when @racket[tcp-accept] on @racket[listener] would
|
@tech{ready for synchronization} when @racket[tcp-accept] on @racket[listener] would
|
||||||
block. If the event is chosen in a synchronization, the result is a
|
not block. The @tech{synchronization result} is a
|
||||||
list of two items, which correspond to the two results of
|
list of two items, which correspond to the two results of
|
||||||
@racket[tcp-accept]. (If the event is not chosen, no connections are
|
@racket[tcp-accept]. (If the event is not chosen in a @racket[syntax], no connections are
|
||||||
accepted.) The ports are placed into the management of the custodian
|
accepted.) The ports are placed into the management of the custodian
|
||||||
that is the current custodian (see @secref["custodians"]) at the time that
|
that is the current custodian (see @secref["custodians"]) at the time that
|
||||||
@racket[tcp-accept-evt] is called.}
|
@racket[tcp-accept-evt] is called.}
|
||||||
|
@ -545,11 +549,11 @@ bstr start-pos end-pos)], and the synchronization result is
|
||||||
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
|
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
|
||||||
evt?]{
|
evt?]{
|
||||||
|
|
||||||
Returns a @tech{synchronizable event}. The event is in a blocking
|
Returns a @tech{synchronizable event}. The event is @tech{ready for synchronization}
|
||||||
state when @racket[udp-send] on @racket[udp-socket] would
|
state when @racket[udp-send] on @racket[udp-socket] would
|
||||||
block. Otherwise, if the event is chosen in a synchronization, data is
|
not block. Otherwise, if the event is chosen in a synchronization, data is
|
||||||
sent as for @racket[(udp-send-to udp-socket bstr start-pos end-pos)],
|
sent as for @racket[(udp-send-to udp-socket bstr start-pos end-pos)],
|
||||||
and the synchronization result is @|void-const|. (No bytes are sent if
|
and the @tech{synchronization result} is @|void-const|. (No bytes are sent if
|
||||||
the event is not chosen.) If @racket[udp-socket] is closed or
|
the event is not chosen.) If @racket[udp-socket] is closed or
|
||||||
unconnected, the @exnraise[exn:fail:network] during a synchronization
|
unconnected, the @exnraise[exn:fail:network] during a synchronization
|
||||||
attempt.}
|
attempt.}
|
||||||
|
@ -560,11 +564,11 @@ attempt.}
|
||||||
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
|
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
|
||||||
evt?]{
|
evt?]{
|
||||||
|
|
||||||
Returns a @tech{synchronizable event}. The event is in a blocking
|
Returns a @tech{synchronizable event}. The event is @tech{ready for synchronization}
|
||||||
state when @racket[udp-receive] on @racket[udp-socket] would
|
when @racket[udp-receive] on @racket[udp-socket] would not
|
||||||
block. Otherwise, if the event is chosen in a synchronization, data is
|
block. Otherwise, if the event is chosen in a synchronization, data is
|
||||||
received into @racket[bstr] as for @racket[(udp-receive! udp-socket
|
received into @racket[bstr] as for @racket[(udp-receive! udp-socket
|
||||||
bytes start-pos end-pos)], and the synchronization result is a list of
|
bytes start-pos end-pos)], and the @tech{synchronization result} is a list of
|
||||||
three values, corresponding to the three results from
|
three values, corresponding to the three results from
|
||||||
@racket[udp-receive!]. (No bytes are received and the @racket[bstr]
|
@racket[udp-receive!]. (No bytes are received and the @racket[bstr]
|
||||||
content is not modified if the event is not chosen.)}
|
content is not modified if the event is not chosen.)}
|
||||||
|
|
|
@ -48,7 +48,11 @@ places that share the value, because they are allowed in a
|
||||||
@deftech{shared memory space}. See @racket[place-message-allowed?].
|
@deftech{shared memory space}. See @racket[place-message-allowed?].
|
||||||
|
|
||||||
A @tech{place channel} can be used as a @tech{synchronizable event}
|
A @tech{place channel} can be used as a @tech{synchronizable event}
|
||||||
(see @secref["sync"]) to receive a value through the channel. A place
|
(see @secref["sync"]) to receive a value through the channel.
|
||||||
|
A @tech{place channel} is @tech{ready for synchronization} when
|
||||||
|
a message is available on the channel, and the @tech{place channel}'s
|
||||||
|
@tech{synchronization result} is the message (which is removed on
|
||||||
|
synchronization). A place
|
||||||
can also receive messages with @racket[place-channel-get], and
|
can also receive messages with @racket[place-channel-get], and
|
||||||
messages can be sent with @racket[place-channel-put].
|
messages can be sent with @racket[place-channel-put].
|
||||||
|
|
||||||
|
@ -237,7 +241,8 @@ The @racket[dynamic-place*] procedure returns four values:
|
||||||
@defproc[(place-dead-evt [p place?]) evt?]{
|
@defproc[(place-dead-evt [p place?]) evt?]{
|
||||||
|
|
||||||
Returns a @tech{synchronizable event} (see @secref["sync"]) that is
|
Returns a @tech{synchronizable event} (see @secref["sync"]) that is
|
||||||
ready if and only if @racket[p] has terminated.
|
@tech{ready for synchronization} if and only if @racket[p] has terminated.
|
||||||
|
@ResultItself{place-dead event}.
|
||||||
|
|
||||||
If any pumping threads were created to connect a non-@tech{file-stream
|
If any pumping threads were created to connect a non-@tech{file-stream
|
||||||
port} to the ports in the place for @racket[p] (see
|
port} to the ports in the place for @racket[p] (see
|
||||||
|
|
|
@ -30,8 +30,9 @@ Returns @racket[#t] if the input or output port @racket[port] is
|
||||||
closed, @racket[#f] otherwise.}
|
closed, @racket[#f] otherwise.}
|
||||||
|
|
||||||
@defproc[(port-closed-evt [port port?]) evt?]{
|
@defproc[(port-closed-evt [port port?]) evt?]{
|
||||||
Return a @tech{synchronizable event} that becomes ready when @racket[port] is
|
Return a @tech{synchronizable event} that becomes @tech{ready for
|
||||||
closed.}
|
synchronization} when @racket[port] is
|
||||||
|
closed. @ResultItself{port-closed event}.}
|
||||||
|
|
||||||
@defparam[current-input-port in input-port?]{A @tech{parameter} that
|
@defparam[current-input-port in input-port?]{A @tech{parameter} that
|
||||||
determines a default input port for many operations, such as
|
determines a default input port for many operations, such as
|
||||||
|
|
|
@ -28,6 +28,15 @@ purposes. The @racket[read-syntax] procedure uses the name of an input
|
||||||
port as the default source location for the @tech{syntax objects} that
|
port as the default source location for the @tech{syntax objects} that
|
||||||
it produces.
|
it produces.
|
||||||
|
|
||||||
|
A port can be used as a @tech{synchronizable event}. An input port is
|
||||||
|
@tech{ready for synchronization} when @racket[read-byte] would not
|
||||||
|
block, and an output port is @tech{ready for synchronization} when
|
||||||
|
@racket[write-bytes-avail] would not block or when the port contains
|
||||||
|
buffered characters and @racket[write-bytes-avail*] can flush part of
|
||||||
|
the buffer (although @racket[write-bytes-avail] might block). A value
|
||||||
|
that can act as both an input port and an output port acts as an input
|
||||||
|
port for a @tech{synchronizable event}. @ResultItself{port}.
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
|
|
||||||
@local-table-of-contents[]
|
@local-table-of-contents[]
|
||||||
|
|
|
@ -16,8 +16,10 @@ is @defterm{fair}: if a thread is blocked on a semaphore and the
|
||||||
semaphore's internal value is non-zero infinitely often, then the
|
semaphore's internal value is non-zero infinitely often, then the
|
||||||
thread is eventually unblocked.
|
thread is eventually unblocked.
|
||||||
|
|
||||||
In addition to its use with semaphore-specific procedures, semaphores
|
In addition to its use with semaphore-specific procedures, a semaphore
|
||||||
can be used as events; see @secref["sync"].
|
can be used as a @tech{synchronizable event} (see @secref["sync"]).
|
||||||
|
A semaphore is @tech{ready for synchronization} when
|
||||||
|
@racket[semaphore-wait] would not block; @resultItself{semaphore}.
|
||||||
|
|
||||||
@defproc[(semaphore? [v any/c]) boolean?]{
|
@defproc[(semaphore? [v any/c]) boolean?]{
|
||||||
|
|
||||||
|
@ -57,9 +59,11 @@ called, then either the semaphore's counter is decremented or the
|
||||||
@racket[exn:break] exception is raised, but not both.}
|
@racket[exn:break] exception is raised, but not both.}
|
||||||
|
|
||||||
@defproc[(semaphore-peek-evt [sema semaphore?]) semaphore-peek-evt?]{Creates and
|
@defproc[(semaphore-peek-evt [sema semaphore?]) semaphore-peek-evt?]{Creates and
|
||||||
returns a new synchronizable event (for use with @racket[sync], for
|
returns a new @tech{synchronizable event} (for use with @racket[sync], for
|
||||||
example) that is ready when @racket[sema] is ready, but synchronizing
|
example) that is @tech{ready for synchronization} when @racket[sema] is ready,
|
||||||
the event does not decrement @racket[sema]'s internal count.}
|
but synchronizing
|
||||||
|
the event does not decrement @racket[sema]'s internal count.
|
||||||
|
@ResultItself{semaphore-peek event}.}
|
||||||
|
|
||||||
@defproc[(semaphore-peek-evt? [v any/c]) boolean?]{
|
@defproc[(semaphore-peek-evt? [v any/c]) boolean?]{
|
||||||
Returns @racket[#t] if @racket[v] is a semaphore wrapper produced by
|
Returns @racket[#t] if @racket[v] is a semaphore wrapper produced by
|
||||||
|
|
|
@ -416,9 +416,10 @@ like @racket[peek-bytes-avail!].}
|
||||||
(current-input-port)])
|
(current-input-port)])
|
||||||
progress-evt?]{
|
progress-evt?]{
|
||||||
|
|
||||||
Returns a @tech{synchronizable event} that becomes ready after any
|
Returns a @tech{synchronizable event} (see @secref["sync"]) that
|
||||||
subsequent read from @racket[in] or after @racket[in] is
|
becomes @tech{ready for synchronization} after any subsequent read
|
||||||
closed. After the event becomes ready, it remains ready.}
|
from @racket[in] or after @racket[in] is closed. After the event
|
||||||
|
becomes ready, it remains ready. @ResultItself{progress event}.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(port-provides-progress-evts? [in input-port?]) boolean]{
|
@defproc[(port-provides-progress-evts? [in input-port?]) boolean]{
|
||||||
|
|
|
@ -65,7 +65,7 @@ The @racket[subprocess] procedure returns four values:
|
||||||
|
|
||||||
@itemize[
|
@itemize[
|
||||||
|
|
||||||
@item{a subprocess value representing the created process;}
|
@item{a @deftech{subprocess} value representing the created process;}
|
||||||
|
|
||||||
@item{an input port piped from the process's standard output, or
|
@item{an input port piped from the process's standard output, or
|
||||||
@racket[#f] if @racket[stdout-output-port] was a port;}
|
@racket[#f] if @racket[stdout-output-port] was a port;}
|
||||||
|
@ -99,7 +99,11 @@ and see @racket[subprocess-group-enabled] for additional caveats.
|
||||||
The @racket[current-subprocess-custodian-mode] parameter determines
|
The @racket[current-subprocess-custodian-mode] parameter determines
|
||||||
whether the subprocess itself is registered with the current
|
whether the subprocess itself is registered with the current
|
||||||
@tech{custodian} so that a custodian shutdown calls
|
@tech{custodian} so that a custodian shutdown calls
|
||||||
@racket[subprocess-kill] for the subprocess.}
|
@racket[subprocess-kill] for the subprocess.
|
||||||
|
|
||||||
|
A subprocess can be used as a @tech{synchronizable event} (see @secref["sync"]).
|
||||||
|
A subprocess value is @tech{ready for synchronization} when
|
||||||
|
@racket[subprocess-wait] would not block; @resultItself{subprocess value}.}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(subprocess-wait [subproc subprocess?]) void?]{
|
@defproc[(subprocess-wait [subproc subprocess?]) void?]{
|
||||||
|
|
|
@ -23,6 +23,10 @@ an internal semaphore when its event queue is empty. Thus, the handler
|
||||||
thread is collectible when the eventspace is unreachable and contains
|
thread is collectible when the eventspace is unreachable and contains
|
||||||
no visible windows or running timers.}
|
no visible windows or running timers.}
|
||||||
|
|
||||||
|
A thread can be used as a @tech{synchronizable event} (see
|
||||||
|
@secref["sync"]). A thread is @tech{ready for synchronization} when
|
||||||
|
@racket[thread-wait] would not block; @resultItself{thread}.
|
||||||
|
|
||||||
All constant-time procedures and operations provided by Racket are
|
All constant-time procedures and operations provided by Racket are
|
||||||
thread-safe because they are @defterm{atomic}. For example,
|
thread-safe because they are @defterm{atomic}. For example,
|
||||||
@racket[set!] assigns to a variable as an atomic action with respect
|
@racket[set!] assigns to a variable as an atomic action with respect
|
||||||
|
@ -199,34 +203,35 @@ breaking is enabled; see @secref["breakhandler"]).}
|
||||||
@defproc[(thread-dead-evt [thd thread?]) evt?]{
|
@defproc[(thread-dead-evt [thd thread?]) evt?]{
|
||||||
|
|
||||||
Returns a @tech{synchronizable event} (see @secref["sync"]) that is
|
Returns a @tech{synchronizable event} (see @secref["sync"]) that is
|
||||||
ready if and only if @racket[thd] has terminated. Unlike using
|
@tech{ready for synchronization} if and only if @racket[thd] has terminated. Unlike using
|
||||||
@racket[thd] directly, however, a reference to the event does not
|
@racket[thd] directly, however, a reference to the event does not
|
||||||
prevent @racket[thd] from being garbage collected (see
|
prevent @racket[thd] from being garbage collected (see
|
||||||
@secref["gc-model"]). For a given @racket[thd],
|
@secref["gc-model"]). For a given @racket[thd],
|
||||||
@racket[thread-dead-evt] always returns the same (i.e., @racket[eq?])
|
@racket[thread-dead-evt] always returns the same (i.e., @racket[eq?])
|
||||||
result.}
|
result .@ResultItself{thread-dead event}.}
|
||||||
|
|
||||||
@defproc[(thread-resume-evt [thd thread?]) evt?]{
|
@defproc[(thread-resume-evt [thd thread?]) evt?]{
|
||||||
|
|
||||||
Returns a @tech{synchronizable event} (see @secref["sync"]) that
|
Returns a @tech{synchronizable event} (see @secref["sync"]) that
|
||||||
becomes ready when @racket[thd] is running. (If @racket[thd] has
|
becomes @tech{ready for synchronization} when @racket[thd] is running. (If @racket[thd] has
|
||||||
terminated, the event never becomes ready.) If @racket[thd] runs and
|
terminated, the event never becomes ready.) If @racket[thd] runs and
|
||||||
is then suspended after a call to @racket[thread-resume-evt], the
|
is then suspended after a call to @racket[thread-resume-evt], the
|
||||||
result event remains ready; after each suspend of @racket[thd] a fresh
|
result event remains ready; after each suspend of @racket[thd] a fresh
|
||||||
event is generated to be returned by @racket[thread-resume-evt]. The
|
event is generated to be returned by @racket[thread-resume-evt]. The
|
||||||
result of the event is @racket[thd], but if @racket[thd] is never
|
result of the event is @racket[thd], but if @racket[thd] is never
|
||||||
resumed, then reference to the event does not prevent @racket[thd]
|
resumed, then reference to the event does not prevent @racket[thd]
|
||||||
from being garbage collected (see @secref["gc-model"]).}
|
from being garbage collected (see @secref["gc-model"]).
|
||||||
|
@ResultItself{thread-result event}.}
|
||||||
|
|
||||||
@defproc[(thread-suspend-evt [thd thread?]) evt?]{
|
@defproc[(thread-suspend-evt [thd thread?]) evt?]{
|
||||||
|
|
||||||
Returns a @tech{synchronizable event} (see @secref["sync"]) that
|
Returns a @tech{synchronizable event} (see @secref["sync"]) that
|
||||||
becomes ready when @racket[thd] is suspended. (If @racket[thd] has
|
becomes @tech{ready for synchronization} when @racket[thd] is suspended. (If @racket[thd] has
|
||||||
terminated, the event will never unblock.) If @racket[thd] is
|
terminated, the event will never unblock.) If @racket[thd] is
|
||||||
suspended and then resumes after a call to
|
suspended and then resumes after a call to
|
||||||
@racket[thread-suspend-evt], the result event remains ready; after
|
@racket[thread-suspend-evt], the result event remains ready; after
|
||||||
each resume of @racket[thd] created a fresh event to be returned by
|
each resume of @racket[thd] created a fresh event to be returned by
|
||||||
@racket[thread-suspend-evt].}
|
@racket[thread-suspend-evt]. @ResultItself{thread-suspend event}.}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section[#:tag "threadmbox"]{Thread Mailboxes}
|
@section[#:tag "threadmbox"]{Thread Mailboxes}
|
||||||
|
@ -263,8 +268,8 @@ or returns @racket[#f] immediately if no message is available.}
|
||||||
@defproc[(thread-receive-evt) evt?]{
|
@defproc[(thread-receive-evt) evt?]{
|
||||||
|
|
||||||
Returns a constant @tech{synchronizable event} (see @secref["sync"])
|
Returns a constant @tech{synchronizable event} (see @secref["sync"])
|
||||||
that becomes ready when the synchronizing thread has a message to
|
that becomes @tech{ready for synchronization} when the synchronizing thread has a message to
|
||||||
receive. The event result is the event itself.}
|
receive. @ResultItself{thread-receive event}.}
|
||||||
|
|
||||||
@defproc[(thread-rewind-receive [lst list?]) void?]{
|
@defproc[(thread-rewind-receive [lst list?]) void?]{
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user