|
|
1.1 root 1: # include "ctlmod.h"
2: # include "pipes.h"
3: # include <resp.h>
4: # include <ingres.h>
5: # include <aux.h>
6: # include <tree.h>
7: # include <sccs.h>
8:
9: SCCSID(@(#)call.c 8.1 12/31/84)
10:
11: /*
12: ** CALL -- Call a state with return.
13: **
14: ** The state indicated by the indicated entry point is
15: ** called. Control will return to the current state.
16: **
17: ** If errflg is non-NULL, it is the address of a function
18: ** which is willing to handle error messages. If it is
19: ** NULL, the parent of this module (and so forth) will
20: ** handle the error message.
21: **
22: ** To call a module, the user should call 'initp' to
23: ** initialize a context in which the called module will
24: ** be executed. Parameters should then be initialized,
25: ** and then the module should be called. For instance:
26: ** initp();
27: ** init_qt(qmode); [only if we have a qtree parameter]
28: ** setp(PV_QTREE, qt, 0);
29: ** setp(PV_INT, ISAM, 0);
30: ** setp(PV_TUPLE, tup, tupsiz);
31: ** call(mdCREATE, catcherr);
32: **
33: ** Alternatively, the 'call' can be replaced with:
34: ** calln(mdCREATE, catcherr);
35: ** [save the return value if desired -- not in Qbuf!]
36: ** resetp();
37: **
38: ** Parameters:
39: ** entpt -- the entry point; indicates the starting
40: ** state. If zero, this is an error block.
41: ** errfn -- the address of an error function;
42: ** NULL indicates to pass errors to the
43: ** parent's error handling function.
44: **
45: ** Returns:
46: ** The return value of the final called state.
47: **
48: ** Side Effects:
49: ** Sets 'Resp' to be the response vector for the
50: ** final called function.
51: **
52: ** Trace Flags:
53: ** 5
54: */
55:
56: call(entpt, errfn)
57: int entpt;
58: int (*errfn)();
59: {
60: calln(entpt, errfn);
61: resetp();
62: return (Resp.resp_resp);
63: }
64: /*
65: ** CALLN -- just like a call, but keep the context around
66: **
67: ** Parameters:
68: ** (see call)
69: **
70: ** Returns:
71: ** (see call)
72: **
73: ** Side Effects:
74: ** (see call)
75: */
76:
77: calln(entpt, errfn)
78: int entpt;
79: int (*errfn)();
80: {
81: pb_t pb;
82: # ifdef xMONITOR
83: extern struct monitor CmMonBuf;
84: extern struct monitor MonBuf[];
85: struct monitor *savemon;
86: struct monitor mon;
87: extern struct monitor *markperf();
88: # endif MONITOR
89:
90: # ifdef xCTR1
91: if (tTf(5, 0))
92: lprintf("call: %d\n", entpt);
93: # endif
94: # ifdef xMONITOR
95: savemon = markperf(&CmMonBuf);
96: # endif xMONITOR
97:
98: /*
99: ** Select the starting state.
100: */
101:
102: if (entpt >= CM_MAXST || entpt < 0)
103: syserr("call: entpt %d", entpt);
104:
105: /*
106: ** Do final setup on context.
107: ** Set up the pipe buffer to use in this call.
108: ** Flag the end of the parmvect.
109: ** Save the error function address.
110: ** Save the monitor struct address. This monitor struct
111: ** will save the collective results of this
112: ** module & all children.
113: */
114:
115: pb_prime(&pb, PB_REG);
116: call_setup(&pb, entpt, errfn);
117: # ifdef xMONITOR
118: Ctx.ctx_mon = &mon;
119: clrmem(&mon, sizeof mon);
120: # endif xMONITOR
121:
122: /*
123: ** Do the sequence.
124: */
125:
126: # ifdef xCTR1
127: if (tTf(5, 2))
128: lprintf("call: ENT %d cmark %d pmark %d\n",
129: pb.pb_st, Ctx.ctx_cmark, Ctx.ctx_pmark);
130: # endif
131:
132: Ctx.ctx_new = FALSE;
133: do_seq(&pb);
134: Ctx.ctx_new = TRUE;
135:
136: # ifdef xMONITOR
137: markperf(savemon);
138: Resp.resp_time = mon.mon_utime + mon.mon_stime;
139: # endif xMONITOR
140:
141: # ifdef xCTR1
142: if (tTf(5, 3))
143: {
144: lprintf("call: EXIT entpt %d st %d\n", entpt, pb.pb_st);
145: printf("\tresp %7d\ttime %7ld\ttups %6ld\n",
146: Resp.resp_resp, Resp.resp_time, Resp.resp_tups);
147: printf("\tpread %6ld\tpwrit %6ld\n",
148: Resp.resp_pread, Resp.resp_pwrit);
149: }
150: # endif
151:
152: /*
153: ** Return the result of the final function in the chain.
154: */
155:
156: return (Resp.resp_resp);
157: }
158: /*
159: ** CALL_SETUP -- Do final setup for call
160: **
161: ** This routine just does the final setup before the main
162: ** part of a call. It is broken off here because it is
163: ** also used by 'error'.
164: **
165: ** Parameters:
166: ** ppb -- pointer to a pipe block to use for this
167: ** call.
168: ** state -- state we are going to enter.
169: ** errfn -- a pointer to the error function to use
170: ** for this call -- NULL if we want to send
171: ** to our parent.
172: **
173: ** Returns:
174: ** none.
175: **
176: ** Side Effects:
177: ** Does setup on *ppb, Ctx, and Resp.
178: **
179: ** Called By:
180: ** call
181: ** error
182: **
183: ** Trace Flags:
184: ** none.
185: */
186:
187: call_setup(ppb, state, errfn)
188: register pb_t *ppb;
189: int state;
190: int (*errfn)();
191: {
192: # ifdef xCTR1
193: if (tTf(5, 5))
194: {
195: lprintf("call_setup: st %d errfn %x\n", state, errfn);
196: prvect(Ctx.ctx_pc, Ctx.ctx_pv);
197: }
198: # endif
199: ppb->pb_st = state;
200: ppb->pb_resp = Cm.cm_myproc;
201: Ctx.ctx_pv[Ctx.ctx_pc].pv_type = PV_EOF;
202: Ctx.ctx_pv[Ctx.ctx_pc].pv_val.pv_str = NULL;
203: Ctx.ctx_ppb = ppb;
204: Ctx.ctx_errfn = errfn;
205: Ctx.ctx_init = FALSE;
206: /*
207: Resp.resp_rval.pv_type = PV_EOF;
208: */
209: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.