Annotation of freem/src/events.c, revision 1.1
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: *
! 18: * Author: Serena Willis <jpw@coherent-logic.com>
! 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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>