1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
/****************************************************************
* *
* Copyright (c) 2001-2024 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* 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 "gdsroot.h"
#include "gdsbt.h"
#include "gdsblk.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "error.h"
#include "gt_timer.h"
#include "util.h"
#include "gv_rundown.h"
#include "print_exit_stats.h"
#include "repl_msg.h" /* needed for jnlpool_addrs_ptr_t */
#include "gtmsource.h" /* needed for jnlpool_addrs_ptr_t */
#include "secshr_db_clnup.h"
#include "gtmimagename.h"
#include "dpgbldir.h"
#include "gtmcrypt.h"
#include "interlock.h"
#include "mlkdef.h"
#include "mlk_ops.h"
GBLREF boolean_t need_core;
GBLREF boolean_t created_core;
GBLREF boolean_t exit_handler_active;
GBLREF boolean_t skip_exit_handler;
GBLREF uint4 dollar_tlevel;
GBLREF uint4 process_id;
void util_exit_handler()
{
int stat;
gd_region *r_top, *reg;
sgmnt_addrs *csa;
gd_addr *addr_ptr;
if (exit_handler_active || skip_exit_handler) /* Skip exit handling if specified or if exit handler already active */
return;
exit_handler_active = TRUE;
SET_PROCESS_EXITING_TRUE; /* Set this BEFORE canceling timers as wcs_phase2_commit_wait relies on this */
if (IS_DSE_IMAGE)
{ /* Need to clear csa->hold_onto_crit in case it was set. This needs to be done before the call to
* secshr_db_clnup() which, if we still hold it, will take care of releasing crit at the appropriate point.
*/
for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
{
for (reg = addr_ptr->regions, r_top = reg + addr_ptr->n_regions; reg < r_top; reg++)
{
if (reg->open && !reg->was_open)
{
csa = &FILE_INFO(reg)->s_addrs;
csa->hold_onto_crit = FALSE; /* need to do this before the rel_crit */
/* If this is an normal (non-error) exit (as determiend by the severity var), go ahead
* and release crit if we are holding it as that secshr_db_clnup() from forcing an
* unneeded cache recovery. However, if this *IS* an error condition, we leave crit
* alone and let secshr_db_clnup() deal with it appropriately.
*/
if ((0 == severity) && !csa->lock_crit_with_db && LOCK_CRIT_HELD(csa))
{
mlk_pvtctl pctl;
MLK_PVTCTL_INIT(pctl, reg);
REL_LOCK_CRIT(&pctl, FALSE);
}
if ((0 == severity) && csa->now_crit)
rel_crit(reg);
}
}
}
}
CANCEL_TIMERS; /* Cancel all unsafe timers - No unpleasant surprises */
/* Note we call secshr_db_clnup() with the flag NORMAL_TERMINATION even in an error condition
* here because we know at this point that we aren't in the middle of a transaction but we may
* be holding crit in one or more regions and/or we could have other odds/ends to cleanup.
*/
secshr_db_clnup(NORMAL_TERMINATION);
WITH_CH(exi_ch, gv_rundown(), if(FALSE));
print_exit_stats();
util_out_close();
GTMCRYPT_CLOSE;
if (need_core && !created_core)
DUMP_CORE;
}
|