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>