racket/pkgs/racket-doc/scribblings/reference/plumbers.scrbl
2017-02-22 23:20:12 -05:00

106 lines
3.6 KiB
Racket

#lang scribble/doc
@(require "mz.rkt")
@title[#:tag "plumbers"]{Plumbers}
A @deftech{plumber} supports @deftech{flush callbacks}, which are
normally triggered just before a Racket process or @tech{place} exits.
For example, a @tech{flush callback} might flush an output port's
buffer.@margin-note{@tech{Flush callbacks} are roughly analogous to the standard C
library's @as-index{@tt{atexit}}, but flush callback can also be used in other,
similar scenarios.}
There is no guarantee that a flush callback will be called before a
process terminates---either because the plumber is not the original
plumber that is flushed by the default @tech{exit handler}, or because
the process is terminated forcibly (e.g., through a custodian
shutdown).
@defproc[(plumber? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a @tech{plumber} value,
@racket[#f] otherwise.
@history[#:added "6.0.1.8"]}
@defproc[(make-plumber) plumber?]{
Creates a new @tech{plumber}.
Plumbers have no hierarchy (unlike @tech{custodians} or
@tech{inspectors}), but a @tech{flush callback} can be registered in
one plumber to call @racket[plumber-flush-all] with another plumber.
@history[#:added "6.0.1.8"]}
@defparam[current-plumber plumber plumber?]{
A @tech{parameter} that determines a @deftech{current plumber} for
@tech{flush callbacks}. For example, creating an output @tech{file
stream port} registers a @tech{flush callback} with the @tech{current
plumber} to flush the port as long as the port is opened.
@history[#:added "6.0.1.8"]}
@defproc[(plumber-flush-all [plumber plumber?]) void?]{
Calls all @tech{flush callbacks} that are registered with @racket[plumber].
The @tech{flush callbacks} to call are collected from @racket[plumber]
before the first one is called. If a @tech{flush callback} registers a
new @tech{flush callback}, the new one is @emph{not} called. If a
@tech{flush callback} raises an exception or otherwise escapes, then
the remaining @tech{flush callbacks} are not called.
@history[#:added "6.0.1.8"]}
@defproc[(plumber-flush-handle? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a @deftech{flush handle}
represents the registration of a @tech{flush callback}, @racket[#f]
otherwise.
@history[#:added "6.0.1.8"]}
@defproc[(plumber-add-flush! [plumber plumber?]
[proc (plumber-flush-handle? . -> . any)]
[weak? any/c #f])
plumber-flush-handle?]{
Registers @racket[proc] as a @tech{flush callback} with @racket[plumber], so
that @racket[proc] is called when @racket[plumber-flush-all] is
applied to @racket[plumber].
The result @tech{flush handle} represents the registration of the
callback, and it can be used with @racket[plumber-flush-handle-remove!] to
unregister the callback.
The given @racket[proc] is reachable from the @tech{flush handle}, but
if @racket[weak?] is true, then @racket[plumber] retains only a
@tech{weak reference} to the result @tech{flush handle} (and
thus @racket[proc]).
When @racket[proc] is called as a @tech{flush callback}, it is passed
the same value that is returned by @racket[plumber-add-flush!] so
that @racket[proc] can conveniently unregister itself. The call of
@racket[proc] is within a @tech{continuation barrier}.
@history[#:added "6.0.1.8"]}
@defproc[(plumber-flush-handle-remove! [handle plumber-flush-handle?]) void?]{
Unregisters the @tech{flush callback} that was registered by the
@racket[plumber-add-flush!] call that produced @racket[handle].
If the registration represented by @racket[handle] has been removed already,
then @racket[plumber-flush-handle-remove!] has no effect.
@history[#:added "6.0.1.8"]}