home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mmpm21tk.zip / TK / FSSHT / SHIOUTIL.C < prev    next >
C/C++ Source or Header  |  1993-02-25  |  20KB  |  394 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         0 - sleep in all cases                 */
  48. /*                  DONT_SLEEP       1 - do not sleep, just check flags     */
  49. /*                On output it may have 2 possible values.                  */
  50. /*                  TRUE  1 - Stopped after recieving stop Discard/Flush    */
  51. /*                  FALSE 0 - Did not stop for Discard or Flush             */
  52. /*                                                                          */
  53. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  54. /*                                                                          */
  55. /* EXIT-ERROR:                                                              */
  56. /*   None                                                                   */
  57. /*                                                                          */
  58. /* SIDE EFFECTS:                                                            */
  59. /*                                                                          */
  60. /* INTERNAL REFERENCES:                                                     */
  61. /*        ROUTINES: None                                                    */
  62. /*                                                                          */
  63. /* EXTERNAL REFERENCES:                                                     */
  64. /*   ROUTINES: None                                                         */
  65. /*                                                                          */
  66. /*   DATA STRUCTURES:                                                       */
  67. /*     sib                                                                  */
  68. /*                                                                          */
  69. /*************************** END OF SPECIFICATIONS **************************/
  70.  
  71. RC SleepNCheck(psib, pulStopped)
  72.  
  73. PSIB psib;
  74. PULONG pulStopped;            // were stop flags encountered.
  75.  
  76. { /* Start of SleepNCheck */
  77.  
  78.   RC    rc = 0L;
  79.   BOOL  KeepSleeping = TRUE;
  80.  
  81.   //
  82.   // While no error (or Destroy/Kill) and Stop specified (KeepSleeping)
  83.   //
  84.   while (!rc && KeepSleeping)
  85.     { /* Suspend */
  86.  
  87.       KeepSleeping = FALSE;
  88.       if (!psib->ulActionFlags)
  89.         {
  90.           RECEIVE_MSG(psib,rc);
  91.           if (!rc) {
  92.              RESET_MSG(psib);
  93.              }
  94.         }
  95.       if (!rc && psib->ulActionFlags)
  96.         { /* Somethings up */
  97.           if (psib->ulActionFlags & (SIBACTFLG_STOP_DISCARD | SIBACTFLG_STOP_FLUSH | SIBACTFLG_STOP_PAUSE))
  98.             {
  99.               //
  100.               // If we were awakend and told to STOP then since we don't
  101.               // own any buffers just keep sleeping (loop and resuspend).
  102.               // We need to clear the STOP flags so when we are started
  103.               // we don't just stop again.
  104.               //
  105.               // Also set the pulStopped to TRUE so our caller knows we
  106.               // were explictly stopped by the calling application.
  107.               //
  108.               if (psib->ulActionFlags & SIBACTFLG_STOP_FLUSH)
  109.                 {
  110.                   psib->ulActionFlags &= ~(SIBACTFLG_STOP_FLUSH);
  111.                   if (*pulStopped != DONT_SLEEP_FLUSH)
  112.                     {
  113.                       KeepSleeping = TRUE;
  114.                       *pulStopped = TRUE;
  115.                     }
  116.                 }
  117.               else
  118.                 { /* discard or pause */
  119.                   KeepSleeping = TRUE;
  120.                   if (psib->ulActionFlags & SIBACTFLG_STOP_DISCARD)
  121.                     {
  122.                       psib->ulActionFlags &= ~(SIBACTFLG_STOP_DISCARD);
  123.                       *pulStopped = TRUE;
  124.                     }
  125.                   else
  126.                     { /* stop pause */
  127.                       psib->ulActionFlags &= ~(SIBACTFLG_STOP_PAUSE);
  128.                       *pulStopped = FALSE;
  129.                     } /* stop pause */
  130.                 } /* discard or pause*/
  131.               //
  132.               // Let calling thread know we are done with the stop command
  133.               //
  134.               SEND_REPLY(psib);
  135.             }
  136.           //
  137.           // If Destroy was sent then the KILL flag should be set.  Check it
  138.           //  and set "rc" to SIBACTFLG_KILL so we will exit the main loop and
  139.           //  this function.  The ulActionFlags will still have the
  140.           //  SIBACTFLG_KILLset so the calling routine can tell if the rc was
  141.           //  a severe error or a Destroy KILL.
  142.           //
  143.           rc = (psib->ulActionFlags & SIBACTFLG_KILL);
  144.         } /* Somethings up */
  145.     } /* Suspend */
  146.  
  147.   return(rc);
  148.  
  149. } /* End of SleepNCheck */
  150.  
  151. /************************** START OF SPECIFICATIONS *************************/
  152. /*                                                                          */
  153. /* SUBROUTINE NAME: CheckNSleep                                             */
  154. /*                                                                          */
  155. /* DESCRIPTIVE NAME: Check actions flags and sleep if stop command.         */
  156. /*                                                                          */
  157. /* FUNCTION: Check the action flags (stop discard, flush and kill) and then */
  158. /*           suspend if needed.  When resumed, check the flags again.       */
  159. /*                                                                          */
  160. /* NOTES: This is called by the shread and shwrite routines.                */
  161. /*  Also, this will not get a stop flush on a target thread since shcstop   */
  162. /*  code filters that out and ignores it.                                   */
  163. /*                                                                          */
  164. /* ENTRY POINT: CheckNSleep                                                 */
  165. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  166. /*                                                                          */
  167. /* INPUT:                                                                   */
  168. /*   psib - stream instance block                                           */
  169. /*                                                                          */
  170. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  171. /*                                                                          */
  172. /* EXIT-ERROR:                                                              */
  173. /*   None                                                                   */
  174. /*                                                                          */
  175. /* SIDE EFFECTS:                                                            */
  176. /*                                                                          */
  177. /* INTERNAL REFERENCES:                                                     */
  178. /*        ROUTINES: None                                                    */
  179. /*                                                                          */
  180. /* EXTERNAL REFERENCES:                                                     */
  181. /*   ROUTINES: None                                                         */
  182. /*                                                                          */
  183. /*   DATA STRUCTURES:                                                       */
  184. /*     sib                                                                  */
  185. /*                                                                          */
  186. /*************************** END OF SPECIFICATIONS **************************/
  187.  
  188. RC CheckNSleep(psib)
  189.  
  190. PSIB psib;
  191.  
  192. { /* Start of CheckNSleep */
  193.  
  194.   RC    rc;
  195.   ULONG ulPostCount;
  196.  
  197.   rc = (psib->ulActionFlags & SIBACTFLG_KILL);
  198.   /* suspend if stop command */
  199.   while (!rc && (psib->ulActionFlags & (SIBACTFLG_STOP_DISCARD | SIBACTFLG_STOP_FLUSH | SIBACTFLG_STOP_PAUSE)))
  200.     { /* Suspend */
  201.       psib->ulActionFlags &= ~(SIBACTFLG_STOP_DISCARD | SIBACTFLG_STOP_FLUSH | SIBACTFLG_STOP_PAUSE);
  202.       RESET_MSG(psib);
  203.       SEND_REPLY(psib);
  204.       RECEIVE_MSG(psib,rc);
  205.       rc = (psib->ulActionFlags & SIBACTFLG_KILL);
  206.     } /* Suspend */
  207.  
  208.   return(rc);
  209.  
  210. } /* End of CheckNSleep */
  211.  
  212. /************************** START OF SPECIFICATIONS *************************/
  213. /*                                                                          */
  214. /* SUBROUTINE NAME: ReportEvent                                             */
  215. /*                                                                          */
  216. /* DESCRIPTIVE NAME: Report an Error Event to the stream manager            */
  217. /*                                                                          */
  218. /* FUNCTION: Report an event of the type passed in to the stream manager.   */
  219. /*                                                                          */
  220. /* NOTES: This is called by the shread and shwrite routines.                */
  221. /*                                                                          */
  222. /* ENTRY POINT: ReportEvent                                                 */
  223. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  224. /*                                                                          */
  225. /* INPUT:                                                                   */
  226. /*   psib         - stream instance block                                   */
  227. /*   ulEventRc    - Event return code                                       */
  228. /*   ulEventType  - Event type                                              */
  229. /*   ulUserParm   - User parameter                                          */
  230. /*   ulFlags      - flags                                                   */
  231. /*                                                                          */
  232. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  233. /*                                                                          */
  234. /* EXIT-ERROR:                                                              */
  235. /*   None                                                                   */
  236. /*                                                                          */
  237. /* SIDE EFFECTS:                                                            */
  238. /*                                                                          */
  239. /* INTERNAL REFERENCES:                                                     */
  240. /*        ROUTINES: None                                                    */
  241. /*                                                                          */
  242. /* EXTERNAL REFERENCES:                                                     */
  243. /*   ROUTINES: None                                                         */
  244. /*    SMHEntryPoint                                                         */
  245. /*                                                                          */
  246. /*   DATA STRUCTURES:                                                       */
  247. /*                                                                          */
  248. /*************************** END OF SPECIFICATIONS **************************/
  249.  
  250. RC ReportEvent(psib, ulEventRc, ulEventType, ulUserParm, ulFlags)
  251.  
  252. PSIB   psib;
  253. RC     ulEventRc;
  254. ULONG  ulEventType;
  255. ULONG  ulUserParm;
  256. ULONG  ulFlags;                     /* Error severity */
  257.  
  258. { /* Start of ReportEvent */
  259.  
  260.   PARM_EVENT parmev;
  261.   IMPL_EVCB  ImplEvcb;
  262.   PLAYL_EVCB PlayEvcb;
  263.   RC         rc;
  264.  
  265.   parmev.ulFunction = SMH_REPORTEVENT;
  266.   parmev.hid = psib->HandlerID;
  267.   parmev.hevent = 0L;
  268.  
  269.   if ((ulEventType == EVENT_PLAYLISTMESSAGE) ||
  270.       (ulEventType == EVENT_PLAYLISTCUEPOINT))
  271.     { /* use playlist evcb */
  272.  
  273.       parmev.pevcbEvent = (PEVCB)&PlayEvcb;
  274.       PlayEvcb.ulType = EVENT_IMPLICIT_TYPE;
  275.       PlayEvcb.ulSubType = ulEventType;
  276.       PlayEvcb.ulFlags = ulFlags;
  277.       PlayEvcb.hstream = psib->hStream;
  278.       PlayEvcb.hid = psib->HandlerID;
  279.       PlayEvcb.ulStatus = ulEventRc;
  280.       PlayEvcb.ulMessageParm = ulUserParm;
  281.       PlayEvcb.unused1 = 0L;
  282.       PlayEvcb.unused2 = 0L;
  283.  
  284.     } /* use playlist evcb */
  285.   else
  286.     { /* use implicit evcb */
  287.  
  288.       parmev.pevcbEvent = (PEVCB)&ImplEvcb;
  289.       ImplEvcb.ulType = EVENT_IMPLICIT_TYPE;
  290.       ImplEvcb.ulSubType = ulEventType;
  291.       ImplEvcb.ulFlags = ulFlags;
  292.       ImplEvcb.hstream = psib->hStream;
  293.       ImplEvcb.hid = psib->HandlerID;
  294.       ImplEvcb.ulStatus = ulEventRc;
  295.       ImplEvcb.unused1 = 0L;
  296.       ImplEvcb.unused2 = 0L;
  297.       ImplEvcb.unused3 = 0L;
  298.  
  299.     } /* use implicit evcb */
  300.   rc = SMHEntryPoint(&parmev);
  301.  
  302.   return(rc);
  303.  
  304. } /* End of ReportEvent */
  305.  
  306. /************************** START OF SPECIFICATIONS *************************/
  307. /*                                                                          */
  308. /* SUBROUTINE NAME: ShIOError                                               */
  309. /*                                                                          */
  310. /* DESCRIPTIVE NAME: Handle an IO Error in stream handler                   */
  311. /*                                                                          */
  312. /* FUNCTION: Routine to handle IO error in the ring3 stream handler read    */
  313. /*           and write routines.                                            */
  314. /*                                                                          */
  315. /* NOTES: This is called by the shread and shwrite routines.                */
  316. /*                                                                          */
  317. /* ENTRY POINT: ShIOError                                                   */
  318. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  319. /*                                                                          */
  320. /* INPUT:                                                                   */
  321. /*   psib         - stream instance block                                   */
  322. /*   npret        - Notify parameter block                                  */
  323. /*   retcode      - return code                                             */
  324. /*                                                                          */
  325. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  326. /*                                                                          */
  327. /* EXIT-ERROR:                                                              */
  328. /*   None                                                                   */
  329. /*                                                                          */
  330. /* SIDE EFFECTS:                                                            */
  331. /*                                                                          */
  332. /* INTERNAL REFERENCES:                                                     */
  333. /*        ROUTINES: None                                                    */
  334. /*                                                                          */
  335. /* EXTERNAL REFERENCES:                                                     */
  336. /*   ROUTINES: None                                                         */
  337. /*     SMHEntryPoint                                                        */
  338. /*     CheckNSleep                                                          */
  339. /*     SleepNCheck                                                          */
  340. /*     ReportEvent                                                          */
  341. /*                                                                          */
  342. /*   DATA STRUCTURES:                                                       */
  343. /*     sib                                                                  */
  344. /*                                                                          */
  345. /*************************** END OF SPECIFICATIONS **************************/
  346.  
  347. RC ShIOError(psib, npret, retcode)
  348.  
  349. PSIB        psib;
  350. PARM_NOTIFY npret;
  351. RC          retcode;
  352.  
  353. { /* Start of ShIOError */
  354.  
  355.   RC         saverc;
  356.   RC         rc = NO_ERROR;
  357.   ULONG      ulStopped = DO_SLEEP;
  358.  
  359.   /* Return the buffer */
  360.  
  361.   saverc = SMHEntryPoint(&npret);
  362.  
  363.   if (psib->ulActionFlags)
  364.     { /* Somethings up */
  365.  
  366.       rc = CheckNSleep(psib);
  367.  
  368.     } /* Somethings up */
  369.   else
  370.     { /* Report I/O error */
  371.  
  372.       /* Clear the stop sem, so if the app clears the error during */
  373.       /* the report and sends a start, then we won't go to sleep */
  374.  
  375.       RESET_MSG(psib);
  376.  
  377.       if (!(rc = ReportEvent(psib,
  378.                              retcode,          /* Return code */
  379.                              EVENT_ERROR,      /* event type */
  380.                              0L,               /* user info */
  381.                              RECOVERABLE_ERROR)))  /* Must get start */
  382.         { /* report event ok */
  383.  
  384.           rc = SleepNCheck(psib, &ulStopped);
  385.  
  386.         } /* report event ok */
  387.     } /* Report I/O error */
  388.   if (!rc)
  389.     rc = saverc; /* restore return empty RC */
  390.  
  391.   return(rc);
  392.  
  393. } /* End of ShIOError */
  394.