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

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: }

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