Whenever one needs to do input/output on more than one connection (file descriptor) at a time, some code is needed to organise the I/O multiplexing. Due to the single-threaded nature of the current GAP language one has to use IO_select
(3.2-55) and some buffering and queueing to organise this. This chapter describes a relative generic implementation of I/O-multiplexing using so-called IOHub
(9.2-1) objects. The basic idea is that an IOHub
(9.2-1) object handles lots of I/O connections at the same time and maintains a buffer for each of them. There is a very simple protocol that marks chunks of data (called "messages") and whenever a message has been received completely it is collected in the input queue of the IOHub
(9.2-1), marked with the number of the connection it came from. Rather than sending a message away in one go, one would always schedule it for sending by appending it to the output queue. The operation DoIO
(9.2-13), when called often enough, will then make sure that the message is sent away eventually.
IOHub
objectsIn this section, we simply describe the functions and operations to create, use and destroy IOHub
(9.2-1) objects.
‣ IOHub ( ) | ( operation ) |
Returns: an IOHub
object
This creates a new IOHub
object at first without any open connections.
‣ NewConnection ( h, i, o ) | ( operation ) |
Returns: a positive integer
This operation adds a new connection to the IOHub
(9.2-1) object h. The arguments i and o must be Unix file descriptors or \(0\) and i must be open for reading if it is positive and o must be open for writing if it is positive. It is allowed that both file descriptors are equal, but they may not both be equal to \(0\). The operation returns a positive integer which is the number under which this new connection will be administrated in the IOHub
(9.2-1) object. Note that this number is specific to the object h.
From the moment these file descriptors are registered with the IOHub
(9.2-1) object, every subsequent call to DoIO
(9.2-13) will try to do input and output on them. This means in particular that the other side of this connection should be in the same initial state of the protocol. Usually this will be achieved by them being added as a new connection to a corresponding IOHub
(9.2-1) object on the other side at the same time.
See also NewTCPConnection
(9.2-10) below.
‣ CloseConnection ( h, nr ) | ( operation ) |
Returns: nothing
The argument h must be an IOHub
(9.2-1) object and nr the number of a connection which was previously returned by NewConnection
(9.2-2). The corresponding connection is closed and removed from the IOHub
(9.2-1).
‣ AttachServingSocket ( h, addr, port ) | ( operation ) |
Returns: a Unix file descriptor or fail
The argument h must be an IOHub
(9.2-1) object, addr an IP address or host name as a string and port a port number (see also IO_MakeIPAddressPort
(4.3-6)). This operation creates a new socket, binds it to the IP address and port and attaches it to the IOHub
(9.2-1) object. From this moment on the operation DoIO
(9.2-13) will accept new bidirectional TCP/IP connections on that socket and add them to h. The operation returns either the file descriptor of the new socket or fail
if an error occurred.
‣ ShutdownServingSocket ( h ) | ( operation ) |
Returns: nothing
The argument h must be an IOHub
(9.2-1) object. Any server socket which was attached to h is shut down, so no new connections will be accepted.
‣ Shutdown ( h ) | ( operation ) |
Returns: nothing
The argument h must be an IOHub
(9.2-1) object. All connections of h will be closed using CloseConnection
(9.2-3) and any serving socket will be shut down using ShutdownServingSocket
(9.2-5). The IOHub
(9.2-1) object will not be usable any more after this call.
‣ AcceptNewConnection ( h ) | ( operation ) |
Returns: a positive integer or fail
The argument h must be an IOHub
(9.2-1) object. The object h must have a serving socket attached to it via AttachServingSocket
(9.2-4), otherwise fail
is returned and nothing happens. One more connection is accepted through the serving socket. It is added as a new bidirectional TCP/IP connection to the IOHub
(9.2-1) object and the new connection number is returned. Note first that this operation blocks until a new connection comes in. Note furthermore that this operation is usually called automatically in DoIO
(9.2-13) whenever a new connection has come in, which is reported in the internal IO_select
(3.2-55) call. So usually, the client code does not have to call this operation at all.
‣ SubmitOutput ( h, nr, st ) | ( operation ) |
Returns: true
or fail
The argument h must be an IOHub
(9.2-1) object, nr must be a positive integer which is the number of an open connection of h which can be used for output. The argument st must be a GAP string. This operation appends the message st to the end of the output queue for the connection nr. Note that at this stage no output is actually performed automatically. One has to call DoIO
(9.2-13) subsequently to actually send the message away.
‣ GetInput ( h, nr ) | ( operation ) |
Returns: a list of length \(2\)
The argument h must be an IOHub
(9.2-1) object, nr must be an integer. If nr is positive, this operation returns the earliest message which has come in from connection number nr and has not yet been returned by GetInput
before. This message is then removed from the input queue. If there is no such message, then false
is returned. A message is returned as a plain list of length \(2\) where the first entry is the connection number it came from and the second entry is a string containing the message itself. If nr is equal to \(0\) then the first message in the input queue from any connection is returned or false
if there is no message in the input queue.
‣ NewTCPConnection ( h, addr, port ) | ( operation ) |
Returns: a connection number or fail
The argument h must be an IOHub
(9.2-1) object, the arguments addr and port must be an address/port pair as used in IO_MakeIPAddressPort
(4.3-6), so address can either be a host name or an IP address and port is a port number. This operation opens a new TCP connection to the address and port specified, adds a new bidirectional connection to the IOHub
(9.2-1) h using NewConnection
(9.2-2) and returns the connection number specific to the object h. If anything goes wrong, fail
is returned.
‣ OutputQueue ( h ) | ( operation ) |
Returns: a list
The argument h must be an IOHub
(9.2-1) object. This returns the internal object for the output queue. Its elements are pairs where the first entry is the connection number where it is going to be sent and the second entry is the message as a string. Only modify this list if you really know what you are doing.
‣ InputQueue ( h ) | ( operation ) |
Returns: a list
The argument h must be an IOHub
(9.2-1) object. This returns the internal object for the input queue. Its elements are pairs where the first entry is the connection number from where the message was received and the second entry is the message as a string. Only modify this list if you really know what you are doing.
‣ DoIO ( h[, block] ) | ( operation ) |
Returns: true
or false
or fail
The argument h must be an IOHub
(9.2-1) object, and the optional second argument block must be true
or false
. This operation uses IO_select
(3.2-55) to decide which of the file descriptors belonging to the connections of h are ready to read or write. All file descriptors which are ready are served, possibly updating the input and output queues. A possible serving socket is also served accepting a new connection if there is one. The operation DoIO
loops until no more file descriptors are ready. It returns true
if some I/O was performed and false
if not. It returns fail
if the IOHub
(9.2-1) is already shut down. The second argument block indicates whether or not DoIO
should block until some I/O has taken place. If this argument is omitted then false
(non-blocking operation) is the default.
Note that broken connections are silently closed.
There is an example hash server in the file examples/hashserver.g
.
generated by GAPDoc2HTML