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:
Matthew Flatt 2012-12-24 21:02:37 -06:00
parent c162657685
commit b69573277c
15 changed files with 203 additions and 263 deletions

View File

@ -13,6 +13,17 @@
@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?]{
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
operation blocks when the channel has @racket[limit] items already.
If @racket[limit] is @racket[#f], the channel buffer has no limit (so
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.}
a put never blocks).}
@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])
evt?]{
Returns a @tech{synchronizable event} that is blocked while
@racket[(async-channel-put ach v)] would block. The unblock result is
the event itself. See also @racket[sync].}
Returns a @tech{synchronizable event} that is @tech{ready for
synchronization} when @racket[(async-channel-put ach v)] would return
a value (i.e., when the channel holds fewer values already than its
limit); @resultItself{asychronous channel-put event}.}
@defexamples[#:eval (async-eval)
(define (server input-channel output-channel)

View File

@ -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
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"].
@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?]{
Returns a fresh @tech{synchronizable event} for use with
@racket[sync]. The event is ready when @racket[(channel-put ch v)]
would not block, and the event's synchronization result is the event
itself.}
@racket[sync]. The event is @tech{ready for synchronization} when
@racket[(channel-put ch v)] would not block, and the event's
@tech{synchronization result} is the event itself.}
@defproc[(channel-put-evt? [v any/c]) boolean?]{

View File

@ -108,14 +108,16 @@ must be the same as @racket[limit-cust], so that excessively large
immediate allocations can be rejected with an
@racket[exn:fail:out-of-memory] exception.}
@defproc[(make-custodian-box [cust custodian?] [v any/c]) custodian-box?]{
Returns a @tech{custodian box} that contains @racket[v] as long as
@racket[cust] has not been shut down.
A @tech{custodian box} is a @tech{synchronizable event} for use with
functions like @racket[sync]. The @tech{custodian box} becomes ready
when its custodian is shut down.}
A @tech{custodian box} is a @tech{synchronizable event} (see @secref["sync"]).
The @tech{custodian box} becomes ready when its custodian is shut down;
@resultItself{@tech{custodian box}}.}
@defproc[(custodian-box? [v any/c]) boolean?]{Returns @racket[#t] if
@racket[v] is a @tech{custodian box} produced by

View File

@ -1,11 +1,6 @@
#lang scribble/doc
@(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}
@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
events.
At any point in time, an event is either @defterm{ready} for
synchronization, or it is not; depending on the kind of event and how
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
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
@ -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
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 @racket[prop:evt]).
@itemize[
@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].}
]
Racket values that act as @tech{synchronizable events} include
@tech{semaphores}, @tech{channels}, @tech{asynchronous channels},
@tech{ports}, @tech{TCP listeners}, @tech{threads},
@tech{subprocess}es, @tech{will executors}, and @tech{custodian
box}es. Libraries can define new synchronizable events, especially
though @racket[prop:evt].
@;------------------------------------------------------------------------
@ -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
@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?))]
[wrap (any/c . -> . any)])
evt?]{
Creates an event that is in a ready when @racket[evt] is ready, but
whose result is determined by applying @racket[wrap] to the result of
@racket[evt]. The call to @racket[wrap] is
Creates an event that is @tech{ready for synchronization} when
@racket[evt] is @tech{ready for synchronization}, but whose
@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[evt] cannot be an event created by @racket[handle-evt] or any
combination of @racket[choice-evt] involving an event from
@racket[handle-evt].}
@defproc[(handle-evt [evt (and/c evt? (not/c handle-evt?))]
[handle (any/c . -> . any)])
handle-evt?]{
Like @racket[wrap], except that @racket[handle] is called in tail
position with respect to the synchronization request, and without
Like @racket[wrap], except that @racket[handle] is called in @tech{tail
position} with respect to the synchronization request, and without
breaks explicitly disabled.}
@defproc[(guard-evt [generator (-> evt?)]) evt?]{
Creates a value that behaves as an event, but that is actually an
event generator. For details, see @elemref["guard-evt"]{the
overview}.}
event generator.
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?]{
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-const| value if the generated event was
not ultimately chosen. For details, see
@elemref["nack-guard-evt"]{the overview}.}
event generator.
An event @racket[_nack-guard] 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[_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?]{
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
@elemref["poll-guard-evt"]{the overview}.}
event generator.
@defthing[always-evt evt?]{A constant event that is always ready, with
itself as its result.}
An event @racket[_poll-guard]returned by @racket[poll-guard-evt]
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
the system is otherwise idle; see @elemref["system-idle-evt"]{the
overview} for more information. The result of the
@defthing[always-evt evt?]{A constant event that is always @tech{ready
for synchronization}, with itself as its @tech{synchronization result}.}
@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.}
@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
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
more than @racket[msecs].}
more than @racket[msecs]. @ResultItself{alarm event}.}
@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?]{
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:
@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
@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
@racket[prop:evt], @racket[prop:input-port], and
@racket[prop:output-port], then the @racket[prop:evt] value (if any)

View File

@ -228,9 +228,9 @@ descendants, as long as either @racket[name] is @racket[#f] or the
reporting logger's name matches @racket[name].
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
@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
for the event message, and an arbitrary value that was supplied as the
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
times, the @racket[level] provided with the last instance in the
argument list takes precedence.}

View File

@ -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
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?]{

View File

@ -143,3 +143,11 @@
(t "An " (racket id) " application can provide better performance for "
(elem what)
" 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))

View File

@ -60,7 +60,11 @@ listener}. This value can be used in future calls to
management of the current custodian (see @secref["custodians"]).
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?]
@ -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?]{
Returns a @tech{synchronizable event} (see @secref["sync"]) that is in
a blocking state when @racket[tcp-accept] on @racket[listener] would
block. If the event is chosen in a synchronization, the result is a
Returns a @tech{synchronizable event} (see @secref["sync"]) that is
@tech{ready for synchronization} when @racket[tcp-accept] on @racket[listener] would
not block. The @tech{synchronization result} is a
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
that is the current custodian (see @secref["custodians"]) at the time that
@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)])
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
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)],
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
unconnected, the @exnraise[exn:fail:network] during a synchronization
attempt.}
@ -560,11 +564,11 @@ attempt.}
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
evt?]{
Returns a @tech{synchronizable event}. The event is in a blocking
state when @racket[udp-receive] on @racket[udp-socket] would
Returns a @tech{synchronizable event}. The event is @tech{ready for synchronization}
when @racket[udp-receive] on @racket[udp-socket] would not
block. Otherwise, if the event is chosen in a synchronization, data is
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
@racket[udp-receive!]. (No bytes are received and the @racket[bstr]
content is not modified if the event is not chosen.)}

