
         GENERAL INFORMATION AND FILES
         ------------------------------

              The ZIP file PIPE.ZIP contains all the source and executables
         for a sample named pipe server which dynamically creates threads.
         This source code is provided for instructional purposes only and
         should not be used in any sort of production environment.

              PIPESRV.EXE is an executable for the named pipe server
         obtained by compiling and linking PIPESRV.CPP. CLIENT.EXE is the
         client side of the named pipe server obtained by compiling and
         linking CLIENT.CPP.
              If you are using Borland C++ for OS/2, both CLIENT.CPP and
         PIPESRV.CPP can be compiled and linked using m.cmd.

         USING DIFFERENT COMPILERS
         -------------------------

              All source code was written and tested using Borland C++ for
         OS/2 2.0.  However, the source can be changed to work with IBM C
         SET/2 or other compiler without major modifications. For IBM C
         SET/2, the calls the "_beginthread" will have to be changed to
         accomodate the differences in the "_beginthread" function for that
         compiler. Otherwise, other functions are either standard "C"
         functions or are OS/2 API functions.
              Unfortunately, the beginthread call is necessary to use the
         Borland C++ library in a multithreaded environment.

         PROGRAM LIMITATIONS
         -------------------

              The astute coder should note the following limitations of the
         code, all of which reflect the fact that this is an example
         program.

              (1) The pipe handle is stored in the "usKey" element of the
         PIPESEMSTATE structure.  However, the pipe handle takes 4 bytes
         and "usKey" is only two bytes.  There is no guarantee that after
         multiple executions of the client that the pipe handle will be
         able to fit into a two byte value.
              The way to change this is to let "usKey" be an index to an
         array of pipe handles which is filled when DosCreateNPipe returns
         succesfully and from which elements are removed when
         DosDisconnectNPipe is called.

              (2) If too many multiple clients are used simulataneously,
         then errors will occur because the pipe server may not be fast
         enough to always have a pipe handle which is waiting to be
         connected (via DosConnectNPipe).
              The way to get around this is to maintain a minimum number of
         threads which are blocked on DosConnectNPipe except under
         unusually heavy usage conditions where this may be impossible.

               (3) Error checking here is relatively poor, as the only
         response to an error by the pipe server is to terminate the
         program. In a real-world environment, the coder would have to be
         more judicious as to the severity of errors.
