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: }
Defined functions
do_seq
defined in line
6; used 2 times