home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / ELM23-2 / ELM23-2.ZIP / os2 / alarm.c next >
C/C++ Source or Header  |  1992-10-04  |  4KB  |  154 lines

  1. #ifndef __EMX__
  2.  
  3. #pragma check_stack(off)
  4.  
  5. /*
  6.  * This software is Copyright 1989 by Jack Hudler.
  7.  *
  8.  * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  9.  * use this software as long as: there is no monetary profit gained
  10.  * specifically from the use or reproduction or this software, it is not
  11.  * sold, rented, traded or otherwise marketed, and this copyright notice is
  12.  * included prominently in any copy made.
  13.  *
  14.  * The author make no claims as to the fitness or correctness of this software
  15.  * for any use whatsoever, and it is provided as is. Any use of this software
  16.  * is at the user's own risk.
  17.  *
  18.  */
  19.  
  20. /****************************** Module Header ******************************\
  21. * Module Name: alarm.c
  22. * Created    : 11-08-89
  23. * Author     : Jack Hudler  [jack@csccat.lonestar.org]
  24. * Copyright  : 1988 Jack Hudler.
  25. * Function   : Unix like alarm signal simulator.
  26. \***************************************************************************/
  27.  
  28. /* Tested using OS2 1.2 with Microsoft C 5.1 and 6.0. */
  29.  
  30. #define INCL_DOSPROCESS
  31. #define INCL_DOSSIGNALS
  32. #define INCL_DOS
  33. #include <os2.h>
  34.  
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37. #include <signal.h>
  38.  
  39. #include "alarm.h"
  40.  
  41. #define ALARM_STACK 4096    /* This maybe over kill, but the page size is 4K */
  42.  
  43. static  PBYTE     pbAlarmStack;
  44. static  SEL       selAlarmStack;
  45. static  TID       tidAlarm;
  46. static  PID       pidMain;
  47. static  BOOL      bAlarmInit=FALSE;
  48. static  BOOL      bAlarmRunning=FALSE;
  49. static  ULONG     ulTime;
  50.  
  51. static VOID FAR alarm_thread ( VOID )
  52. {
  53.     while(1)
  54.     {
  55.       DosSleep(1000L);
  56.       if (bAlarmRunning)
  57.       {
  58.         ulTime--;
  59.         if (ulTime==0L)
  60.         {
  61.         /* send signal to the main process.. I could have put raise() here
  62.            however that would require the use of the multithreaded library,
  63.            and it does not contain raise()!
  64.            I tried it with the standard library, this signaled ok, but a
  65.            test printf in the signal would not work and even caused SEGV.
  66.            So I signal the process through OS/2 and then the process
  67.            signals itself. */
  68.           DosFlagProcess(pidMain,FLGP_PID, PFLG_A,1);
  69.           bAlarmRunning=FALSE;
  70.         }
  71.       }
  72.     }
  73. }
  74.  
  75. static VOID PASCAL FAR AlarmSignal(USHORT usSigArg,USHORT usSigNum)
  76. {
  77.     /*
  78.      * this is not executed from the thread. The thread triggers Process
  79.      * flag A which is in the main processes scope, this inturn triggers
  80.      * (via the raise) SIGUSR1 which is defined to SIGALRM.
  81.      */
  82.   PFNSIGHANDLER pfnPrev;
  83.   USHORT       pfAction;
  84.   DosSetSigHandler(AlarmSignal,&pfnPrev,&pfAction,SIGA_ACKNOWLEDGE,SIG_PFLG_A);
  85.   raise(SIGUSR1);
  86. }
  87.  
  88. static void alarm_init(void)
  89. {
  90.     PFNSIGHANDLER pfnPrev;
  91.     USHORT       pfAction;
  92.     PIDINFO      pid;
  93.     if (!DosAllocSeg( ALARM_STACK, (PSEL) &selAlarmStack, SEG_NONSHARED ))
  94.     {
  95.       bAlarmInit = TRUE;
  96.       OFFSETOF(pbAlarmStack) = ALARM_STACK - 2;
  97.       SELECTOROF(pbAlarmStack) = selAlarmStack;
  98.       /* Create the thread */
  99.       if (DosCreateThread( alarm_thread, &tidAlarm, pbAlarmStack ))
  100.       {
  101.         fprintf(stderr,"Alarm thread failed to start.\n");
  102.         exit(1);
  103.       }
  104.       /* Setup the signal handler for Process Flag A */
  105.       if (DosSetSigHandler(AlarmSignal,&pfnPrev,&pfAction,SIGA_ACCEPT,SIG_PFLG_A))
  106.       {
  107.         fprintf(stderr,"SigHandler Failed to install.\n");
  108.         exit(1);
  109.       }
  110.       /* Save main process ID, we'll need it for triggering the signal */
  111.       DosGetPID(&pid);
  112.       pidMain = pid.pid;
  113.     }
  114.     else
  115.       exit(1);
  116. }
  117.  
  118. long alarm(long sec)
  119. {
  120.     if (_osmode == DOS_MODE) return 0L;
  121.     if (!bAlarmInit) alarm_init();
  122.     if (sec)
  123.     {
  124.       ulTime = sec;
  125.       bAlarmRunning = TRUE;
  126.     }
  127.     else
  128.       bAlarmRunning = FALSE;
  129.  
  130.     return 0L;
  131. }
  132.  
  133. #ifdef TESTING
  134. /* A simple test to see if it works */
  135. BOOL  x;
  136.  
  137. void timeout(void)
  138. {
  139.     fprintf(stderr,"ALARM TRIGGERED!!\n");
  140.     DosBeep(1000,500);
  141.     x++;
  142. }
  143.  
  144. void main(void)
  145. {
  146.     (void) signal(SIGALRM, timeout);
  147.     (void) alarm(5L);
  148.     printf("ALARM RUNNING!!\n");
  149.     while(!x);
  150. }
  151. #endif
  152.  
  153. #endif
  154.