Annotation of freem/src/events.c, revision 1.5

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>