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: }