|
|
1.1 ! root 1: # include "ctlmod.h" ! 2: # include "pipes.h" ! 3: # include <resp.h> ! 4: # include <sccs.h> ! 5: ! 6: SCCSID(@(#)do_seq.c 8.1 12/31/84) ! 7: ! 8: /* ! 9: ** DO_SEQ -- do sequence of states ! 10: ** ! 11: ** The sequence of states indicated by the start state ! 12: ** ppb->pb_st is executed. ! 13: ** ! 14: ** Recursion and multiple processes are implemented in ! 15: ** this routine. For each iteration through the top ! 16: ** loop, the next state to call is checked. If the state ! 17: ** is local (in this process), the state is executed and ! 18: ** the next state is computed. If the state is remote, ! 19: ** (contained in another process), we write out the ! 20: ** current call on a pipe which will (eventually) get ! 21: ** to the target process. In this case (and the system ! 22: ** reset case) the next state is unknown. This causes ! 23: ** this routine to read the input pipe for a command. ! 24: ** The command read is then executed -- notice that it ! 25: ** does not matter if this command is part of this level ! 26: ** of call (a sibling of the 'call'd process) or a lower ! 27: ** level (a descendent), since 'call' saved the state. ! 28: ** ! 29: ** If there are no more states in the chain after execution ! 30: ** of a local state, then a response block is generated. ! 31: ** The 'readinput' call can also generate one of these. ! 32: ** If the return is local (to this process), it is just ! 33: ** returned. Otherwise, it sends it off to the process ! 34: ** currently blocked for this state sequence to complete, ! 35: ** and the PB_UNKNOWN state is reentered. ! 36: ** ! 37: ** Parameters: ! 38: ** ppb -- a pointer to the pipe block which ! 39: ** (a) describes the state to call and ! 40: ** (b) provides an I/O area. ! 41: ** ! 42: ** Returns: ! 43: ** none ! 44: ** ! 45: ** Side Effects: ! 46: ** Lots. The side effects of all the states. ! 47: ** Leaves 'Resp' set to the response of the last ! 48: ** state in the chain. ! 49: ** ! 50: ** Called By: ! 51: ** call ! 52: ** main ! 53: ** ! 54: ** Trace Flags: ! 55: ** 2.0 - 2.7 ! 56: */ ! 57: ! 58: do_seq(ppb) ! 59: register pb_t *ppb; ! 60: { ! 61: register int i; ! 62: ! 63: /* ! 64: ** Top Loop. ! 65: ** Iterate until we have a response block intended ! 66: ** for this process (and hence this state, since ! 67: ** state invocations are properly nested inside ! 68: ** process invocations). ! 69: ** We also insure that we can always get at the ! 70: ** current pipe block. ! 71: ** ! 72: ** We return from the setjmp with non-zero value if ! 73: ** we get a fatal error. ! 74: */ ! 75: ! 76: Ctx.ctx_ppb = ppb; ! 77: if (setjmp(Ctx.ctx_jbuf) != 0) ! 78: return; ! 79: ! 80: for (;;) ! 81: { ! 82: # ifdef xCTR1 ! 83: if (tTf(2, 0)) ! 84: lprintf("do_seq: state %d\n", ppb->pb_st); ! 85: # endif ! 86: /* take cases */ ! 87: switch (ppb->pb_st) ! 88: { ! 89: case PB_UNKNOWN: ! 90: /* ! 91: ** Read the input and get a state, since we ! 92: ** don't have one already. This will set ! 93: ** Parmc & Parmv and change *ppb. The ! 94: ** state it found will be processed next ! 95: ** time through the loop. ! 96: */ ! 97: ! 98: readinput(ppb); ! 99: break; ! 100: ! 101: case PB_NONE: ! 102: /* ! 103: ** The 'no next state' case, i.e., a response. ! 104: ** This only happens if the response is ! 105: ** for this process, so we just return. ! 106: */ ! 107: ! 108: # ifdef xCTR1 ! 109: if (tTf(2, 1)) ! 110: lprintf("do_seq: exit\n"); ! 111: # endif ! 112: return; ! 113: ! 114: default: ! 115: /* ! 116: ** The state is known, let do_st do all ! 117: ** the dirty work. Hand it the global ! 118: ** Parmc & Parmv to pass to the function. ! 119: ** Do_st returns the next state to execute. ! 120: */ ! 121: ! 122: ppb->pb_st = i = do_st(ppb, Ctx.ctx_pc, Ctx.ctx_pv); ! 123: if (i == PB_NONE) ! 124: { ! 125: # ifdef xCM_DEBUG ! 126: if (ppb->pb_resp == PB_UNKNOWN) ! 127: syserr("do_seq: pb_resp"); ! 128: # endif ! 129: ppb->pb_proc = ppb->pb_resp; ! 130: if (ppb->pb_proc != Cm.cm_myproc) ! 131: { ! 132: /* write to correct process */ ! 133: pb_prime(ppb, PB_RESP); ! 134: send_off(ppb, 0, (PARM *)NULL); ! 135: pb_flush(ppb); ! 136: ! 137: /* next state is unknown */ ! 138: ppb->pb_st = PB_UNKNOWN; ! 139: } ! 140: } ! 141: break; ! 142: } ! 143: } ! 144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.