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