![]() ![]() | ![]() |
1.1 snw 1: /*
2: * *
3: * * *
4: * * *
5: * ***************
6: * * * * *
7: * * MUMPS *
8: * * * * *
9: * ***************
10: * * *
11: * * *
12: * *
13: *
14: * events.c
15: * event framework
16: *
17: *
1.2 ! snw 18: * Author: Serena Willis <snw@coherent-logic.com>
1.1 snw 19: * Copyright (C) 1998 MUG Deutschland
20: * Copyright (C) 2020 Coherent Logic Development LLC
21: *
22: *
23: * This file is part of FreeM.
24: *
25: * FreeM is free software: you can redistribute it and/or modify
26: * it under the terms of the GNU Affero Public License as published by
27: * the Free Software Foundation, either version 3 of the License, or
28: * (at your option) any later version.
29: *
30: * FreeM is distributed in the hope that it will be useful,
31: * but WITHOUT ANY WARRANTY; without even the implied warranty of
32: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33: * GNU Affero Public License for more details.
34: *
35: * You should have received a copy of the GNU Affero Public License
36: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
37: *
38: **/
39:
40: #include <stdlib.h>
41: #include <string.h>
42:
43: #include "mpsdef.h"
44: #include "events.h"
45: #include "freem.h"
46: #include "mref.h"
47:
48:
49: short evt_async_enabled = FALSE;
50: short evt_async_restore = FALSE;
51: short evt_async_initial = FALSE;
52:
53: short evt_queue_rear = -1;
54: short evt_queue_front = -1;
55:
56: evt_entry *evt_queue[EVT_QLENGTH];
57: short evt_status[EVT_MAX];
58: int evt_blocks[EVT_MAX];
59: int evt_depth;
60:
61: void evt_init (void)
62: {
63: register int i;
64:
65: for(i = 0; i < EVT_MAX; i++) {
66: evt_status[i] = EVT_S_DISABLED;
67: evt_blocks[i] = 0;
68: }
69:
70: evt_async_enabled = FALSE;
71: evt_depth = 0;
72: }
73:
74: int evt_ablock (short evt_class)
75: {
76: register int i;
77: int unblocked_evt_count = 0;
78:
79: evt_blocks[evt_class]++;
80:
81: for (i = 0; i < EVT_MAX; i++) {
82: if (evt_blocks[i] == 0) unblocked_evt_count++;
83: }
84:
85: if (unblocked_evt_count == 0) evt_async_enabled = FALSE;
86:
87: return evt_blocks[evt_class];
88: }
89:
90: int evt_aunblock (short evt_class)
91: {
92: register int i;
93: int unblocked_evt_count = 0;
94:
95: if (evt_blocks[evt_class]) evt_blocks[evt_class]--;
96:
97: for (i = 0; i < EVT_MAX; i++) {
98: if (evt_blocks[i] == 0) unblocked_evt_count++;
99: }
100:
101: if (unblocked_evt_count) evt_async_enabled = TRUE;
102:
103: return evt_blocks[i - 1];
104: }
105:
106: int evt_enqueue (char *event_id, short evt_class, short interrupt)
107: {
108: evt_entry *e = malloc (sizeof (evt_entry));
109: NULLPTRCHK(e,"evt_enqueue");
110:
111: if (!evt_registered (event_id, evt_class)) {
112: free (e);
113: return -1;
114: }
115:
116: strncpy (e->event_id, event_id, 256);
117: e->evt_class = evt_class;
118:
119: if (evt_queue_rear == EVT_QLENGTH - 1) {
120: /* queue overflow */
121: free (e);
122: return -1;
123: }
124:
125: if (evt_queue_front == -1) evt_queue_front = 0;
126:
127: evt_queue[++evt_queue_rear] = e;
128:
129: if (interrupt && (evt_blocks[evt_class] == 0)) {
130: merr_raise (ASYNC);
131: }
132:
133: return evt_queue_rear;
134: }
135:
136: evt_entry *evt_dequeue (void)
137: {
138: evt_entry *e;
139:
140: if (evt_queue_front == -1 || evt_queue_front > evt_queue_rear) {
141: /* queue underflow */
142: return NULL;
143: }
144:
145: e = evt_queue[evt_queue_front++];
146:
147: return e;
148: }
149:
150:
151: char *evt_class_name (evt_entry *e) {
152:
153: char *evt_name = malloc (15 * sizeof (char));
154: NULLPTRCHK(evt_name,"evt_class_name");
155:
156: switch (e->evt_class) {
157:
158: case EVT_CLS_COMM:
159: strcpy (evt_name, "COMM");
160: break;
161:
162: case EVT_CLS_HALT:
163: strcpy (evt_name, "HALT");
164: break;
165:
166: case EVT_CLS_IPC:
167: strcpy (evt_name, "IPC");
168: break;
169:
170: case EVT_CLS_INTERRUPT:
171: strcpy (evt_name, "INTERRUPT");
172: break;
173:
174: case EVT_CLS_POWER:
175: strcpy (evt_name, "POWER");
176: break;
177:
178: case EVT_CLS_TIMER:
179: strcpy (evt_name, "TIMER");
180: break;
181:
182: case EVT_CLS_USER:
183: strcpy (evt_name, "USER");
184: break;
185:
186: case EVT_CLS_WAPI:
187: strcpy (evt_name, "WAPI");
188: break;
189:
190: case EVT_CLS_TRIGGER:
191: strcpy (evt_name, "TRIGGER");
192: break;
193:
194: }
195:
196: return evt_name;
197:
198: }
199:
200: char *evt_class_name_c (int c) {
201:
202: char *evt_name = malloc (15 * sizeof (char));
203: NULLPTRCHK(evt_name,"evt_class_name_c");
204:
205: switch (c) {
206:
207: case EVT_CLS_COMM:
208: strcpy (evt_name, "COMM");
209: break;
210:
211: case EVT_CLS_HALT:
212: strcpy (evt_name, "HALT");
213: break;
214:
215: case EVT_CLS_IPC:
216: strcpy (evt_name, "IPC");
217: break;
218:
219: case EVT_CLS_INTERRUPT:
220: strcpy (evt_name, "INTERRUPT");
221: break;
222:
223: case EVT_CLS_POWER:
224: strcpy (evt_name, "POWER");
225: break;
226:
227: case EVT_CLS_TIMER:
228: strcpy (evt_name, "TIMER");
229: break;
230:
231: case EVT_CLS_USER:
232: strcpy (evt_name, "USER");
233: break;
234:
235: case EVT_CLS_WAPI:
236: strcpy (evt_name, "WAPI");
237: break;
238:
239: case EVT_CLS_TRIGGER:
240: strcpy (evt_name, "TRIGGER");
241: break;
242:
243: }
244:
245: return evt_name;
246:
247: }
248:
249: int evt_get_handlers (char *buf) {
250:
251: char *t_key;
252: char *class_name;
253: char *t_buf;
254: freem_ref_t *r;
255: freem_ref_t *rs;
256: char pid_s[10];
257: int ct;
258: evt_entry *e;
259:
260: class_name = malloc (256 * sizeof (char));
261: NULLPTRCHK(class_name,"evt_get_handlers");
262:
263: t_buf = malloc (STRLEN * sizeof (char));
264: NULLPTRCHK(t_buf,"evt_get_handlers");
265:
266: r = malloc (sizeof (freem_ref_t));
267: NULLPTRCHK(r,"evt_get_handlers");
268:
269: rs = malloc (sizeof (freem_ref_t));
270: NULLPTRCHK(rs,"evt_get_handlers");
271:
272: ct = 0;
273: t_buf[0] = '\201';
274:
275: mref_init (r, MREF_RT_SSVN, "^$JOB");
276: mref_init (rs, MREF_RT_SSVN, "^$SYSTEM");
277:
278: snprintf (pid_s, 9, "%d", pid);
279:
280:
281: while ((e = evt_dequeue ()) != NULL) {
282:
283: if (evt_status[e->evt_class] > EVT_S_DISABLED) {
284: class_name = evt_class_name (e);
285:
286: mref_set_subscript (r, 0, pid_s);
287: mref_set_subscript (r, 1, "EVENT");
288: mref_set_subscript (r, 2, class_name);
289: mref_set_subscript (r, 3, e->event_id);
290:
291: t_key = mref_to_internal (r);
292: ssvn (get_sym, t_key, t_buf);
293: free (t_key);
294: stcnv_m2c (t_buf);
295:
296: if (strlen (t_buf) > 0) {
297:
298: ct++;
299:
300: strcat (buf, t_buf);
301: strcat (buf, ",");
302: }
303:
304: mref_set_subscript (rs, 0, "EVENT");
305: mref_set_subscript (rs, 1, class_name);
306: mref_set_subscript (rs, 2, e->event_id);
307:
308: t_key = mref_to_internal (rs);
309: ssvn (get_sym, t_key, t_buf);
310: free (t_key);
311: stcnv_m2c (t_buf);
312:
313: if (strlen (t_buf) > 0) {
314:
315: ct++;
316:
317: strcat (buf, t_buf);
318: strcat (buf, ",");
319: }
320:
321: }
322:
323: free (e);
324:
325: }
326:
327: if (ct) {
328: buf[strlen (buf) - 1] = NUL;
329: }
330: else {
331: buf[0] = NUL;
332: }
333:
334: free (r);
335: free (rs);
336: free (class_name);
337: free (t_buf);
338:
339: return ct;
340: }
341:
342: short evt_registered (char *event_id, short evt_class)
343: {
344: char *t_key;
345: char *class_name;
346: char *t_buf;
347: freem_ref_t *r;
348: freem_ref_t *rs;
349: char pid_s[10];
350: int ct;
351:
352: t_key = malloc (256 * sizeof (char));
353: NULLPTRCHK(t_key,"evt_registered");
354:
355: class_name = malloc (256 * sizeof (char));
356: NULLPTRCHK(class_name,"evt_registered");
357:
358: t_buf = malloc (STRLEN * sizeof (char));
359: NULLPTRCHK(t_buf,"evt_registered");
360:
361:
362: r = malloc (sizeof (freem_ref_t));
363: NULLPTRCHK(r,"evt_registered");
364:
365: rs = malloc (sizeof (freem_ref_t));
366: NULLPTRCHK(rs,"evt_registered");
367:
368: ct = 0;
369: t_buf[0] = '\201';
370:
371: mref_init (r, MREF_RT_SSVN, "^$JOB");
372:
373: snprintf (pid_s, 9, "%d", pid);
374:
375: class_name = evt_class_name_c (evt_class);
376:
377: mref_set_subscript (r, 0, pid_s);
378: mref_set_subscript (r, 1, "EVENT");
379: mref_set_subscript (r, 2, class_name);
380: mref_set_subscript (r, 3, event_id);
381:
382: t_key = mref_to_internal (r);
383:
384: ssvn (get_sym, t_key, t_buf);
385: stcnv_m2c (t_buf);
386:
387: if (strlen (t_buf) > 0) ct++;
388:
389: mref_init (rs, MREF_RT_SSVN, "^$SYSTEM");
390:
391: mref_set_subscript (rs, 0, "EVENT");
392: mref_set_subscript (rs, 1, class_name);
393: mref_set_subscript (rs, 2, event_id);
394:
395: t_key = mref_to_internal (rs);
396:
397: ssvn (get_sym, t_key, t_buf);
398: stcnv_m2c (t_buf);
399:
400: if (strlen (t_buf) > 0) ct++;
401:
402: free (r);
403: free (rs);
404: free (t_key);
405: free (class_name);
406: free (t_buf);
407:
408: return (ct > 0) ? TRUE : FALSE;
409: }