gauche.selector- Simple dispatcher
This module provides a simple interface to dispatch I/O events to
registered handlers, based on
sys-select (see I/O multiplexing).
A dispatcher instance that keeps watching I/O ports with associated
handlers. A new instance can be created by
Add a handler proc to the selector. proc is called when port-or-fd, which should be a port object or an integer that specifies a system file descriptor, meets a certain condition specified by flags. flags must be a list of one or more of the following symbols.
Calls proc when data is available at port-or-fd to read.
Calls proc when port-or-fd is ready to be written.
Calls proc when an exceptional condition occurs on port-or-fd.
proc is called with two arguments. The first one is port-or-fd
itself, and the second one is a symbol
indicating the condition.
If a handler is already associated with port-or-fd under the same condition, the previous handler is replaced by proc.
Deletes the handler entries that matches port-or-fd, proc
and flags. One or more of the arguments may be
meaning “don’t care”. For example,
(selector-delete! selector the-port #f #f)
deletes all the handlers associated to the-port, and
(selector-delete! selector #f #f '(w))
deletes all the handlers waiting for writable condition.
Dispatcher body. Waits for the conditions registered in self, and when it occurs, calls the associated handler. If the timeout argument is omitted or false, this method waits indefinitely. Alternatively you can give a timeout value, that can be a real number in microseconds, or a list of two integers that represents seconds and microseconds.
Returns the number of handlers called. Zero means the selector has been timed out.
It is safe to modify self inside handler. The change will be
effective from the next call of
This is a simple example of "echo" server:
(use gauche.net) (use gauche.selector) (use gauche.uvector) (define (echo-server port) (let ((selector (make <selector>)) (server (make-server-socket 'inet port :reuse-addr? #t))) (define (accept-handler sock flag) (let* ((client (socket-accept server)) (output (socket-output-port client))) (selector-add! selector (socket-input-port client :buffering #f) (lambda (input flag) (echo client input output)) '(r)))) (define (echo client input output) (let ((str (read-uvector <u8vector> 4096 input))) (if (eof-object? str) (begin (selector-delete! selector input #f #f) (socket-close client)) (begin (write-uvector str output) (flush output))))) (selector-add! selector (socket-fd server) accept-handler '(r)) (do () (#f) (selector-select selector))))