home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / alarm / alarm.c next >
Encoding:
C/C++ Source or Header  |  1990-07-18  |  3.9 KB  |  142 lines

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