home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / mm / fssht / shioutil.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  24KB  |  490 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                    Copyright (c) IBM Corporation 1992, 1993              */
  4. /*                           All Rights Reserved                            */
  5. /*                                                                          */
  6. /* SOURCE FILE NAME: SHIOUTIL.C                                             */
  7. /*                                                                          */
  8. /* DESCRIPTIVE NAME:  Stream Handler Input Output Utility routines.         */
  9. /*                                                                          */
  10. /* FUNCTION: Utility functions for ring 3 stream handlers.                  */
  11. /*                                                                          */
  12. /* ENTRY POINTS:                                                            */
  13. /*   SleepNCheck                                                            */
  14. /*   CheckNSleep                                                            */
  15. /*   ReportEvent                                                            */
  16. /*   ShIOError                                                              */
  17. /*                                                                          */
  18. /*************************** END OF SPECIFICATIONS **************************/
  19. #define  INCL_NOPMAPI                  /* no PM include files required */
  20. #define  INCL_DOSSEMAPHORES
  21. #define  INCL_DOSPROCESS
  22. #define  INCL_DOSERRORS
  23. #define  INCL_OS2MM
  24. #include <os2.h>
  25. #include <os2me.h>
  26. #include <hhpheap.h>
  27. #include <shi.h>
  28.  
  29. /************************** START OF SPECIFICATIONS *************************/
  30. /*                                                                          */
  31. /* SUBROUTINE NAME: SleepNCheck                                             */
  32. /*                                                                          */
  33. /* DESCRIPTIVE NAME: Sleep and check action flags when woken  up.           */
  34. /*                                                                          */
  35. /* FUNCTION: Suspend execution and when resumed, do checks for action flags */
  36. /*           of stop discard, flush, and check the kill flag.               */
  37. /*                                                                          */
  38. /* NOTES: This is called by the shread and shwrite routines.                */
  39. /*                                                                          */
  40. /* ENTRY POINT: SleepNCheck                                                 */
  41. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  42. /*                                                                          */
  43. /* INPUT:                                                                   */
  44. /*   psib - stream instance block                                           */
  45. /*   pulStopped - pointer to stopped variable.                              */
  46. /*                On input it may have 3 possible values.                   */
  47. /*                  DO_SLEEP            - sleep in all cases                */
  48. /*                  DONT_SLEEP          - do not sleep, just check flags    */
  49. /*                  DONT_SLEEP_FLUSH    - Wake up for flush stops           */
  50. /*                  DONT_SLEEP_DISCARD  - Wake up for discard stops         */
  51. /*                                                                          */
  52. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  53. /*   pulStopped - pointer to output stopped variable.                       */
  54. /*                On output it may have the following output values:        */
  55. /*                  AWAKEN_BY_OTHER        - woke up by kill action         */
  56. /*                  AWAKEN_BY_FLUSH_STOP   - woke up by flush stop          */
  57. /*                  AWAKEN_BY_DISCARD_STOP - woke up by discard stop        */
  58. /*                                                                          */
  59. /* EXIT-ERROR:                                                              */
  60. /*   None                                                                   */
  61. /*                                                                          */
  62. /* SIDE EFFECTS:                                                            */
  63. /*                                                                          */
  64. /* INTERNAL REFERENCES:                                                     */
  65. /*        ROUTINES: None                                                    */
  66. /*                                                                          */
  67. /* EXTERNAL REFERENCES:                                                     */
  68. /*   ROUTINES: None                                                         */
  69. /*                                                                          */
  70. /*   DATA STRUCTURES:                                                       */
  71. /*     sib                                                                  */
  72. /*                                                                          */
  73. /*************************** END OF SPECIFICATIONS **************************/
  74. #ifdef INCL_NEWSH
  75.  
  76. RC SleepNCheck ( PSIB psib,
  77.                  PULONG pulStopped )
  78.  
  79. { /* Start of SleepNCheck */
  80.  
  81.    RC    rc = 0L;
  82.    BOOL  KeepSleeping = TRUE;
  83.    ULONG ulStopped = *pulStopped;     /* Save Flags */
  84.  
  85.    *pulStopped = AWAKEN_BY_OTHER;     /* Reset the output */
  86.  
  87.    /**********************************************************************/
  88.    /* While no error (or Destroy/Kill) and Stop specified (KeepSleeping) */
  89.    /**********************************************************************/
  90.    while (!rc && KeepSleeping) { /* Suspend */
  91.  
  92.       KeepSleeping = FALSE;
  93.  
  94.       if (!psib->ulActionFlags) {
  95.          RECEIVE_MSG(psib,rc);
  96.  
  97.          if (!rc) {
  98.             RESET_MSG(psib);
  99.             }
  100.          }
  101.  
  102.       if (!rc && psib->ulActionFlags) { /* Somethings up */
  103.  
  104.          if (psib->ulActionFlags & (SIBACTFLG_STOP_DISCARD | SIBACTFLG_STOP_FLUSH | SIBACTFLG_STOP_PAUSE)) {
  105.  
  106.             /************************************************************/
  107.             /* If we were awakend and told to STOP then since we don't  */
  108.             /* own any buffers just keep sleeping (loop and resuspend). */ 
  109.             /* We need to clear the STOP flags so when we are started   */ 
  110.             /* we don't just stop again.                                */ 
  111.             /*                                                          */ 
  112.             /* Also set the pulStopped to TRUE so our caller knows we   */ 
  113.             /* were explictly stopped by the calling application.       */
  114.             /************************************************************/
  115.  
  116.             if (psib->ulActionFlags & SIBACTFLG_STOP_FLUSH) {      /* FLUSH STOP */
  117.                psib->ulActionFlags &= ~(SIBACTFLG_STOP_FLUSH);
  118.                if (ulStopped & DONT_SLEEP_FLUSH)
  119.                   *pulStopped = AWAKEN_BY_FLUSH_STOP;
  120.                else
  121.                   KeepSleeping = TRUE;
  122.                }
  123.  
  124.             else if (psib->ulActionFlags & SIBACTFLG_STOP_DISCARD) {  /* DISCARD STOP */
  125.                psib->ulActionFlags &= ~(SIBACTFLG_STOP_DISCARD);
  126.                if (ulStopped & DONT_SLEEP_DISCARD)
  127.                   *pulStopped = AWAKEN_BY_DISCARD_STOP;
  128.                else
  129.                   KeepSleeping = TRUE;
  130.                }
  131.  
  132.             else {        /* PAUSE STOP */
  133.                psib->ulActionFlags &= ~(SIBACTFLG_STOP_PAUSE);
  134.                KeepSleeping = TRUE;
  135.                }
  136.  
  137.             /*************************************************************/ 
  138.             /* Let calling thread know we are done with the stop command */ 
  139.             /*************************************************************/
  140.             SEND_REPLY(psib);
  141.             }
  142.  
  143.          /**********************************************************************/
  144.          /* If Destroy was sent then the KILL flag should be set.  Check it    */
  145.          /*  and set "rc" to SIBACTFLG_KILL so we will exit the main loop and  */
  146.          /*  this function.  The ulActionFlags will still have the             */
  147.          /*  SIBACTFLG_KILLset so the calling routine can tell if the rc was   */
  148.          /*  a severe error or a Destroy KILL.                                 */
  149.          /**********************************************************************/
  150.          rc = (psib->ulActionFlags & SIBACTFLG_KILL);
  151.          } /* Somethings up */
  152.       } /* Suspend */
  153.  
  154.    return(rc);
  155.  
  156. } /* End of SleepNCheck */
  157.  
  158.  
  159. #else
  160. /*****************************************************************************/
  161. RC SleepNCheck(psib, pulStopped)
  162.  
  163. PSIB psib;
  164. PULONG pulStopped;            // were stop flags encountered.
  165.  
  166. { /* Start of SleepNCheck */
  167.  
  168.   RC    rc = 0L;
  169.   BOOL  KeepSleeping = TRUE;
  170.  
  171.   //
  172.   // While no error (or Destroy/Kill) and Stop specified (KeepSleeping)
  173.   //
  174.   while (!rc && KeepSleeping)
  175.     { /* Suspend */
  176.  
  177.       KeepSleeping = FALSE;
  178.       if (!psib->ulActionFlags)
  179.         {
  180.           RECEIVE_MSG(psib,rc);
  181.           if (!rc) {
  182.              RESET_MSG(psib);
  183.              }
  184.         }
  185.       if (!rc && psib->ulActionFlags)
  186.         { /* Somethings up */
  187.           if (psib->ulActionFlags & (SIBACTFLG_STOP_DISCARD | SIBACTFLG_STOP_FLUSH | SIBACTFLG_STOP_PAUSE))
  188.             {
  189.               //
  190.               // If we were awakend and told to STOP then since we don't
  191.               // own any buffers just keep sleeping (loop and resuspend).
  192.               // We need to clear the STOP flags so when we are started
  193.               // we don't just stop again.
  194.               //
  195.               // Also set the pulStopped to TRUE so our caller knows we
  196.               // were explictly stopped by the calling application.
  197.               //
  198.  
  199.               if (psib->ulActionFlags & SIBACTFLG_STOP_FLUSH)       /* FLUSH STOP */
  200.                 {
  201.                   psib->ulActionFlags &= ~(SIBACTFLG_STOP_FLUSH);
  202.  
  203.                   if (*pulStopped != DONT_SLEEP_FLUSH)
  204.                     {
  205.                       KeepSleeping = TRUE;
  206.                       *pulStopped = TRUE;
  207.                     }
  208.                 }
  209.               else
  210.                 { /* discard or pause */
  211.                   KeepSleeping = TRUE;
  212.                   if (psib->ulActionFlags & SIBACTFLG_STOP_DISCARD)
  213.                     {
  214.                       psib->ulActionFlags &= ~(SIBACTFLG_STOP_DISCARD);
  215.                       *pulStopped = TRUE;
  216.                     }
  217.                   else
  218.                     { /* stop pause */
  219.                       psib->ulActionFlags &= ~(SIBACTFLG_STOP_PAUSE);
  220.                       *pulStopped = FALSE;
  221.                     } /* stop pause */
  222.                 } /* discard or pause*/
  223.  
  224.               //
  225.               // Let calling thread know we are done with the stop command
  226.               //
  227.               SEND_REPLY(psib);
  228.             }
  229.           //
  230.           // If Destroy was sent then the KILL flag should be set.  Check it
  231.           //  and set "rc" to SIBACTFLG_KILL so we will exit the main loop and
  232.           //  this function.  The ulActionFlags will still have the
  233.           //  SIBACTFLG_KILLset so the calling routine can tell if the rc was
  234.           //  a severe error or a Destroy KILL.
  235.           //
  236.           rc = (psib->ulActionFlags & SIBACTFLG_KILL);
  237.         } /* Somethings up */
  238.     } /* Suspend */
  239.  
  240.   return(rc);
  241.  
  242. } /* End of SleepNCheck */
  243. #endif
  244.  
  245.  
  246.  
  247. /************************** START OF SPECIFICATIONS *************************/
  248. /*                                                                          */
  249. /* SUBROUTINE NAME: CheckNSleep                                             */
  250. /*                                                                          */
  251. /* DESCRIPTIVE NAME: Check actions flags and sleep if stop command.         */
  252. /*                                                                          */
  253. /* FUNCTION: Check the action flags (stop discard, flush and kill) and then */
  254. /*           suspend if needed.  When resumed, check the flags again.       */
  255. /*                                                                          */
  256. /* NOTES: This is called by the shread and shwrite routines.                */
  257. /*  Also, this will not get a stop flush on a target thread since shcstop   */
  258. /*  code filters that out and ignores it.                                   */
  259. /*                                                                          */
  260. /* ENTRY POINT: CheckNSleep                                                 */
  261. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  262. /*                                                                          */
  263. /* INPUT:                                                                   */
  264. /*   psib - stream instance block                                           */
  265. /*                                                                          */
  266. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  267. /*                                                                          */
  268. /* EXIT-ERROR:                                                              */
  269. /*   None                                                                   */
  270. /*                                                                          */
  271. /* SIDE EFFECTS:                                                            */
  272. /*                                                                          */
  273. /* INTERNAL REFERENCES:                                                     */
  274. /*        ROUTINES: None                                                    */
  275. /*                                                                          */
  276. /* EXTERNAL REFERENCES:                                                     */
  277. /*   ROUTINES: None                                                         */
  278. /*                                                                          */
  279. /*   DATA STRUCTURES:                                                       */
  280. /*     sib                                                                  */
  281. /*                                                                          */
  282. /*************************** END OF SPECIFICATIONS **************************/
  283.  
  284. RC CheckNSleep(psib)
  285.  
  286. PSIB psib;
  287.  
  288. { /* Start of CheckNSleep */
  289.  
  290.   RC    rc;
  291.   ULONG ulPostCount;
  292.  
  293.   rc = (psib->ulActionFlags & SIBACTFLG_KILL);
  294.   /* suspend if stop command */
  295.   while (!rc && (psib->ulActionFlags & (SIBACTFLG_STOP_DISCARD | SIBACTFLG_STOP_FLUSH | SIBACTFLG_STOP_PAUSE)))
  296.     { /* Suspend */
  297.       psib->ulActionFlags &= ~(SIBACTFLG_STOP_DISCARD | SIBACTFLG_STOP_FLUSH | SIBACTFLG_STOP_PAUSE);
  298.       RESET_MSG(psib);
  299.       SEND_REPLY(psib);
  300.       RECEIVE_MSG(psib,rc);
  301.       rc = (psib->ulActionFlags & SIBACTFLG_KILL);
  302.     } /* Suspend */
  303.  
  304.   return(rc);
  305.  
  306. } /* End of CheckNSleep */
  307.  
  308. /************************** START OF SPECIFICATIONS *************************/
  309. /*                                                                          */
  310. /* SUBROUTINE NAME: ReportEvent                                             */
  311. /*                                                                          */
  312. /* DESCRIPTIVE NAME: Report an Error Event to the stream manager            */
  313. /*                                                                          */
  314. /* FUNCTION: Report an event of the type passed in to the stream manager.   */
  315. /*                                                                          */
  316. /* NOTES: This is called by the shread and shwrite routines.                */
  317. /*                                                                          */
  318. /* ENTRY POINT: ReportEvent                                                 */
  319. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  320. /*                                                                          */
  321. /* INPUT:                                                                   */
  322. /*   psib         - stream instance block                                   */
  323. /*   ulEventRc    - Event return code                                       */
  324. /*   ulEventType  - Event type                                              */
  325. /*   ulUserParm   - User parameter                                          */
  326. /*   ulFlags      - flags                                                   */
  327. /*                                                                          */
  328. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  329. /*                                                                          */
  330. /* EXIT-ERROR:                                                              */
  331. /*   None                                                                   */
  332. /*                                                                          */
  333. /* SIDE EFFECTS:                                                            */
  334. /*                                                                          */
  335. /* INTERNAL REFERENCES:                                                     */
  336. /*        ROUTINES: None                                                    */
  337. /*                                                                          */
  338. /* EXTERNAL REFERENCES:                                                     */
  339. /*   ROUTINES: None                                                         */
  340. /*    SMHEntryPoint                                                         */
  341. /*                                                                          */
  342. /*   DATA STRUCTURES:                                                       */
  343. /*                                                                          */
  344. /*************************** END OF SPECIFICATIONS **************************/
  345.  
  346. RC ReportEvent(psib, ulEventRc, ulEventType, ulUserParm, ulFlags)
  347.  
  348. PSIB   psib;
  349. RC     ulEventRc;
  350. ULONG  ulEventType;
  351. ULONG  ulUserParm;
  352. ULONG  ulFlags;                     /* Error severity */
  353.  
  354. { /* Start of ReportEvent */
  355.  
  356.   PARM_EVENT parmev;
  357.   IMPL_EVCB  ImplEvcb;
  358.   PLAYL_EVCB PlayEvcb;
  359.   RC         rc;
  360.  
  361.   parmev.ulFunction = SMH_REPORTEVENT;
  362.   parmev.hid = psib->HandlerID;
  363.   parmev.hevent = 0L;
  364.  
  365.   if ((ulEventType == EVENT_PLAYLISTMESSAGE) ||
  366.       (ulEventType == EVENT_PLAYLISTCUEPOINT))
  367.     { /* use playlist evcb */
  368.  
  369.       parmev.pevcbEvent = (PEVCB)&PlayEvcb;
  370.       PlayEvcb.ulType = EVENT_IMPLICIT_TYPE;
  371.       PlayEvcb.ulSubType = ulEventType;
  372.       PlayEvcb.ulFlags = ulFlags;
  373.       PlayEvcb.hstream = psib->hStream;
  374.       PlayEvcb.hid = psib->HandlerID;
  375.       PlayEvcb.ulStatus = ulEventRc;
  376.       PlayEvcb.ulMessageParm = ulUserParm;
  377.       PlayEvcb.unused1 = 0L;
  378.       PlayEvcb.unused2 = 0L;
  379.  
  380.     } /* use playlist evcb */
  381.   else
  382.     { /* use implicit evcb */
  383.  
  384.       parmev.pevcbEvent = (PEVCB)&ImplEvcb;
  385.       ImplEvcb.ulType = EVENT_IMPLICIT_TYPE;
  386.       ImplEvcb.ulSubType = ulEventType;
  387.       ImplEvcb.ulFlags = ulFlags;
  388.       ImplEvcb.hstream = psib->hStream;
  389.       ImplEvcb.hid = psib->HandlerID;
  390.       ImplEvcb.ulStatus = ulEventRc;
  391.       ImplEvcb.unused1 = 0L;
  392.       ImplEvcb.unused2 = 0L;
  393.       ImplEvcb.unused3 = 0L;
  394.  
  395.     } /* use implicit evcb */
  396.   rc = SMHEntryPoint(&parmev);
  397.  
  398.   return(rc);
  399.  
  400. } /* End of ReportEvent */
  401.  
  402. /************************** START OF SPECIFICATIONS *************************/
  403. /*                                                                          */
  404. /* SUBROUTINE NAME: ShIOError                                               */
  405. /*                                                                          */
  406. /* DESCRIPTIVE NAME: Handle an IO Error in stream handler                   */
  407. /*                                                                          */
  408. /* FUNCTION: Routine to handle IO error in the ring3 stream handler read    */
  409. /*           and write routines.                                            */
  410. /*                                                                          */
  411. /* NOTES: This is called by the shread and shwrite routines.                */
  412. /*                                                                          */
  413. /* ENTRY POINT: ShIOError                                                   */
  414. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  415. /*                                                                          */
  416. /* INPUT:                                                                   */
  417. /*   psib         - stream instance block                                   */
  418. /*   npret        - Notify parameter block                                  */
  419. /*   retcode      - return code                                             */
  420. /*                                                                          */
  421. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  422. /*                                                                          */
  423. /* EXIT-ERROR:                                                              */
  424. /*   None                                                                   */
  425. /*                                                                          */
  426. /* SIDE EFFECTS:                                                            */
  427. /*                                                                          */
  428. /* INTERNAL REFERENCES:                                                     */
  429. /*        ROUTINES: None                                                    */
  430. /*                                                                          */
  431. /* EXTERNAL REFERENCES:                                                     */
  432. /*   ROUTINES: None                                                         */
  433. /*     SMHEntryPoint                                                        */
  434. /*     CheckNSleep                                                          */
  435. /*     SleepNCheck                                                          */
  436. /*     ReportEvent                                                          */
  437. /*                                                                          */
  438. /*   DATA STRUCTURES:                                                       */
  439. /*     sib                                                                  */
  440. /*                                                                          */
  441. /*************************** END OF SPECIFICATIONS **************************/
  442.  
  443. RC ShIOError(psib, npret, retcode)
  444.  
  445. PSIB        psib;
  446. PARM_NOTIFY npret;
  447. RC          retcode;
  448.  
  449. { /* Start of ShIOError */
  450.  
  451.   RC         saverc;
  452.   RC         rc = NO_ERROR;
  453.   ULONG      ulStopped = DO_SLEEP;
  454.  
  455.   /* Return the buffer */
  456.  
  457.   saverc = SMHEntryPoint(&npret);
  458.  
  459.   if (psib->ulActionFlags)
  460.     { /* Somethings up */
  461.  
  462.       rc = CheckNSleep(psib);
  463.  
  464.     } /* Somethings up */
  465.   else
  466.     { /* Report I/O error */
  467.  
  468.       /* Clear the stop sem, so if the app clears the error during */
  469.       /* the report and sends a start, then we won't go to sleep */
  470.  
  471.       RESET_MSG(psib);
  472.  
  473.       if (!(rc = ReportEvent(psib,
  474.                              retcode,          /* Return code */
  475.                              EVENT_ERROR,      /* event type */
  476.                              0L,               /* user info */
  477.                              RECOVERABLE_ERROR)))  /* Must get start */
  478.         { /* report event ok */
  479.  
  480.           rc = SleepNCheck(psib, &ulStopped);
  481.  
  482.         } /* report event ok */
  483.     } /* Report I/O error */
  484.   if (!rc)
  485.     rc = saverc; /* restore return empty RC */
  486.  
  487.   return(rc);
  488.  
  489. } /* End of ShIOError */
  490.