View File

@ -48,7 +48,11 @@ places that share the value, because they are allowed in a
@deftech{shared memory space}. See @racket[place-message-allowed?].
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
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?]{
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
port} to the ports in the place for @racket[p] (see

View File

@ -30,8 +30,9 @@ Returns @racket[#t] if the input or output port @racket[port] is
closed, @racket[#f] otherwise.}
@defproc[(port-closed-evt [port port?]) evt?]{
Return a @tech{synchronizable event} that becomes ready when @racket[port] is
closed.}
Return a @tech{synchronizable event} that becomes @tech{ready for
synchronization} when @racket[port] is
closed. @ResultItself{port-closed event}.}
@defparam[current-input-port in input-port?]{A @tech{parameter} that
determines a default input port for many operations, such as

View File

@ -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
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[]

View File

@ -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
thread is eventually unblocked.
In addition to its use with semaphore-specific procedures, semaphores
can be used as events; see @secref["sync"].
In addition to its use with semaphore-specific procedures, a semaphore
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?]{
@ -57,9 +59,11 @@ called, then either the semaphore's counter is decremented or the
@racket[exn:break] exception is raised, but not both.}
@defproc[(semaphore-peek-evt [sema semaphore?]) semaphore-peek-evt?]{Creates and
returns a new synchronizable event (for use with @racket[sync], for
example) that is ready when @racket[sema] is ready, but synchronizing
the event does not decrement @racket[sema]'s internal count.}
returns a new @tech{synchronizable event} (for use with @racket[sync], for
example) that is @tech{ready for synchronization} when @racket[sema] is ready,
but synchronizing
the event does not decrement @racket[sema]'s internal count.
@ResultItself{semaphore-peek event}.}
@defproc[(semaphore-peek-evt? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a semaphore wrapper produced by

View File

@ -416,9 +416,10 @@ like @racket[peek-bytes-avail!].}
(current-input-port)])
progress-evt?]{
Returns a @tech{synchronizable event} that becomes ready after any
subsequent read from @racket[in] or after @racket[in] is
closed. After the event becomes ready, it remains ready.}
Returns a @tech{synchronizable event} (see @secref["sync"]) that
becomes @tech{ready for synchronization} after any subsequent read
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]{

View File

@ -65,7 +65,7 @@ The @racket[subprocess] procedure returns four values:
@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
@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
whether the subprocess itself is registered with the current
@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?]{

View File

@ -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
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
thread-safe because they are @defterm{atomic}. For example,
@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?]{
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
prevent @racket[thd] from being garbage collected (see
@secref["gc-model"]). For a given @racket[thd],
@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?]{
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
is then suspended after a call to @racket[thread-resume-evt], the
result event remains ready; after each suspend of @racket[thd] a fresh
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
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?]{
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
suspended and then resumes after a call to
@racket[thread-suspend-evt], the result event remains ready; after
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}
@ -263,8 +268,8 @@ or returns @racket[#f] immediately if no message is available.}
@defproc[(thread-receive-evt) evt?]{
Returns a constant @tech{synchronizable event} (see @secref["sync"])
that becomes ready when the synchronizing thread has a message to
receive. The event result is the event itself.}
that becomes @tech{ready for synchronization} when the synchronizing thread has a message to
receive. @ResultItself{thread-receive event}.}
@defproc[(thread-rewind-receive [lst list?]) void?]{