fis-gtm/sr_unix/gtm_trigger.h

93 lines
4.9 KiB
C

/****************************************************************
* *
* Copyright 2010 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. *
* *
****************************************************************/
#ifndef GTM_TRIGGER_H
#define GTM_TRIGGER_H
#include "gtm_trigger_trc.h"
#define TRIGGER_NAME_RESERVED_SPACE 2 /* Reserved space in trigger name to make name unique if needbe */
/* This macro is used where it is possible for the top frame to be a trigger base frame if we are in
* "trigger-no-mans-land" which is characterized by us having created the trigger base frame but no
* trigger execution frame on the stack that would have incremented gtm_trigger_depth (gtm_trigger_depth
* is only incremented for the duration of the trigger execution frame which also means gtm_trigger and
* dm_start are also on the stack). To be in this state at this point, we must have driven at least one of
* a parallel trigger set, returned back to gvtr_match_n_invoke, then, while retrieving the trigger source
* for the next parallel trigger, we hit a restart condition. There are a few different handlers than can
* catch this condition depending on where this macro is used but they all share one thing in common:
* In a normal restart condition while the trigger is running, gtm_trigger itself will unwind the trigger
* base frame during restarts but in this condition where we are in "trigger-no-mans-land", we need to
* unwind the trigger. We use an interuptable state flag that contains this nomansland state to determine
* if we are eligible for this unwind. If not, this is an out-of-design condition we need to protect
* against.
*/
#define TRIGGER_BASE_FRAME_UNWIND_IF_NOMANSLAND \
{ \
if (SFT_TRIGR & frame_pointer->type) \
{ \
if (INTRPT_IN_TRIGGER_NOMANS_LAND == intrpt_ok_state) \
{ /* Remove this errant frame and continue to restart */ \
DBGTRIGR((stderr, "%s: trigger-no-mans-land situation - removing trigger " \
"base frame\n", __FILE__)); \
gtm_trigger_fini(FALSE, FALSE); \
} else \
/* Bad mojo - not in trigger-no-mans-land - unknown issue to protect against */ \
GTMASSERT; \
} \
}
typedef enum
{ /* Trigger rethrow types */
trigr_rethrow_nil,
trigr_rethrow_zg1, /* Rethrow level-only ZGOTO (op_zg1) */
trigr_rethrow_zgoto, /* Rethrow level/entryref ZGOTO (op_zgoto) */
trigr_rethrow_goerrorfrm /* Rethrow goerrorframe() unwind */
} trigr_rethrow_t;
/* Second parm to gtm_trigger() containing non-static type items for a given trigger */
typedef struct
{
mval *ztoldval_new; /* mval to set into $ZTOLDVAL.
* Points to stringpool at "gtm_trigger" entry - is NOT updated by the function */
mval *ztvalue_new; /* mval for current value to set into $ZTVALUE.
* Points to stringpool at "gtm_trigger" entry.
*/
const mval *ztdata_new; /* $Data status of trigger value being Set/Killed - points to a constant mval
* in mtables.c */
const mval *ztriggerop_new; /* Opcode type invoking the trigger - points to a constant mval in mtables.c */
mval *ztupdate_new; /* mval to set into $ZTUPDATE.
* Points to stringpool at "gtm_trigger" entry - is NOT updated by the function */
mval **lvvalarray; /* Value array for lvs named in "lvnamearray" member of gv_trigger_t structure.
* Values are derived from subscripts of matching key at runtime.
* Note that this points to an array of "mval *" each of which in turn point to
* mvals in the M-stack whose strings point to the stringpool.
* For performance reasons, we keep this an array of trigdsc->numsubs entries
* (not trigdsc->numlvsubs entries). So "gtm_trigger" has to look at
* trigdsc->lvindexarray and figure out the actual indices which correspond to
* local variables of interest to that trigdsc and obtain the corresponding
* indices from this array to get the actual local variable values.
* Points to stringpool at "gtm_trigger" entry - is NOT updated by the function */
boolean_t ztvalue_changed; /* Set to TRUE if $ZTVALUE was changed inside the trigger. "ztvalue_new" member
* is updated to point to the new value (in the stringpool) in this case.
*/
/* All above "mval *" fields that point to the stringpool have their corresponding mvals pushed onto the M-stack
* so they are safe from stp_gcol already. No special care needs to be taken by the function "gtm_trigger" for this.
*/
} gtm_trigger_parms;
int gtm_trigger(gv_trigger_t *trigdsc, gtm_trigger_parms *trigprm);
void gtm_trigger_fini(boolean_t forced_unwind, boolean_t fromzgoto);
void gtm_trigger_cleanup(gv_trigger_t *trigdsc);
int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink);
#endif