home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / LANMAN.ZIP / MAKEPIPE.C < prev    next >
C/C++ Source or Header  |  1991-01-01  |  7KB  |  164 lines

  1. /*-------------------------------------------------------------------
  2.   MAKEPIPE.C -- PBX pipe creation thread
  3.  
  4.   Description:
  5.  
  6.   This routine dynamically creates the named-pipes managed by PBX.
  7.   It will attempt to always keep available a minimum number of
  8.   unowned pipes for clients.  After creating a pipe, control of the
  9.   pipe is tranferred to the PipeMgr thread by associating the pipe
  10.   with the PipeMgr thread's pipe semaphore (via DosSetNmPipeSem).
  11.   When a pipe is closed or connected to by a client, this thread
  12.   needs to be notified by clearing the semMakePipe semaphore so
  13.   an additional pipe can be created.
  14.  
  15.   Author:  Brendan Dixon
  16.            Microsoft, inc.
  17.            LAN Manager Developer Support
  18.  
  19.   This code example is provided for demonstration purposes only.
  20.   Microsoft makes no warranty, either express or implied,
  21.   as to its usability in any given situation.
  22. -------------------------------------------------------------------*/
  23.  
  24. // Includes ---------------------------------------------------------
  25. #define   INCL_DOS
  26. #define   INCL_DOSERRORS
  27. #include  <os2.h>
  28.  
  29. #include  <lan.h>
  30.  
  31. #include  <errno.h>
  32. #include  <process.h>
  33. #include  <stddef.h>
  34. #include  <stdio.h>
  35. #include  <string.h>
  36.  
  37. #include  "pbxsrv.h"
  38.  
  39.  
  40. /* MakePipe ---------------------------------------------------------
  41.   Description:  See file header
  42.   Input      :  None
  43.   Output     :  None
  44. -------------------------------------------------------------------*/
  45. void _cdecl MakePipe(void)
  46. {
  47.   USHORT  usLinesNeeded;                  // Lines to create
  48.   USHORT  usLineNum;                      // Current line number
  49.   USHORT  usRetCode;                      // Return code
  50.  
  51.   for (;;) {
  52.     // Wait until more pipes need to be created
  53.     DosSemRequest(&(pbPBXMem->semMakePipe), SEM_INDEFINITE_WAIT);
  54.  
  55.     // Check for PBX shutdown
  56.     usRetCode = DosSemWait(&(pbPBXMem->semExit),
  57.                            SEM_IMMEDIATE_RETURN);
  58.     if (usRetCode)
  59.       break;
  60.  
  61.     // Check for PBX pause
  62.     DosSemWait(&(pbPBXMem->semPause), SEM_INDEFINITE_WAIT);
  63.  
  64.     // If all pipes have not been created and if the number
  65.     // currently not owned by a client is less then the minimum
  66.     // goal, create more lines
  67.     if (pbPBXMem->usLinesCreated < pbPBXMem->usLines       &&
  68.         (pbPBXMem->usLinesCreated-pbPBXMem->usLinesOwned)
  69.                                    < pbPBXMem->usOpenLines  ) {
  70.  
  71.       // Determine the number of lines to create
  72.       // It should be either the number needed such that all lines
  73.       // are created or the number needed such that the minimum goal
  74.       // is met, whichever is the lessor value
  75.       usLinesNeeded =
  76.            MIN(pbPBXMem->usLines-pbPBXMem->usLinesCreated,
  77.                pbPBXMem->usOpenLines-
  78.                 (pbPBXMem->usLinesCreated-pbPBXMem->usLinesOwned));
  79.  
  80.       // Loop through the routing table filling available entries
  81.       // until the number of needed lines has been created
  82.       for (usLineNum=0;
  83.            usLinesNeeded && usLineNum < pbPBXMem->usLines;
  84.            usLineNum++) {
  85.  
  86.         // Is the table slot open for the allocation of a new line?
  87.         if (pbPBXMem->abRTable[usLineNum].fState == Available) {
  88.           // Create a new pipe instance
  89.           // Pipe is initially created as non-blocking so that the
  90.           // DosConnectNmPipe call will not block this thread
  91.           usRetCode = DosMakeNmPipe(
  92.                          PIPELINE,                // Pipe name
  93.                          &(pbPBXMem->abRTable[usLineNum].hLine),
  94.                          NP_ACCESS_DUPLEX  |      // Full duplex
  95.                          NP_NOINHERIT      |      // Private
  96.                          NP_WRITEBEHIND,          // Speedy writes
  97.                          NP_NOWAIT         |      // Non-blocking
  98.                          NP_READMODE_BYTE  |      // Byte mode
  99.                          NP_TYPE_BYTE      |
  100.                          (pbPBXMem->usLines > 254 ?
  101.                          NP_UNLIMITED_INSTANCES   :
  102.                          pbPBXMem->usLines),      // Number of lines
  103.                          pbPBXMem->usLineBufSize, // Line
  104.                          pbPBXMem->usLineBufSize, //   Buffers
  105.                          LINEWAITTIMEOUT);        // Timeout value
  106.           if (usRetCode) {
  107.             ERRRPT("DosMakeNmPipe", usRetCode, Warning);
  108.             break;
  109.           }
  110.  
  111.           // Pipe was created successfully, finish initialization
  112.           else {
  113.             // Set number of read/write bytes available
  114.             pbPBXMem->abRTable[usLineNum].usRData = 0;
  115.             pbPBXMem->abRTable[usLineNum].usWSpace=
  116.                                            pbPBXMem->usLineBufSize;
  117.  
  118.             // Mark the entry as open for assignment
  119.             pbPBXMem->abRTable[usLineNum].fState  = Open;
  120.  
  121.             // Associate the line with the PipeMgr thread semaphore
  122.             // (set the key for the line to its routing table offset)
  123.             DosSetNmPipeSem(pbPBXMem->abRTable[usLineNum].hLine,
  124.                             pbPBXMem->hsemPipeMgr,
  125.                             usLineNum);
  126.  
  127.             // Place the pipe into a connect state
  128.             usRetCode = DosConnectNmPipe(
  129.                               pbPBXMem->abRTable[usLineNum].hLine);
  130.             if (usRetCode                            &&
  131.                 usRetCode != ERROR_PIPE_NOT_CONNECTED ) {
  132.               ERRRPT("DosConnectNmPipe", usRetCode, Warning);
  133.               break;
  134.             }
  135.  
  136.             // Set pipe to blocking mode
  137.             // This is necessary because DosQNmPipeSemState is only
  138.             // valid for blocking pipes
  139.             usRetCode = DosSetNmPHandState(
  140.                               pbPBXMem->abRTable[usLineNum].hLine,
  141.                               NP_READMODE_BYTE | NP_WAIT);
  142.             if (usRetCode                            &&
  143.                 usRetCode != ERROR_PIPE_NOT_CONNECTED ) {
  144.               ERRRPT("DosSetNmPHandState", usRetCode, Warning);
  145.               break;
  146.             }
  147.  
  148.             // Line was successfully created and initialized,
  149.             // adjust line counts
  150.             usLinesNeeded--;
  151.             DosSemRequest(&(pbPBXMem->semPBXMem),
  152.                           SEM_INDEFINITE_WAIT);
  153.             pbPBXMem->usLinesCreated++;
  154.             DosSemClear(&(pbPBXMem->semPBXMem));
  155.           }
  156.         }
  157.       }
  158.     }
  159.   }
  160.  
  161.   // PBX is in a shutdown process, exit this thread
  162.   _endthread();
  163. }
  164.