int read_event_notify(int descr, dbref player, const char* cmd) { timequeue ptr; if (muf_event_read_notify(descr, player, cmd)) { return 1; } ptr = tqhead; while (ptr) { if (ptr->uid == player) { if (ptr->fr && ptr->fr->multitask != BACKGROUND) { if (*cmd || ptr->fr->wantsblanks) { struct inst temp; temp.type = PROG_INTEGER; temp.data.number = descr; muf_event_add(ptr->fr, "READ", &temp, 1); return 1; } } } ptr = ptr->next; } return 0; }
void prim_watchpid(PRIM_PROTOTYPE) { struct frame *frame; CHECKOP(1); oper1 = POP(); if (mlev < 3) { abort_interp("Mucker level 3 required."); } if (oper1->type != PROG_INTEGER) { abort_interp("Process PID expected."); } /* Lets see if the batbat catches this one. */ /* Heh. - Revar */ if (oper1->data.number == fr->pid) { abort_interp("Narcissistic processes not allowed."); } frame = timequeue_pid_frame (oper1->data.number); if (frame) { struct mufwatchpidlist **cur; struct mufwatchpidlist *waitee; for (cur = &frame->waiters; *cur; cur = &(*cur)->next) { if ((*cur)->pid == oper1->data.number) { break; } } if (!*cur) { *cur = (struct mufwatchpidlist*) malloc (sizeof (**cur)); if (!*cur) { abort_interp ("Internal memory error.\n"); } (*cur)->next = 0; (*cur)->pid = fr->pid; waitee = (struct mufwatchpidlist*) malloc (sizeof (*waitee)); if (!waitee) { abort_interp ("Internal memory error.\n"); } waitee->next = fr->waitees; waitee->pid = oper1->data.number; fr->waitees = waitee; } } else { char buf[64]; snprintf (buf, sizeof(buf), "PROC.EXIT.%d", oper1->data.number); muf_event_add(fr, buf, oper1, 0); } CLEAR (oper1); }
/* clean up lists from watchpid and sends event */ void watchpid_process(struct frame *fr) { if (!fr) { log_status("WARNING: watchpid_process(): NULL frame passed ! Ignored."); return; } struct frame *frame; struct mufwatchpidlist *cur; struct mufwatchpidlist **curptr; struct inst temp1; temp1.type = PROG_INTEGER; temp1.data.number = fr->pid; while (fr->waitees) { cur = fr->waitees; fr->waitees = cur->next; frame = timequeue_pid_frame (cur->pid); free (cur); if (frame) { for (curptr = &frame->waiters; *curptr; curptr = &(*curptr)->next) { if ((*curptr)->pid == fr->pid) { cur = *curptr; *curptr = (*curptr)->next; free (cur); break; } } } } while (fr->waiters) { char buf[64]; snprintf (buf, sizeof(buf), "PROC.EXIT.%d", fr->pid); cur = fr->waiters; fr->waiters = cur->next; frame = timequeue_pid_frame (cur->pid); free (cur); if (frame) { muf_event_add(frame, buf, &temp1, 0); for (curptr = &frame->waitees; *curptr; curptr = &(*curptr)->next) { if ((*curptr)->pid == fr->pid) { cur = *curptr; *curptr = (*curptr)->next; free (cur); break; } } } } }
void prim_event_send(PRIM_PROTOTYPE) { struct frame *destfr; stk_array *arr; struct inst temp1; CHECKOP(3); oper3 = POP(); /* any: data to pass */ oper2 = POP(); /* string: event id */ oper1 = POP(); /* int: process id to send to */ if (mlev < 3) abort_interp("Requires Mucker level 3 or better."); if (oper1->type != PROG_INTEGER) abort_interp("Expected an integer process id. (1)"); if (oper2->type != PROG_STRING) abort_interp("Expected a string event id. (2)"); if (oper1->data.number == fr->pid) destfr = fr; else destfr = timequeue_pid_frame(oper1->data.number); if (destfr) { stk_array_active_list = &destfr->array_active_list; struct inst data_copy; deep_copyinst(oper3, &data_copy, destfr->pinning); arr = new_array_dictionary(destfr->pinning); array_set_strkey(&arr, "data", &data_copy); array_set_strkey_intval(&arr, "caller_pid", fr->pid); array_set_strkey_intval(&arr, "descr", fr->descr); array_set_strkey_refval(&arr, "caller_prog", program); array_set_strkey_refval(&arr, "trigger", fr->trig); array_set_strkey_refval(&arr, "prog_uid", ProgUID); array_set_strkey_refval(&arr, "player", player); temp1.type = PROG_ARRAY; temp1.data.array = arr; snprintf(buf, sizeof(buf), "USER.%.32s", DoNullInd(oper2->data.string)); muf_event_add(destfr, buf, &temp1, 0); stk_array_active_list = &fr->array_active_list; CLEAR(&temp1); CLEAR(&data_copy); } CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); }
void prim_event_send(PRIM_PROTOTYPE) { struct frame *destfr; stk_array *arr; struct inst temp1; CHECKOP(3); oper3 = POP(); /* any: data to pass */ oper2 = POP(); /* string: event id */ oper1 = POP(); /* int: process id to send to */ if (mlev < 3) abort_interp("Requires Mucker level 3 or better."); if (oper1->type != PROG_INTEGER) abort_interp("Expected an integer process id. (1)"); if (oper2->type != PROG_STRING) abort_interp("Expected a string event id. (2)"); destfr = (struct frame*) timequeue_pid_frame(oper1->data.number); if (destfr) { arr = new_array_dictionary(); array_set_strkey(&arr, "data", oper3); array_set_strkey_intval(&arr, "caller_pid", fr->pid); array_set_strkey_refval(&arr, "caller_prog", program); temp1.type = PROG_ARRAY; temp1.data.array = arr; sprintf(buf, "USER.%.32s", DoNullInd(oper2->data.string)); muf_event_add(destfr, buf, oper3); } CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); }
void next_timequeue_event(void) { struct frame *tmpfr; int tmpbl, tmpfg; timequeue lastevent, event; int maxruns = 0; int forced_pid = 0; time_t rtime; time(&rtime); lastevent = tqhead; while ((lastevent) && (rtime >= lastevent->when) && (maxruns < 10)) { lastevent = lastevent->next; maxruns++; } while (tqhead && (tqhead != lastevent) && (maxruns--)) { if (tqhead->typ == TQ_MUF_TYP && tqhead->subtyp == TQ_MUF_READ) { break; } event = tqhead; tqhead = tqhead->next; process_count--; forced_pid = event->eventnum; event->eventnum = 0; if (event->typ == TQ_MPI_TYP) { char cbuf[BUFFER_LEN]; int ival; strcpyn(match_args, sizeof(match_args), event->str3 ? event->str3 : ""); strcpyn(match_cmdname, sizeof(match_cmdname), event->command ? event->command : ""); ival = (event->subtyp & TQ_MPI_OMESG) ? MPI_ISPUBLIC : MPI_ISPRIVATE; if (event->subtyp & TQ_MPI_BLESSED) { ival |= MPI_ISBLESSED; } if (event->subtyp & TQ_MPI_LISTEN) { ival |= MPI_ISLISTENER; do_parse_mesg(event->descr, event->uid, event->trig, event->called_data, "(MPIlisten)", cbuf, sizeof(cbuf), ival); } else if ((event->subtyp & TQ_MPI_SUBMASK) == TQ_MPI_DELAY) { do_parse_mesg(event->descr, event->uid, event->trig, event->called_data, "(MPIdelay)", cbuf, sizeof(cbuf), ival); } else { do_parse_mesg(event->descr, event->uid, event->trig, event->called_data, "(MPIqueue)", cbuf, sizeof(cbuf), ival); } if (*cbuf) { if (!(event->subtyp & TQ_MPI_OMESG)) { notify_filtered(event->uid, event->uid, cbuf, 1); } else { char bbuf[BUFFER_LEN]; dbref plyr; snprintf(bbuf, sizeof(bbuf), ">> %.4000s %.*s", NAME(event->uid), (int)(4000 - strlen(NAME(event->uid))), pronoun_substitute(event->descr, event->uid, cbuf)); plyr = DBFETCH(event->loc)->contents; for (; plyr != NOTHING; plyr = DBFETCH(plyr)->next) { if (Typeof(plyr) == TYPE_PLAYER && plyr != event->uid) notify_filtered(event->uid, plyr, bbuf, 0); } } } } else if (event->typ == TQ_MUF_TYP) { if (Typeof(event->called_prog) == TYPE_PROGRAM) { if (event->subtyp == TQ_MUF_DELAY) { /* Uncomment when DBFETCH "does" something */ /* FIXME: DBFETCH(event->uid); */ tmpbl = PLAYER_BLOCK(event->uid); tmpfg = (event->fr->multitask != BACKGROUND); interp_loop(event->uid, event->called_prog, event->fr, 0); if (!tmpfg) { PLAYER_SET_BLOCK(event->uid, tmpbl); } } else if (event->subtyp == TQ_MUF_TIMER) { struct inst temp; temp.type = PROG_INTEGER; temp.data.number = event->when; event->fr->timercount--; muf_event_add(event->fr, event->called_data, &temp, 0); } else if (event->subtyp == TQ_MUF_TREAD) { handle_read_event(event->descr, event->uid, NULL); } else { strcpyn(match_args, sizeof(match_args), event->called_data ? event->called_data : ""); strcpyn(match_cmdname, sizeof(match_cmdname), event->command ? event->command : ""); tmpfr = interp(event->descr, event->uid, event->loc, event->called_prog, event->trig, BACKGROUND, STD_HARDUID, forced_pid); if (tmpfr) { interp_loop(event->uid, event->called_prog, tmpfr, 0); } } } } event->fr = NULL; free_timenode(event); } }