fis-gtm/sr_port/t_ch.c

98 lines
3.7 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 "cdb_sc.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsblk.h"
#include "gdsfhead.h"
#include "error.h"
#include "ast.h"
#include "send_msg.h"
#include "t_commit_cleanup.h"
#include "util.h"
#include "have_crit.h"
#include "filestruct.h"
#include "jnl.h"
GBLREF boolean_t created_core;
GBLREF boolean_t need_core;
GBLREF boolean_t dont_want_core;
GBLREF sgmnt_addrs *cs_addrs;
GBLREF uint4 dollar_tlevel;
GBLREF jnl_gbls_t jgbl;
CONDITION_HANDLER(t_ch)
{
boolean_t retvalue;
error_def(ERR_GTMCHECK);
error_def(ERR_GTMASSERT);
error_def(ERR_ASSERT);
error_def(ERR_MEMORY);
error_def(ERR_VMSMEMORY);
error_def(ERR_STACKOFLOW);
error_def(ERR_OUTOFSPACE);
START_CH;
UNIX_ONLY(
/* To get as virgin a state as possible in the core, take the core now if we
* would be doing so anyway. This will set created_core so it doesn't happen again.
*/
if (DUMPABLE)
{ /* this is most likely a fatal error, therefore print the error right here as we do not know if
* the send_msg() call in t_commit_cleanup() done below might overlay this primary fatal error.
*/
PRN_ERROR;
if (!SUPPRESS_DUMP)
{
need_core = TRUE;
gtm_fork_n_core();
}
}
)
if ((SUCCESS == SEVERITY) || (INFO == SEVERITY))
{ /* We dont know how it is possible to have a success or info type severity message show up while we are in
* the middle of a transaction commit. In any case, return right away instead of invoking t_commit_cleanup.
* The issue with invoking that is that it would complete the transaction and release crit but the NEXTCH
* call at the end of this condition handler would invoke the next level condition handler which could
* decide the message is innocuous and therefore decide to return control to where the error was signalled
* in the first place (in the midst of database commit) which can cause database damage since we no longer
* hold crit.
*/
assert(FALSE);
CONTINUE;
}
ENABLE_AST;
/* Reset jgbl.dont_reset_gbl_jrec_time to FALSE if already set by tp_tend and we come here due to an rts_error in wcs_flu.
* However, if it was forward recovery that ended up invoking tp_tend, then we should not reset the variable to FALSE as
* forward recovery keeps it set to TRUE for its entire duration. So, take that into account for the if check.
*/
if (jgbl.dont_reset_gbl_jrec_time && dollar_tlevel && !jgbl.forw_phase_recovery)
jgbl.dont_reset_gbl_jrec_time = FALSE;
/* We could go through all regions involved in the TP and check for crit on only those regions - instead we use an
* existing function "have_crit". If the design assumption that all crits held at transaction commit time are
* transaction related holds true, the result is the same and efficiency doesn't matter (too much) in exception handling.
*/
if ((!dollar_tlevel && T_IN_CRIT_OR_COMMIT(cs_addrs))
|| (dollar_tlevel && (0 != have_crit(CRIT_HAVE_ANY_REG | CRIT_IN_COMMIT))))
{
retvalue = t_commit_cleanup(cdb_sc_uperr, SIGNAL); /* if return value is TRUE, it means transaction commit has */
assert(!retvalue || DUMPABLE); /* started in which case we should not have come to t_ch() */
/* instead t_end/tp_tend would have called t_commit_cleanup */
}
NEXTCH;
}