  
  [1X9 I/O multiplexing[0X
  
  
  [1X9.1 Introduction[0X
  
  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 [5XGAP[0m language one has to use
  [2XIO_select[0m  ([14X3.2-51[0m)  and  some buffering and queueing to organise this. This
  chapter  describes  a  relative  generic  implementation of I/O-multiplexing
  using  so-called  [2XIOHub[0m  ([14X9.2-1[0m)  objects.  The  basic idea is that an [2XIOHub[0m
  ([14X9.2-1[0m)  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 [2XIOHub[0m ([14X9.2-1[0m),
  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 [2XDoIO[0m ([14X9.2-13[0m), when called
  often enough, will then make sure that the message is sent away eventually.
  
  
  [1X9.2 The operations for [10XIOHub[1X objects[0X
  
  In  this section, we simply describe the functions and operations to create,
  use and destroy [2XIOHub[0m ([14X9.2-1[0m) objects.
  
  [1X9.2-1 IOHub[0m
  
  [2X> IOHub( [0X[3X[0X[2X ) _______________________________________________________[0Xoperation
  [6XReturns:[0X  an [2XIOHub[0m object
  
  This creates a new [2XIOHub[0m object at first without any open connections.
  
  [1X9.2-2 NewConnection[0m
  
  [2X> NewConnection( [0X[3Xh, i, o[0X[2X ) ________________________________________[0Xoperation
  [6XReturns:[0X  a positive integer
  
  This  operation  adds  a  new  connection to the [2XIOHub[0m ([14X9.2-1[0m) object [3Xh[0m. The
  arguments  [3Xi[0m and [3Xo[0m must be Unix file descriptors or 0 and [3Xi[0m must be open for
  reading  if it is positive and [3Xo[0m 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 [2XIOHub[0m ([14X9.2-1[0m)
  object. Note that this number is specific to the object [3Xh[0m.
  
  From the moment these file descriptors are registered with the [2XIOHub[0m ([14X9.2-1[0m)
  object,  every  subsequent  call  to  [2XDoIO[0m ([14X9.2-13[0m) 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
  [2XIOHub[0m ([14X9.2-1[0m) object on the other side at the same time.
  
  See also [2XNewTCPConnection[0m ([14X9.2-10[0m) below.
  
  [1X9.2-3 CloseConnection[0m
  
  [2X> CloseConnection( [0X[3Xh, nr[0X[2X ) ________________________________________[0Xoperation
  [6XReturns:[0X  nothing
  
  The  argument  [3Xh[0m  must  be  an  [2XIOHub[0m  ([14X9.2-1[0m) object and [3Xnr[0m the number of a
  connection  which  was  previously  returned  by  [2XNewConnection[0m ([14X9.2-2[0m). The
  corresponding connection is closed and removed from the [2XIOHub[0m ([14X9.2-1[0m).
  
  [1X9.2-4 AttachServingSocket[0m
  
  [2X> AttachServingSocket( [0X[3Xh, addr, port[0X[2X ) ____________________________[0Xoperation
  [6XReturns:[0X  a Unix file descriptor or [9Xfail[0m
  
  The  argument  [3Xh[0m must be an [2XIOHub[0m ([14X9.2-1[0m) object, [3Xaddr[0m an IP address or host
  name  as  a  string  and  [3Xport[0m  a port number (see also [2XIO_MakeIPAddressPort[0m
  ([14X4.3-6[0m)).  This  operation  creates a new socket, binds it to the IP address
  and  port  and  attaches it to the [2XIOHub[0m ([14X9.2-1[0m) object. From this moment on
  the operation [2XDoIO[0m ([14X9.2-13[0m) will accept new bidirectional TCP/IP connections
  on  that  socket  and  add  them to [3Xh[0m. The operation returns either the file
  descriptor of the new socket or [9Xfail[0m if an error occurred.
  
  [1X9.2-5 ShutdownServingSocket[0m
  
  [2X> ShutdownServingSocket( [0X[3Xh[0X[2X ) ______________________________________[0Xoperation
  [6XReturns:[0X  nothing
  
  The  argument [3Xh[0m must be an [2XIOHub[0m ([14X9.2-1[0m) object. Any server socket which was
  attached to [3Xh[0m is shut down, so no new connections will be accepted.
  
  [1X9.2-6 Shutdown[0m
  
  [2X> Shutdown( [0X[3Xh[0X[2X ) ___________________________________________________[0Xoperation
  [6XReturns:[0X  nothing
  
  The argument [3Xh[0m must be an [2XIOHub[0m ([14X9.2-1[0m) object. All connections of [3Xh[0m will be
  closed  using  [2XCloseConnection[0m  ([14X9.2-3[0m)  and any serving socket will be shut
  down  using [2XShutdownServingSocket[0m ([14X9.2-5[0m). The [2XIOHub[0m ([14X9.2-1[0m) object will not
  be usable any more after this call.
  
  [1X9.2-7 AcceptNewConnection[0m
  
  [2X> AcceptNewConnection( [0X[3Xh[0X[2X ) ________________________________________[0Xoperation
  [6XReturns:[0X  a positive integer or [9Xfail[0m
  
  The  argument  [3Xh[0m  must  be an [2XIOHub[0m ([14X9.2-1[0m) object. The object [3Xh[0m must have a
  serving  socket  attached  to  it via [2XAttachServingSocket[0m ([14X9.2-4[0m), otherwise
  [9Xfail[0m  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  [2XIOHub[0m  ([14X9.2-1[0m)  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
  [2XDoIO[0m  ([14X9.2-13[0m)  whenever  a new connection has come in, which is reported in
  the  internal  [2XIO_select[0m ([14X3.2-51[0m) call. So usually, the client code does not
  have to call this operation at all.
  
  [1X9.2-8 SubmitOutput[0m
  
  [2X> SubmitOutput( [0X[3Xh, nr, st[0X[2X ) _______________________________________[0Xoperation
  [6XReturns:[0X  [9Xtrue[0m or [9Xfail[0m
  
  The  argument  [3Xh[0m  must  be  an  [2XIOHub[0m  ([14X9.2-1[0m) object, [3Xnr[0m must be a positive
  integer which is the number of an open connection of [3Xh[0m which can be used for
  output.  The  argument  [3Xst[0m  must be a [5XGAP[0m string. This operation appends the
  message  [3Xst[0m  to the end of the output queue for the connection [3Xnr[0m. Note that
  at this stage no output is actually performed automatically. One has to call
  [2XDoIO[0m ([14X9.2-13[0m) subsequently to actually send the message away.
  
  [1X9.2-9 GetInput[0m
  
  [2X> GetInput( [0X[3Xh, nr[0X[2X ) _______________________________________________[0Xoperation
  [6XReturns:[0X  a list of length 2
  
  The argument [3Xh[0m must be an [2XIOHub[0m ([14X9.2-1[0m) object, [3Xnr[0m must be an integer. If [3Xnr[0m
  is  positive,  this operation returns the earliest message which has come in
  from  connection number [3Xnr[0m and has not yet been returned by [2XGetInput[0m before.
  This  message  is  then  removed  from  the input queue. If there is no such
  message,  then  [9Xfalse[0m  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 [3Xnr[0m is equal to 0
  then the first message in the input queue from any connection is returned or
  [9Xfalse[0m if there is no message in the input queue.
  
  [1X9.2-10 NewTCPConnection[0m
  
  [2X> NewTCPConnection( [0X[3Xh, addr, port[0X[2X ) _______________________________[0Xoperation
  [6XReturns:[0X  a connection number or [9Xfail[0m
  
  The  argument [3Xh[0m must be an [2XIOHub[0m ([14X9.2-1[0m) object, the arguments [3Xaddr[0m and [3Xport[0m
  must  be  an  address/port  pair as used in [2XIO_MakeIPAddressPort[0m ([14X4.3-6[0m), so
  [3Xaddress[0m  can  either  be  a  host  name  or an IP address and [3Xport[0m is a port
  number.  This  operation  opens a new TCP connection to the address and port
  specified,  adds a new bidirectional connection to the [2XIOHub[0m ([14X9.2-1[0m) [3Xh[0m using
  [2XNewConnection[0m  ([14X9.2-2[0m)  and  returns  the  connection number specific to the
  object [3Xh[0m. If anything goes wrong, [9Xfail[0m is returned.
  
  [1X9.2-11 OutputQueue[0m
  
  [2X> OutputQueue( [0X[3Xh[0X[2X ) ________________________________________________[0Xoperation
  [6XReturns:[0X  a list
  
  The  argument  [3Xh[0m  must be an [2XIOHub[0m ([14X9.2-1[0m) 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.
  
  [1X9.2-12 InputQueue[0m
  
  [2X> InputQueue( [0X[3Xh[0X[2X ) _________________________________________________[0Xoperation
  [6XReturns:[0X  a list
  
  The  argument  [3Xh[0m  must be an [2XIOHub[0m ([14X9.2-1[0m) 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.
  
  [1X9.2-13 DoIO[0m
  
  [2X> DoIO( [0X[3Xh[, block][0X[2X ) ______________________________________________[0Xoperation
  [6XReturns:[0X  [9Xtrue[0m or [9Xfalse[0m or [9Xfail[0m
  
  The  argument  [3Xh[0m  must  be  an [2XIOHub[0m ([14X9.2-1[0m) object, and the optional second
  argument [3Xblock[0m must be [9Xtrue[0m or [9Xfalse[0m. This operation uses [2XIO_select[0m ([14X3.2-51[0m)
  to  decide  which  of the file descriptors belonging to the connections of [3Xh[0m
  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 [2XDoIO[0m
  loops  until no more file descriptors are ready. It returns [9Xtrue[0m if some I/O
  was  performed  and  [9Xfalse[0m  if  not. It returns [9Xfail[0m if the [2XIOHub[0m ([14X9.2-1[0m) is
  already  shut  down. The second argument [3Xblock[0m indicates whether or not [2XDoIO[0m
  should  block  until  some  I/O has taken place. If this argument is omitted
  then [9Xfalse[0m (non-blocking operation) is the default.
  
  Note that broken connections are silently closed.
  
  
  [1X9.3 Examples[0X
  
  There is an example hash server in the file [11Xexamples/hashserver.g[0m.
  
