File:  [Coherent Logic Development] / freem / src / events.c
Revision 1.1: download - view: text, annotated - select for diffs
Sun Jan 19 02:04:04 2025 UTC (14 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Initial revision

    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>