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