Chapter 36

thread.ss: Thread Utilities

(consumer-thread f [init])      PROCEDURE

Returns two values: a thread descriptor for a new thread, and a procedure with the same arity as f.10 When the returned procedure is applied, its arguments are queued to be passed on to f, and void is immediately returned. The thread created by consumer-thread dequeues arguments and applies f to them, removing a new set of arguments from the queue only when the previous application of f has completed; if f escapes from a normal return (via an exception or a continuation), the f-applying thread terminates.

The init argument is a procedure of no arguments; if it is provided, init is called in the new thread immediately after the thread is created.

(copy-port input-port output-port ···1)      PROCEDURE

Reads data from input-port and writes it back out to output-port, returning when input-port produces eof. The copy is efficient, and without significant buffer delays (i.e., a character that becomes available on input-port is immediately transferred to output-port, even if future reads on input-port must block).

This function is often called from a ``background'' thread to continuously pump data from one stream to another.

If multiple output-ports are provided, case data from input-port is written to every output-port. The different output-ports block output to each other, because each quantum of data read from input-port is written completely to one output-port before moving to the next output-port. The output-ports are written in the provided order, so non-blocking ports (e.g., to a file) should be placed first in the argument list.

(dynamic-disable-break thunk)      PROCEDURE

Invokes thunk and returns the result. During the application of thunk, breaks are disabled.

(dynamic-enable-break thunk)      PROCEDURE

Invokes thunk and returns the result. During the application of thunk, breaks are enabled.

(make-limited-input-port input-port limit-k [close-orig?])      PROCEDURE

Returns a port whose content is drawn from input-port, but where an end-of-file is reported after limit-k characters are read. If close-orig? is true, then the original port is closed if the returned port is closed.

Characters are consumed from input-port only when they are consumed from the returned port. In particular, peeking into the returned port peeks into the original port.

If input-port is used directly while the resulting port is also used, then the limit-k characters provided by the port need not be contiguous parts of the original port's stream.

(make-single-threader)      PROCEDURE

Returns a new procedure that takes any thunk and applies it. When this procedure is applied to any collection of thunks by any collection of threads, the thunks are applied sequentially across all threads.

(merge-input a-input-port b-input-port [limit-k])      PROCEDURE

Accepts two input ports and returns a new input port. The new port merges the data from two original ports, so data can be read from the new port whenever it is available from either original port. The data from the original ports are interleaved. When EOF has been read from an original port, it no longer contributes characters to the new port. After EOF has been read from both original ports, the new port returns EOF. Closing the merged port does not close the original ports.

The optional limit-k argument limits the number of characters to be buffered from a-input-port and b-input-port, so that the merge process does not advance arbitrarily beyond the rate of consumption of the merged data. A #f value disables the limit; the default is 4096.

(run-server port-k session-proc session-timeout [handler-proc listen-proc close-proc accept-proc accept/break-proc])      PROCEDURE

Executes a TCP server on the port inidicated by port-k. When a connection is made by a client, session-proc is called with two values: an input port to receive from the client, and an output port to send to the client.

Each client connection, or session, is managed by a new custodian, and each call to session-proc occurs in a new thread (managed by the session's custodian). If the thread executing session-proc terminates for any reason (e.g., sesson-proc returns), the session's custodian is shut down. Consequently, session-proc need not close the ports provded to it. Breaks are enabled in the session thread if breaks are enabled when run-server is called.

If session-timeout is not #f, then it must be a non-negative number specifying the time in seconds that a session thread is allowed to run before it is sent a break signal. Then, if the thread runs longer than (* session-timeout 2) seconds, then the session's custodian is shut down. If session-timeout is #f, a session thread can run indefinitely.

If handler-proc is provided, it is passed exceptions related to connections (i.e., exceptions not caught by session-proc, or exceptions that occur when trying to accept a connection). The default handler ignores the exception and returns void.

The listen-proc, close-proc, accept-proc and accept/break-proc arguments default to the tcp-listen, tcp-close, tcp-accept, and tcp-accept/enable-break procedures, respectively. The run-server function calls these procedures without optional arguments. Provide alternate procedures to use an alternate communication protocol (such as SLL) or to supply optional arguments in the use of tcp-listen.

The run-server procedure loops to serve client connections, so it never returns. If a break occurs, the loop will cleanly shut down the server, but it will not terminate active sessions.

(with-semaphore s thunk)      PROCEDURE

Calls semaphore-wait on s, then invokes thunk with no arguments, and then calls semaphore-post on s. The return value is the result of calling thunk.


10 The returned procedure actually accepts any number of arguments, but immediately raises exn:application:arity if f cannot accept the provided number of arguments.