home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / source / devnews / vol2 / sample2 / worker.c < prev   
Encoding:
C/C++ Source or Header  |  1993-10-25  |  2.9 KB  |  114 lines

  1. /* WORKER.C.  This program shows how a worker function can use an
  2. exception handler like a safety net for calling threads.
  3. Compile and link this program with:  icc /ss worker.c */
  4.  
  5. // os2 includes
  6. #define INCL_DOS
  7. #define INCL_ERRORS
  8. #include <os2.h>
  9.  
  10. // c includes
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <setjmp.h>
  15. #include <assert.h>
  16.  
  17. // user-extended exception registration record
  18. typedef struct _regrec {
  19.   PVOID     pNext;
  20.   PFN       pfnHandler;
  21.   jmp_buf   jmpWorker;
  22. } REGREC;
  23. typedef REGREC *PREGREC;
  24.  
  25. // ----------------------------------------------------------------------
  26. ULONG _System Handler( PEXCEPTIONREPORTRECORD p1,
  27.                        PREGREC p2,
  28.                        PCONTEXTRECORD p3,
  29.                        PVOID pv )
  30. {
  31.   switch( p1->ExceptionNum ) {
  32.   case XCPT_ACCESS_VIOLATION:
  33.   case XCPT_INTEGER_DIVIDE_BY_ZERO:
  34.   case XCPT_INTEGER_OVERFLOW:
  35.   case XCPT_PROCESS_TERMINATE:        // killed thread case
  36.   case XCPT_ASYNC_PROCESS_TERMINATE:  // killed thread case
  37.     // interested in this one
  38.     longjmp( p2->jmpWorker, p1->ExceptionNum );
  39.   default:
  40.     break;
  41.   }
  42.   // not handled
  43.   return XCPT_CONTINUE_SEARCH;
  44. }
  45.  
  46.  
  47. // ----------------------------------------------------------------------
  48. // returns TRUE for success, FALSE for failure
  49. LONG _System WorkerFunction( PCHAR pch )
  50. {
  51.   LONG        rc;
  52.   LONG        rcResult;
  53.   ULONG       ulException;
  54.   REGREC      regrec;
  55.  
  56.   // set a handler
  57.   regrec.pfnHandler = (PFN)Handler;
  58.   rc = DosSetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) ®rec );
  59.   assert( rc == 0 );
  60.  
  61.   // store a known thread state
  62.   ulException = setjmp( regrec.jmpWorker );
  63.  
  64.   if( ulException ) {
  65.  
  66.     // cleanup here: free memory allocations, release mutex sems, etc.
  67.  
  68.     // get the handler off the chain
  69.     rc = DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) ®rec );
  70.     assert( rc == 0 );
  71.  
  72.     // check for the killed-thread case
  73.     switch( ulException ) {
  74.     case XCPT_PROCESS_TERMINATE:
  75.     case XCPT_ASYNC_PROCESS_TERMINATE:
  76.       // clean up done above and thread really wants to die
  77.       DosExit( EXIT_THREAD, 0 );
  78.       break;
  79.     }
  80.     // set a failing result code
  81.     rcResult = FALSE;
  82.     goto depart;
  83.   }
  84.  
  85.   // dereference the supplied pointer
  86.   *pch = 'a';
  87.  
  88.   rc = DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) ®rec );
  89.   assert( rc == 0 );
  90.  
  91.   rcResult = TRUE;
  92.  
  93. depart:
  94.   return rcResult;
  95. }
  96.  
  97.  
  98. // ----------------------------------------------------------------------
  99. int main ( void )
  100. {
  101.   CHAR     szWork[ 16 ];
  102.   LONG     rc;
  103.  
  104.   // try worker function with a good pointer
  105.   rc = WorkerFunction( szWork );
  106.   printf( "Good pointer returns %d\n", rc );
  107.  
  108.   // try worker function with a bad pointer
  109.   rc = WorkerFunction( NULL );
  110.   printf( "Bad pointer returns %d\n", rc );
  111.  
  112.   return 0;
  113. }
  114.