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

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                    Copyright (c) IBM Corporation 1992                    */
  4. /*                           All Rights Reserved                            */
  5. /*                                                                          */
  6. /* SOURCE FILE NAME: FSSHWRIT.C                                             */
  7. /*                                                                          */
  8. /* DESCRIPTIVE NAME:  File System Stream Handler Write routine              */
  9. /*                                                                          */
  10. /* FUNCTION: This function is the routine that writes an object to the      */
  11. /*           file system.                                                   */
  12. /*                                                                          */
  13. /* ENTRY POINTS: FsshWrite                                                  */
  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: FsshWrite                                               */
  29. /*                                                                          */
  30. /* DESCRIPTIVE NAME: File System Stream Handler Write routine               */
  31. /*                                                                          */
  32. /* FUNCTION: Gets data from source stream handler (actually SSM) and writes */
  33. /*           it to the file system.                                         */
  34. /* NOTES:                                                                   */
  35. /*                                                                          */
  36. /* ENTRY POINT: FsshWrite                                                   */
  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 FsshWrite(psib)
  57. PSIB psib;                                // Stream Instance Block
  58.  
  59. { /* Start of FsshWrite */
  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. TGTBUFTAB   TgtBufTab = {0};              // Target buffer table
  66. ULONG       ulStopped = DONT_SLEEP_FLUSH; // 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.ulFlags = BUF_GETFULL;
  77.   npget.ulGetNumEntries = 1L;
  78.   npget.ulRetNumEntries = 0L;
  79.   npget.pGetBufTab = &TgtBufTab;
  80.   npget.pRetBufTab = NULL;
  81.  
  82.   npret.ulFunction = SMH_NOTIFY;
  83.   npret.hid = psib->HandlerID;
  84.   npret.hstream = psib->hStream;
  85.   npret.ulFlags = BUF_RETURNEMPTY;
  86.   npret.ulGetNumEntries = 0L;
  87.   npret.ulRetNumEntries = 1L;
  88.   npret.pGetBufTab = NULL;
  89.   npret.pRetBufTab = &TgtBufTab;
  90.  
  91.   //
  92.   // Wait until we get the ShcStart
  93.   //
  94.   DosWaitEventSem(psib->hevStop, SEM_INDEFINITE_WAIT);
  95.  
  96.   //
  97.   // We will loop forever getting a full buffer, calling the file system to
  98.   // write it out and returning the empty buffer to the stream manager.
  99.   // During each iteration of the loop we will check the action flags for
  100.   // asynchronous requests to do things.
  101.   //
  102.  
  103.   if (psib->ulActionFlags & SIBACTFLG_KILL)
  104.     { /* Must have been a create error */
  105.       rc = 1L;
  106.     } /* Must have been a create error */
  107.  
  108.   //
  109.   //  Start the main loop
  110.   //
  111.  
  112.   while (!rc)
  113.     { /* while no severe error */
  114.  
  115.     if (psib->ulActionFlags)
  116.       rc = CheckNSleep(psib);
  117.  
  118.     /*
  119.      * Get a buffer
  120.      */
  121.     NeedBuf = TRUE;
  122.     while ((NeedBuf) && (!rc))
  123.       { /* while we don't have a buffer */
  124.  
  125.         //
  126.         // Clear the stop sem, so if after we call ssm to get a buffer if
  127.         // it returns none avail then we won't miss a SSMBuffer Start before
  128.         // we go to sleep.
  129.         //
  130.         DosResetEventSem(psib->hevStop, &ulPostCount);
  131.  
  132.         //
  133.         // Make sure only GetFull flag is on and call ssm to get a buffer
  134.         //
  135.         npget.ulFlags = BUF_GETFULL;
  136.         rc = SMHEntryPoint(&npget); /* get a buffer */
  137.         if (!rc)
  138.           {
  139.             NeedBuf = FALSE;
  140.             /* set return buffer EOS flag if get EOS is on */
  141.             npret.ulFlags |= npget.ulFlags & BUF_EOS;
  142.           }
  143.         else
  144.           { /* return code from smhnotify */
  145.             if (rc == ERROR_BUFFER_NOT_AVAILABLE)
  146.               { /* buffer not available */
  147.  
  148.                 /* the smhnotify resets the num entries when none avail */
  149.                 npget.ulGetNumEntries = 1L;
  150.                 ulStopped = DONT_SLEEP_FLUSH;
  151.                 rc = SleepNCheck(psib, &ulStopped);
  152.  
  153.               } /* buffer not available */
  154.           } /* return code from smhnotify */
  155.       } /* while we don't have a buffer */
  156.  
  157.     //
  158.     // We have a buffer or an error
  159.     //
  160.  
  161.     if (!rc)
  162.       { /* have a buffer */
  163.         //
  164.         // Check to see if we got a cuepoint in the buf attribute field.
  165.         // If so, we need to report this event.
  166.         //
  167.         if (TgtBufTab.ulMessageParm)
  168.           {
  169.             rc = ReportEvent(psib,
  170.                              0L,                        // no return code
  171.                              EVENT_PLAYLISTCUEPOINT,    // event type
  172.                              TgtBufTab.ulMessageParm,   // user supplied value
  173.                              0L);
  174.  
  175.           }
  176.         //
  177.         // Make sure attribute is clear in all cases so it won't be passed
  178.         // around the system inadvertently
  179.         //
  180.         TgtBufTab.ulMessageParm = 0L;
  181.  
  182.         //
  183.         // If there is data in the buffer we received then write it out.
  184.         //
  185.         NumBytesIO = 0L;
  186.         if (TgtBufTab.ulLength)
  187.           {
  188.             NumBytesIO = mmioWrite((HMMIO)psib->ulAssocP1,
  189.                                    (PCHAR)TgtBufTab.pBuffer,
  190.                                    (LONG)TgtBufTab.ulLength);
  191.           }
  192.         if ((NumBytesIO == -1L) ||
  193.             (NumBytesIO != (LONG)TgtBufTab.ulLength))
  194.  
  195.           { /* an error */
  196.  
  197.             /* get the real error code */
  198.             rc = mmioGetLastError((HMMIO)psib->ulAssocP1);
  199.  
  200.             rc = ShIOError(psib, npret, rc);
  201.  
  202.           } /* an error */
  203.         else
  204.           { /* We wrote ok */
  205.  
  206.             // Set up to return buffer to stream manager
  207.  
  208.             if (npret.ulFlags & BUF_EOS)
  209.               { /* End of stream */
  210.                 bAtEOS = TRUE;
  211.                 DosResetEventSem(psib->hevStop, &ulPostCount);
  212.               } /* End of stream */
  213.  
  214.             // Return the empty buffer to the stream manager
  215.  
  216.             if (!(rc = SMHEntryPoint(&npret)))
  217.               { /* buffer returned */
  218.                 if (bAtEOS)
  219.                   {
  220.                     bAtEOS = FALSE;
  221.                     ulStopped = DONT_SLEEP_FLUSH;
  222.                     rc = SleepNCheck(psib, &ulStopped);
  223.                   }
  224.               } /* buffer returned */
  225.           } /* We wrote ok */
  226.         //
  227.         // Make sure EOS is turned off, so things will work if the
  228.         // stream is restarted.
  229.         //
  230.         npret.ulFlags = BUF_RETURNEMPTY;
  231.  
  232.       } /* have a buffer */
  233.  
  234.     } /* while no severe error */
  235.  
  236.   //
  237.   // We get here if an error has occurred or a kill has
  238.   //  been sent.  In the case of the kill, reset the
  239.   //  return code to 0 (no error) and exit the thread.
  240.   //  Otherwise, report the error event and exit the
  241.   //  thread.
  242.   //
  243.  
  244.   if (psib->ulActionFlags & SIBACTFLG_KILL)
  245.     {
  246.       rc = 0L;
  247.     }
  248.   else
  249.     {
  250.       ReportEvent(psib,
  251.                   rc,                   // Return code
  252.                   EVENT_ERROR,          // event type
  253.                   0L,                   // user info
  254.                   NONRECOVERABLE_ERROR);  // Severe Error
  255.     }
  256.  
  257.   //
  258.   // Only set this flag when we no longer need access to the sib since
  259.   // Destroy may get control and Free the sib.
  260.   //
  261.   psib->ulActionFlags |= SIBACTFLG_THREAD_DEAD;
  262.   return(rc);
  263.  
  264. } /* End of FsshWrite */
  265.