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>