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).
{gauche.selector
}
A dispatcher instance that keeps watching I/O ports with associated
handlers. A new instance can be created by make
method.
{gauche.selector
}
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.
r
Calls proc when data is available at port-or-fd to read.
w
Calls proc when port-or-fd is ready to be written.
x
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 r
, w
or x
,
indicating the condition.
If a handler is already associated with port-or-fd under the same condition, the previous handler is replaced by proc.
{gauche.selector
}
Deletes the handler entries that matches port-or-fd, proc
and flags. One or more of the arguments may be #f
,
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.
{gauche.selector
}
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 selector-select
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))))