home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mmpm21tk.zip / TK / FSSHT / FSSHWRIT.C < prev    next >
C/C++ Source or Header  |  1993-02-25  |  11KB  |  264 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                    Copyright (c) IBM Corporation 1992, 1993              */
  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: Pointer to sib (stream instance block)                            */
  40. /*                                                                          */
  41. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  42. /*                                                                          */
  43. /* EXIT-ERROR:                                                              */
  44. /*   ERROR_BUFFER_NOT_AVAILABLE                                             */
  45. /*                                                                          */
  46. /* SIDE EFFECTS:                                                            */
  47. /*                                                                          */
  48. /* INTERNAL REFERENCES:                                                     */
  49. /*        ROUTINES: None                                                    */
  50. /*                                                                          */
  51. /* EXTERNAL REFERENCES:                                                     */
  52. /*        ROUTINES:                                                         */
  53. /*          DosWaitEventSem                                                 */
  54. /*          CheckNSleep                                                     */
  55. /*          DosResetEventSem                                                */
  56. /*          SMHEntryPoint                                                   */
  57. /*          SleepNCheck                                                     */
  58. /*          mmioWrite                                                       */
  59. /*          ShIOError                                                       */
  60. /*          mmioGetLastError                                                */
  61. /*          ReportEvent                                                     */
  62. /*        DATA STRUCTURES:                                                  */
  63. /*          npget                                                           */
  64. /*          sib                                                             */
  65. /*          hmtxGlobalData                                                       */
  66. /*                                                                          */
  67. /*************************** END OF SPECIFICATIONS **************************/
  68.  
  69. VOID FsshWrite(psib)
  70. PSIB psib;                                /* Stream Instance Block */
  71.  
  72. { /* Start of FsshWrite */
  73.  
  74. RC          rc = NO_ERROR;                /* local return code */
  75. char        NeedBuf;                      /* local loop boolean */
  76. LONG        NumBytesIO;                   /* Number of bytes from mmio */
  77. PARM_NOTIFY npget, npret;                 /* parms for SMH_NOTIFY calls */
  78. TGTBUFTAB   TgtBufTab = {0};              /* Target buffer table */
  79. ULONG       ulStopped = DONT_SLEEP_FLUSH; /* did we get stop discard or flush */
  80. BOOL        bAtEOS = FALSE;               /* End of Stream indicator */
  81. ULONG       ulPostCount;                /* Temp to hold count */
  82.  
  83.   /* Before we start lets do some init stuff: */
  84.  
  85.   npget.ulFunction = SMH_NOTIFY;
  86.   npget.hid = psib->HandlerID;
  87.   npget.hstream = psib->hStream;
  88.   npget.ulFlags = BUF_GETFULL;
  89.   npget.ulGetNumEntries = 1L;
  90.   npget.ulRetNumEntries = 0L;
  91.   npget.pGetBufTab = &TgtBufTab;
  92.   npget.pRetBufTab = NULL;
  93.  
  94.   npret.ulFunction = SMH_NOTIFY;
  95.   npret.hid = psib->HandlerID;
  96.   npret.hstream = psib->hStream;
  97.   npret.ulFlags = BUF_RETURNEMPTY;
  98.   npret.ulGetNumEntries = 0L;
  99.   npret.ulRetNumEntries = 1L;
  100.   npret.pGetBufTab = NULL;
  101.   npret.pRetBufTab = &TgtBufTab;
  102.  
  103.   /* Wait until we get the ShcStart */
  104.  
  105.   DosWaitEventSem(psib->hevStop, SEM_INDEFINITE_WAIT);
  106.  
  107.   /* We will loop forever getting a full buffer, calling the file system to */
  108.   /* write it out and returning the empty buffer to the stream manager. */
  109.   /* During each iteration of the loop we will check the action flags for */
  110.   /* asynchronous requests to do things. */
  111.  
  112.   if (psib->ulActionFlags & SIBACTFLG_KILL)
  113.     { /* Must have been a create error */
  114.       rc = 1L;
  115.     } /* Must have been a create error */
  116.  
  117.   /*  Start the main loop */
  118.  
  119.   while (!rc)
  120.     { /* while no severe error */
  121.  
  122.     if (psib->ulActionFlags)
  123.       rc = CheckNSleep(psib);
  124.  
  125.     /*
  126.      * Get a buffer
  127.      */
  128.     NeedBuf = TRUE;
  129.     while ((NeedBuf) && (!rc))
  130.       { /* while we don't have a buffer */
  131.  
  132.         /* Clear the stop sem, so if after we call ssm to get a buffer if */
  133.         /* it returns none avail then we won't miss a SSMBuffer Start before */
  134.         /* we go to sleep. */
  135.  
  136.         DosResetEventSem(psib->hevStop, &ulPostCount);
  137.  
  138.         /* Make sure only GetFull flag is on and call ssm to get a buffer */
  139.  
  140.         npget.ulFlags = BUF_GETFULL;
  141.         rc = SMHEntryPoint(&npget); /* get a buffer */
  142.         if (!rc)
  143.           {
  144.             NeedBuf = FALSE;
  145.             /* set return buffer EOS flag if get EOS is on */
  146.             npret.ulFlags |= npget.ulFlags & BUF_EOS;
  147.           }
  148.         else
  149.           { /* return code from smhnotify */
  150.             if (rc == ERROR_BUFFER_NOT_AVAILABLE)
  151.               { /* buffer not available */
  152.  
  153.                 /* the smhnotify resets the num entries when none avail */
  154.                 npget.ulGetNumEntries = 1L;
  155.                 ulStopped = DONT_SLEEP_FLUSH;
  156.                 rc = SleepNCheck(psib, &ulStopped);
  157.  
  158.               } /* buffer not available */
  159.           } /* return code from smhnotify */
  160.       } /* while we don't have a buffer */
  161.  
  162.     /* We have a buffer or an error */
  163.  
  164.     if (!rc)
  165.       { /* have a buffer */
  166.  
  167.         /* Check to see if we got a cuepoint in the buf attribute field. */
  168.         /* If so, we need to report this event. */
  169.  
  170.         if (TgtBufTab.ulMessageParm)
  171.           {
  172.             rc = ReportEvent(psib,
  173.                              0L,                        /* no return code */
  174.                              EVENT_PLAYLISTCUEPOINT,    /* event type */
  175.                              TgtBufTab.ulMessageParm,   /* user supplied value */
  176.                              0L);
  177.  
  178.           }
  179.  
  180.         /* Make sure attribute is clear in all cases so it won't be passed */
  181.         /* around the system inadvertently */
  182.  
  183.         TgtBufTab.ulMessageParm = 0L;
  184.  
  185.         /* If there is data in the buffer we received then write it out. */
  186.  
  187.         NumBytesIO = 0L;
  188.         if (TgtBufTab.ulLength)
  189.           {
  190.             NumBytesIO = mmioWrite((HMMIO)psib->ulAssocP1,
  191.                                    (PCHAR)TgtBufTab.pBuffer,
  192.                                    (LONG)TgtBufTab.ulLength);
  193.           }
  194.         if ((NumBytesIO == -1L) ||
  195.             (NumBytesIO != (LONG)TgtBufTab.ulLength))
  196.  
  197.           { /* an error */
  198.  
  199.             /* get the real error code */
  200.             rc = mmioGetLastError((HMMIO)psib->ulAssocP1);
  201.  
  202.             rc = ShIOError(psib, npret, rc);
  203.  
  204.           } /* an error */
  205.         else
  206.           { /* We wrote ok */
  207.  
  208.             /* Set up to return buffer to stream manager */
  209.  
  210.             if (npret.ulFlags & BUF_EOS)
  211.               { /* End of stream */
  212.                 bAtEOS = TRUE;
  213.                 DosResetEventSem(psib->hevStop, &ulPostCount);
  214.               } /* End of stream */
  215.  
  216.             /* Return the empty buffer to the stream manager */
  217.  
  218.             if (!(rc = SMHEntryPoint(&npret)))
  219.               { /* buffer returned */
  220.                 if (bAtEOS)
  221.                   {
  222.                     bAtEOS = FALSE;
  223.                     ulStopped = DONT_SLEEP_FLUSH;
  224.                     rc = SleepNCheck(psib, &ulStopped);
  225.                   }
  226.               } /* buffer returned */
  227.           } /* We wrote ok */
  228.  
  229.         /* Make sure EOS is turned off, so things will work if the */
  230.         /* stream is restarted. */
  231.  
  232.         npret.ulFlags = BUF_RETURNEMPTY;
  233.  
  234.       } /* have a buffer */
  235.  
  236.     } /* while no severe error */
  237.  
  238.   /* We get here if an error has occurred or a kill has */
  239.   /*  been sent.  In the case of the kill, reset the */
  240.   /*  return code to 0 (no error) and exit the thread. */
  241.   /*  Otherwise, report the error event and exit the */
  242.   /*  thread. */
  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.   /* Only set this flag when we no longer need access to the sib since */
  258.   /* Destroy may get control and Free the sib. */
  259.  
  260.   psib->ulActionFlags |= SIBACTFLG_THREAD_DEAD;
  261.   return;
  262.  
  263. } /* End of FsshWrite */
  264.