MUX(3)                                                     MUX(3)

     NAME
          Mux, muxinit, muxrpc, muxthreads - protocol multiplexor

     SYNOPSIS
          #include <mux.h>

          struct Mux
          {
              uint mintag;
              uint maxtag;
              int (*settag)(Mux *mux, void *msg, uint tag);
              int (*gettag)(Mux *mux, void *msg);
              int (*send)(Mux *mux, void *msg);
              void *(*recv)(Mux *mux);
              void *(*nbrecv)(Mux *mux);
              void *aux;

              ...   /* private fields follow */
          };

          void  muxinit(Mux *mux);

          void* muxrpc(Mux *mux, void *request);

          void  muxprocs(Mux *mux);

          Muxrpc*muxrpcstart(Mux *mux, void *request);

          void* muxrpccanfinish(Muxrpc *rpc);

     DESCRIPTION
          Libmux is a generic protocol multiplexor.  A client program
          initializes a Mux structure with information about the pro-
          tocol (mainly in the form of helper functions) and can then
          use muxrpc to execute individual RPCs without worrying about
          details of multiplexing requests and demultiplexing
          responses.

          Libmux assumes that the protocol messages contain a tag (or
          message ID) field that exists for the sole purpose of demul-
          tiplexing messages.  Libmux chooses the tags and then calls
          a helper function to put them in the outgoing messages.
          Libmux calls another helper function to retrieve tags from
          incoming messages.  It also calls helper functions to send
          and receive packets.

          A client should allocate a Mux structure and then call
          muxinit to initialize the library's private elements.  The
          client must initialize the following elements:

     MUX(3)                                                     MUX(3)

          mintag, maxtag
               The range of valid tags; maxtag is the maximum valid
               tag plus one, so that maxtag-mintag is equal to the
               number of valid tags.  If libmux runs out of tags (all
               tags are being used for RPCs currently in progress), a
               new call to muxrpc will block until an executing call
               finishes.

          settag, gettag
               Set or get the tag value in a message.

          send, recv, nbrecv
               Send or receive protocol messages on the connection.
               Recv should block until a message is available and
               should return nil if the connection is closed.  Nbrecv
               should not block; it returns nil if there is no message
               available to be read.  Libmux will arrange that only
               one call to recv or nbrecv is active at a time.

          aux  An auxiliary pointer for use by the client.  Once a
               client has initialized the Mux structure, it can call
               muxrpc to execute RPCs.  The request is the message
               passed to settag and send. The return value is the
               response packet, as provided by recv, or nil if an
               error occurred.  Muxprocs allocates new procs (see
               thread(3)) in which to run send and recv. After a call
               to muxprocs, muxrpc will run send and recv in these
               procs instead of in the calling proc.  This is useful
               if the implementation of either (particularly recv)
               blocks an entire proc and there are other threads in
               the calling proc that need to remain active.

          Libmux also provides a non-blocking interface, useful for
          programs forced to use a select(2)-based main loop.
          Muxrpcstart runs the first half of muxrpc: it assigns a tag
          and sends the request, but does not wait for the reply.
          Instead it returns a pointer to a Muxrpc structure that rep-
          resents the in-progress call.  Muxrpccanfinish checks
          whether the given call can finish.  If no mux procs have
          been started, muxrpccanfinish may call nbrecv to poll for
          newly arrived responses.

     EXAMPLE
          See /src/lib9pclient/fs.c for an example of using libmux
          with 9P (see intro(9p)).

     SOURCE
          /src/libmux

     SEE ALSO
          thread(3), intro(9p)

     MUX(3)                                                     MUX(3)

     BUGS
          Libmux does not know how to free protocol messages, so mes-
          sage arriving with unexpected or invalid tags are leaked.