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

  1. /*-------------------------------------------------------------------
  2.   ROUTER.C -- PBX Packet transfer routine
  3.  
  4.   Description:
  5.  
  6.   This thread manages pipes that are connected.  After receiving a
  7.   CONNECT request, the PipeMgr thread transfers control of the
  8.   connected pipes to one of the Router threads (via
  9.   DosSetNmPipeSem).  This thread rapidly moves data between the two
  10.   pipes with no regard for the contents of the data.  A connection
  11.   is broken by one of the clients closing their end of the pipe.
  12.  
  13.   Author:  Brendan Dixon
  14.            Microsoft, inc.
  15.            LAN Manager Developer Support
  16.  
  17.   This code example is provided for demonstration purposes only.
  18.   Microsoft makes no warranty, either express or implied,
  19.   as to its usability in any given situation.
  20. -------------------------------------------------------------------*/
  21.  
  22. // Includes ---------------------------------------------------------
  23. #define   INCL_DOS
  24. #define   INCL_DOSERRORS
  25. #include  <os2.h>
  26.  
  27. #define   INCL_NETSERVICE
  28. #include  <lan.h>
  29.  
  30. #include  <stdio.h>
  31. #include  <string.h>
  32.  
  33. #include  "pbxsrv.h"
  34.  
  35.  
  36. /* Router -----------------------------------------------------------
  37.   Description:  See file header
  38.   Input      :  usThreadNum -- Router thread instance number
  39.   Output     :  None
  40. -------------------------------------------------------------------*/
  41. void _cdecl Router(USHORT usThreadNum)
  42. {
  43.   ROUTEENT _far     *pbREnt;              // Client table entry
  44.   ROUTEENT _far     *pbRTargetEnt;        // Target table entry
  45.   RTHREAD  _far     *pbRThread;           // Router struct pointer
  46.   USHORT            usNPSSRData;          // NPSS_RDATAs found
  47.   USHORT            usNPSSClose;          // NPSS_CLOSEs found
  48.   USHORT            usCnt;                // Loop counter
  49.   USHORT            usByteCnt;            // Bytes to transfer
  50.   USHORT            usRetCode;            // Return code
  51.  
  52.   // Establish a pointer to this threads memory structure
  53.   pbRThread = pbPBXMem->abRouters + usThreadNum;
  54.  
  55.   // Loop forever processing requests
  56.   for (;;) {
  57.  
  58.     // Wait for input on one of the lines
  59.     DosSemRequest(pbRThread->hsemRouter, SEM_INDEFINITE_WAIT);
  60.  
  61.     // Read all of the PIPESEMSTATE records
  62.     usRetCode = DosQNmPipeSemState(pbRThread->hsemRouter,
  63.                                    pbRThread->aPSemState,
  64.                                    pbRThread->usPSemStateSize);
  65.     if (usRetCode) {
  66.       ERRRPT("DosQNmPipeSemState", usRetCode, Warning);
  67.     }
  68.  
  69.     // First, loop thru the PIPESEMSTATE records setting the amount
  70.     // of write space available for each pipe and counting the
  71.     // number of NPSS_RDATA and NPSS_CLOSE records encountered
  72.     // Next, for each NPSS_RDATA and NPSS_CLOSE record found during
  73.     // the first loop, transfer as much data as possible and close
  74.     // those pipes which have been closed by their clients
  75.     else  {
  76.       // First, set amount of write space each pipe has and count
  77.       // the number of NPSS_RDATA and NPSS_CLOSE records encountered
  78.       // (save pointers into the routing table for each record
  79.       // encountered)
  80.       for (usCnt = usNPSSRData = usNPSSClose = 0;
  81.            pbRThread->aPSemState[usCnt].fStatus != NPSS_EOI;
  82.            usCnt++) {
  83.         // Build a pointer into the routing table
  84.         pbREnt = pbPBXMem->abRTable +
  85.                           pbRThread->aPSemState[usCnt].usKey;
  86.  
  87.         // And process the record
  88.         switch (pbRThread->aPSemState[usCnt].fStatus) {
  89.  
  90.           // Update the amount of data available to be read
  91.           case NPSS_RDATA :
  92.             pbREnt->usRData = pbRThread->aPSemState[usCnt].usAvail;
  93.             if (pbREnt->usRData) {
  94.               pbRThread->aRData[usNPSSRData] = pbREnt;
  95.               usNPSSRData++;
  96.             }
  97.             break;
  98.  
  99.           // Update the amount of write space available
  100.           case NPSS_WSPACE:
  101.             pbREnt->usWSpace = pbRThread->aPSemState[usCnt].usAvail;
  102.             break;
  103.  
  104.           // A client has broken their pipe connection
  105.           case NPSS_CLOSE :
  106.             pbRThread->aClose[usNPSSClose] = pbREnt;
  107.             usNPSSClose++;
  108.             break;
  109.  
  110.           default         : {
  111.             CHAR  pszMsg[80];             // Error message buffer
  112.  
  113.             sprintf(pszMsg,
  114.                     "Unknown DosQNmPipeSemState record type of %u",
  115.                     (USHORT)(pbRThread->aPSemState[usCnt].fStatus));
  116.             ERRRPT(pszMsg, 0, Warning);
  117.             break;
  118.           }
  119.         }
  120.       }
  121.  
  122.       // Transfer all data that can be transferred
  123.       for (usCnt=0; usCnt < usNPSSRData; usCnt++) {
  124.         pbREnt       = pbRThread->aRData[usCnt];
  125.         pbRTargetEnt = pbPBXMem->abRTable + pbREnt->usConnection;
  126.  
  127.         // Determine the maximum amount of data that can be moved
  128.         usByteCnt = MIN(pbREnt->usRData, pbRTargetEnt->usWSpace);
  129.  
  130.         // And transfer the data
  131.         if (usByteCnt                                        &&
  132.             ReadPKT(pbRThread->pbLineBuf, usByteCnt, pbREnt)  )
  133.           SendPKT(pbRThread->pbLineBuf, usByteCnt, pbRTargetEnt);
  134.       }
  135.  
  136.       // Close pipes for those clients which have closed their end
  137.       for (usCnt=0; usCnt < usNPSSClose; usCnt++) {
  138.         Deregister(pbRThread->aClose[usCnt]);
  139.  
  140.         // Decrement the number of connections managed by this pipe
  141.         DosSemRequest(&(pbRThread->semRAccess), SEM_INDEFINITE_WAIT);
  142.         pbRThread->cConnections--;
  143.         DosSemClear(&(pbRThread->semRAccess));
  144.       }
  145.     }
  146.   }
  147.  
  148.   // Control never arrives at this point, the thread is simply
  149.   // terminated when PBX shuts down
  150.   return;
  151. }
  152.