fis-gtm/sr_port/jobinterrupt_process.c

125 lines
4.6 KiB
C

/****************************************************************
* *
* Copyright 2001, 2011 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#include "error.h"
#include "indir_enum.h"
#include <rtnhdr.h>
#include "op.h"
#include "stack_frame.h"
#include "error_trap.h"
#include "mv_stent.h"
#include "gtm_stdio.h"
#include "stringpool.h"
#include "jobinterrupt_process.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "hashtab_int4.h"
#include "gdskill.h"
#include "jnl.h"
#include "gdscc.h"
#include "buddy_list.h"
#include "tp.h"
#include "gvname_info.h"
#include "op_merge.h"
#include "zwrite.h"
#include "zshow.h"
GBLREF stack_frame *frame_pointer, *error_frame;
GBLREF unsigned char *stackbase, *stacktop, *msp, *stackwarn;
GBLREF spdesc stringpool;
GBLREF mval dollar_zinterrupt;
GBLREF boolean_t dollar_zininterrupt;
GBLREF unsigned short proc_act_type;
GBLREF mv_stent *mv_chain;
GBLREF int dollar_truth;
GBLREF mstr extnam_str;
GBLREF unsigned char *restart_pc, *restart_ctxt;
GBLREF dollar_ecode_type dollar_ecode;
GBLREF dollar_stack_type dollar_stack;
GBLREF int merge_args;
GBLREF uint4 zwrtacindx;
GBLREF merge_glvn_ptr mglvnp;
GBLREF gvzwrite_datablk *gvzwrite_block;
GBLREF lvzwrite_datablk *lvzwrite_block;
GBLREF zshow_out *zwr_output;
GBLREF zwr_hash_table *zwrhtab;
error_def(ERR_STACKOFLOW);
error_def(ERR_STACKCRIT);
void jobinterrupt_process(void)
{
mv_stent *mv_st_ent;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
assert(dollar_zininterrupt);
/* Compile and push new (counted) frame onto the stack to drive the
* $zinterrupt handler.
*/
assert((SFT_COUNT | SFT_ZINTR) == proc_act_type);
op_commarg(&dollar_zinterrupt, indir_linetail);
frame_pointer->type = proc_act_type; /* The mark of zorro.. */
proc_act_type = 0;
/* Save restart_pc/ctxt so a resumed frame or ztrap can resume in the corrct place and
* not and inappropriate resume point determined by the interrupting code.
*/
PUSH_MV_STENT(MVST_RSTRTPC);
mv_st_ent = mv_chain;
mv_st_ent->mv_st_cont.mvs_rstrtpc.restart_pc_save = restart_pc;
mv_st_ent->mv_st_cont.mvs_rstrtpc.restart_ctxt_save = restart_ctxt;
/* Now we need to preserve our current environment. This MVST_ZINTR mv_stent type will hold
* the items deemed necessary to preserve. All other items are the user's responsibility.
*
* Initialize the mv_stent elements processed by stp_gcol which can be called for either the
* op_gvsavtarg() or extnam items. This initialization keeps stp_gcol from attempting to
* process unset fields with garbage in them as valid mstr address/length pairs.
*/
PUSH_MV_STENT(MVST_ZINTR);
mv_st_ent = mv_chain;
mv_st_ent->mv_st_cont.mvs_zintr.savtarg.str.len = 0;
mv_st_ent->mv_st_cont.mvs_zintr.savextref.len = 0;
mv_st_ent->mv_st_cont.mvs_zintr.saved_dollar_truth = dollar_truth;
op_gvsavtarg(&mv_st_ent->mv_st_cont.mvs_zintr.savtarg);
if (extnam_str.len)
{
ENSURE_STP_FREE_SPACE(extnam_str.len);
mv_st_ent->mv_st_cont.mvs_zintr.savextref.addr = (char *)stringpool.free;
memcpy(mv_st_ent->mv_st_cont.mvs_zintr.savextref.addr, extnam_str.addr, extnam_str.len);
stringpool.free += extnam_str.len;
assert(stringpool.free <= stringpool.top);
}
mv_st_ent->mv_st_cont.mvs_zintr.savextref.len = extnam_str.len;
/* save/restore $ECODE/$STACK over this invocation */
mv_st_ent->mv_st_cont.mvs_zintr.error_frame_save = error_frame;
memcpy(&mv_st_ent->mv_st_cont.mvs_zintr.dollar_ecode_save, &dollar_ecode, SIZEOF(dollar_ecode));
memcpy(&mv_st_ent->mv_st_cont.mvs_zintr.dollar_stack_save, &dollar_stack, SIZEOF(dollar_stack));
NULLIFY_ERROR_FRAME;
ecode_init();
/* If we interrupted a Merge, ZWrite, or ZShow, save the state info in an mv_stent that will be restored when this
* interrupt frame returns. Note that at this time, return from an interrupt does not "return" to the interrupt
* point but rather restarts the line of M code we were running *OR* at the most recent save point (set by
* op_restartpc or equivalent). In the future this is likely to change, at least for an interrupted Merge, ZWrite
* or ZShow command, so this save/restore is appropriate both now (to let these nest at all) and especially in the future.
*/
if (TREF(in_zwrite) || (0 != merge_args))
PUSH_MVST_MRGZWRSV;
return;
}