home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional Developers Kit 1992 November / Disc01 / Disc01.mdf / runnable / mmos2 / mmtoolkt / samples / fssht / fsshread.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-06  |  9.1 KB  |  235 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                    Copyright (c) IBM Corporation 1992                    */
  4. /*                           All Rights Reserved                            */
  5. /*                                                                          */
  6. /* SOURCE FILE NAME: FSSHREAD.C                                             */
  7. /*                                                                          */
  8. /* DESCRIPTIVE NAME:  File System Stream Handler Read routine               */
  9. /*                                                                          */
  10. /* FUNCTION: This function is the routine that reads an object from the     */
  11. /*           file system.                                                   */
  12. /*                                                                          */
  13. /* ENTRY POINTS: FsshRead                                                   */
  14. /*                                                                          */
  15. /*************************** END OF SPECIFICATIONS **************************/
  16. #define  INCL_NOPMAPI                  /* no PM include files required */
  17. #define  INCL_DOSSEMAPHORES
  18. #define  INCL_DOSPROCESS
  19. #define  INCL_DOSERRORS
  20. #define  INCL_MMIO
  21. #include <os2.h>
  22. #include <os2me.h>
  23. #include <hhpheap.h>
  24. #include <shi.h>
  25.  
  26. /************************** START OF SPECIFICATIONS *************************/
  27. /*                                                                          */
  28. /* SUBROUTINE NAME: FsshRead                                                */
  29. /*                                                                          */
  30. /* DESCRIPTIVE NAME: File System Stream Handler Read routine                */
  31. /*                                                                          */
  32. /* FUNCTION: Reads object from the file system and supplies it to the       */
  33. /*           target stream handler.                                         */
  34. /* NOTES:                                                                   */
  35. /*                                                                          */
  36. /* ENTRY POINT: FsshRead                                                    */
  37. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  38. /*                                                                          */
  39. /* INPUT:                                                                   */
  40. /*                                                                          */
  41. /* EXIT-NORMAL:                                                             */
  42. /*                                                                          */
  43. /* EXIT-ERROR:                                                              */
  44. /*                                                                          */
  45. /* SIDE EFFECTS:                                                            */
  46. /*                                                                          */
  47. /* INTERNAL REFERENCES:                                                     */
  48. /*        ROUTINES:                                                         */
  49. /*                                                                          */
  50. /* EXTERNAL REFERENCES:                                                     */
  51. /*        ROUTINES:                                                         */
  52. /*        DATA STRUCTURES:                                                  */
  53. /*                                                                          */
  54. /*************************** END OF SPECIFICATIONS **************************/
  55.  
  56. RC FsshRead(psib)
  57. PSIB psib;                              // Stream Instance Block
  58.  
  59. { /* Start of FsshRead */
  60.  
  61. RC          rc = NO_ERROR;              // local return code
  62. char        NeedBuf;                    // local loop boolean
  63. LONG        NumBytesIO;                 // Number of bytes from mmio
  64. PARM_NOTIFY npget, npret;               // parms for SMH_NOTIFY calls
  65. SRCBUFTAB   SrcBufTab = {0};            // Source buffer table
  66. ULONG       ulStopped = DO_SLEEP;       // did we get stop discard or flush
  67. BOOL        bAtEOS = FALSE;             // End of Stream indicator
  68. ULONG       ulPostCount;                // Temp to hold count
  69.  
  70.   //
  71.   // Before we start lets do some init stuff:
  72.   //
  73.   npget.ulFunction = SMH_NOTIFY;
  74.   npget.hid = psib->HandlerID;
  75.   npget.hstream = psib->hStream;
  76.   npget.ulGetNumEntries = 1L;
  77.   npget.ulRetNumEntries = 0L;
  78.   npget.pGetBufTab = &SrcBufTab;
  79.   npget.pRetBufTab = NULL;
  80.  
  81.   npret.ulFunction = SMH_NOTIFY;
  82.   npret.hid = psib->HandlerID;
  83.   npret.hstream = psib->hStream;
  84.   npret.ulFlags = BUF_RETURNFULL;
  85.   npret.ulGetNumEntries = 0L;
  86.   npret.ulRetNumEntries = 1L;
  87.   npret.pGetBufTab = NULL;
  88.   npret.pRetBufTab = &SrcBufTab;
  89.  
  90.   //
  91.   // Wait until we get the ShcStart
  92.   //
  93.   DosWaitEventSem(psib->hevStop, SEM_INDEFINITE_WAIT);
  94.  
  95.   //
  96.   // We will loop forever getting an empty buffer, calling the device to
  97.   // fill up the buffer, sending it to the consumer.  During each iteration
  98.   // of the loop we will check the action flags for asynchronous requests
  99.   // to do things.
  100.   //
  101.   if (psib->ulActionFlags & SIBACTFLG_KILL)
  102.     { /* Must have been a create error */
  103.       rc = 1L;
  104.     } /* Must have been a create error */
  105.  
  106.   //
  107.   //  Start the main loop
  108.   //
  109.  
  110.   while (!rc)
  111.     { /* while no severe error */
  112.  
  113.     if (psib->ulActionFlags)
  114.       rc = CheckNSleep(psib);
  115.  
  116.     /*
  117.      * Get a buffer
  118.      */
  119.     NeedBuf = TRUE;
  120.     while ((NeedBuf) && (!rc))
  121.       { /* while we don't have a buffer */
  122.  
  123.         //
  124.         // Clear the stop sem, so if after we call ssm to get a buffer if
  125.         // it returns none avail then we won't miss a SSMBuffer Start before
  126.         // we go to sleep.
  127.         //
  128.         DosResetEventSem(psib->hevStop, &ulPostCount);
  129.  
  130.         npget.ulFlags = BUF_GETEMPTY;
  131.         rc = SMHEntryPoint(&npget); /* get a buffer */
  132.         if (!rc)
  133.           {
  134.             NeedBuf = FALSE;
  135.             /* make sure attribute is 0 so we don't pass around a bad value */
  136.             SrcBufTab.ulMessageParm = 0L;
  137.           }
  138.         else
  139.           { /* return code from smhnotify */
  140.             if (rc == ERROR_BUFFER_NOT_AVAILABLE)
  141.               { /* buffer not available */
  142.  
  143.                 /* the smhnotify resets the num entries to 0 when none avail */
  144.                 npget.ulGetNumEntries = 1L;
  145.  
  146.                 ulStopped = DO_SLEEP;
  147.                 rc = SleepNCheck(psib, &ulStopped);
  148.  
  149.               } /* buffer not available */
  150.           } /* return code from smhnotify */
  151.       } /* while we don't have a buffer */
  152.  
  153.     //
  154.     // We have a buffer or an error
  155.     //
  156.  
  157.     if (!rc)
  158.       { /* have a buffer - do the read */
  159.  
  160.         NumBytesIO = mmioRead((HMMIO)psib->ulAssocP1,
  161.                                 (PCHAR)SrcBufTab.pBuffer,
  162.                                 (LONG)SrcBufTab.ulLength);
  163.  
  164.         if (NumBytesIO == -1L)
  165.           { /* an error */
  166.  
  167.             SrcBufTab.ulLength = 0L;
  168.             /* get the real error code */
  169.             rc = mmioGetLastError((HMMIO)psib->ulAssocP1);
  170.  
  171.             rc = ShIOError(psib, npret, rc);
  172.  
  173.           } /* an error */
  174.         else
  175.           { /* We have some data */
  176.  
  177.             if (NumBytesIO != (LONG)SrcBufTab.ulLength)
  178.               { /* End of stream */
  179.                 npret.ulFlags |= BUF_EOS;
  180.                 bAtEOS = TRUE;
  181.                 DosResetEventSem(psib->hevStop, &ulPostCount);
  182.                 SrcBufTab.ulLength = NumBytesIO;
  183.               } /* End of stream */
  184.  
  185.             // Send the data to the stream manager
  186.  
  187.             rc = SMHEntryPoint(&npret);
  188.             if (!rc)
  189.               { /* data sent ok */
  190.                 if (bAtEOS)
  191.                   {
  192.                     bAtEOS = FALSE;
  193.                     ulStopped = DO_SLEEP;
  194.                     rc = SleepNCheck(psib, &ulStopped);
  195.                   }
  196.               } /* data sent ok */
  197.           } /* We have some data */
  198.  
  199.         /* Clear the EOS if it was set. And attribute */
  200.         npret.ulFlags = BUF_RETURNFULL;
  201.         SrcBufTab.ulMessageParm = 0L;
  202.  
  203.       } /* have a buffer - do the read */
  204.  
  205.     } /* while no severe error */
  206.  
  207.   //
  208.   // We get here if an error has occurred or a kill has
  209.   //  been sent.  In the case of the kill, reset the
  210.   //  return code to 0 (no error) and exit the thread.
  211.   //  Otherwise, report the error event and exit the
  212.   //  thread.
  213.   //
  214.  
  215.   if (psib->ulActionFlags & SIBACTFLG_KILL)
  216.     {
  217.       rc = 0L;
  218.     }
  219.   else
  220.     {
  221.       ReportEvent(psib,
  222.                   rc,                   // Return code
  223.                   EVENT_ERROR,          // event type
  224.                   0L,                   // user info
  225.                   NONRECOVERABLE_ERROR);  // Severe Error
  226.     }
  227.   //
  228.   // Only set this flag when we no longer need access to the sib since
  229.   // Destroy may get control and Free the sib.
  230.   //
  231.   psib->ulActionFlags |= SIBACTFLG_THREAD_DEAD;
  232.   return(rc);
  233.  
  234. } /* End of FsshRead */
  235.