コード例 #1
0
ファイル: gvzwrite_clnup.c プロジェクト: CeperaCPP/fis-gtm
void	gvzwrite_clnup(void)
{
	gv_key		*old;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	gv_cur_region = gvzwrite_block->gd_reg;
	change_reg();
	assert(reset_gv_target == ((gv_namehead *)gvzwrite_block->old_targ));
	if (NULL != gvzwrite_block->old_key)
	{
		old = (gv_key *)gvzwrite_block->old_key;
		memcpy(&gv_currkey->base[0], &old->base[0], old->end + 1);
		gv_currkey->end = old->end;
		gv_currkey->prev = old->prev;
		gd_map = gvzwrite_block->old_map;
		gd_map_top = gvzwrite_block->old_map_top;
		free(gvzwrite_block->old_key);
		gvzwrite_block->old_key = gvzwrite_block->old_targ = (unsigned char *)NULL;
		gvzwrite_block->subsc_count = 0;
		TREF(gv_last_subsc_null) = gvzwrite_block->gv_last_subsc_null;
		TREF(gv_some_subsc_null) = gvzwrite_block->gv_some_subsc_null;
	}
	RESET_GV_TARGET(DO_GVT_GVKEY_CHECK);
}
コード例 #2
0
ファイル: preemptive_db_clnup.c プロジェクト: mihawk/fis-gtm
void preemptive_db_clnup(int preemptive_severe)
{
	sgmnt_addrs	*csa;
	sgm_info	*si;
	gd_region	*r_top, *reg;
	gd_addr		*addr_ptr;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	/* Clear "inctn_opcode" global variable now that any in-progress transaction is aborted at this point.
	 * Not doing so would cause future calls to "t_end" to get confused and skip writing logical jnl recs
	 * and instead incorrectly write an INCTN record (GTM-8425).
	 */
	if (bml_save_dollar_tlevel)
	{
		assert(!dollar_tlevel);
		dollar_tlevel = bml_save_dollar_tlevel;
		bml_save_dollar_tlevel = 0;
	}
	assert(!dollar_tlevel || (inctn_invalid_op == inctn_opcode) || (inctn_bmp_mark_free_gtm == inctn_opcode));
	assert(dollar_tlevel || update_trans || (inctn_invalid_op == inctn_opcode));
	inctn_opcode = inctn_invalid_op;
	if (!dollar_tlevel && update_trans)
	{	/* It's possible we hit an error in the middle of an update, at which point we have
		 * a valid clue and non-NULL cse. However, this causes problems for subsequent
		 * transactions (see comment in t_begin). In particular we could end up pinning buffers
		 * unnecessarily. So clear the cse of any histories that may have been active during the update.
		 */
		CLEAR_CSE(gv_target);
		if ((NULL != gv_target) && (NULL != gv_target->gd_csa))
		{
			CLEAR_CSE(gv_target->gd_csa->dir_tree);
			GTMTRIG_ONLY(CLEAR_CSE(gv_target->gd_csa->hasht_tree));
		}
		/* Resetting this is necessary to avoid blowing an assert in t_begin that it is 0 at the start of a transaction. */
		update_trans = 0;
	}
	if (INVALID_GV_TARGET != reset_gv_target)
	{
		if (SUCCESS != preemptive_severe && INFO != preemptive_severe)
		{
			/* We know of a few cases in Unix where gv_target and gv_currkey could be out of sync at this point.
			 *   a) If we are inside trigger code which in turn does an update that does
			 *	reads of ^#t global and ends up in a restart. This restart would
			 *	in turn do a rts_error_csa(TPRETRY) which would invoke mdb_condition_handler
			 *	that would in turn invoke preemptive_db_clnup which invokes this macro.
			 *	In this tp restart case though, it is ok for gv_target and gv_currkey
			 *	to be out of sync because they are going to be reset by tp_clean_up anyways.
			 *	So skip the dbg-only in-sync check.
			 *   b) If we are in gvtr_init reading the ^#t global and detect an error (e.g. TRIGINVCHSET)
			 *	gv_target after the reset would be pointing to a regular global whereas gv_currkey
			 *	would be pointing to ^#t. It is ok to be out-of-sync since in this case, we expect
			 *	mdb_condition_handler to be calling us. That has code to reset gv_currkey (and
			 *	cs_addrs/cs_data etc.) to reflect gv_target (i.e. get them back in sync).
			 * Therefore in Unix we pass SKIP_GVT_GVKEY_CHECK to skip the gvtarget/gvcurrkey out-of-sync check
			 * in RESET_GV_TARGET. In VMS we pass DO_GVT_GVKEY_CHECK as we dont yet know of an out-of-sync situation.
			 */
			RESET_GV_TARGET(UNIX_ONLY(SKIP_GVT_GVKEY_CHECK) VMS_ONLY(DO_GVT_GVKEY_CHECK));
		}
	}
	need_kip_incr = FALSE;	/* in case we got an error in t_end (e.g. GBLOFLOW), dont want this global variable to get
				 * carried over to the next non-TP transaction that this process does (e.g. inside an error trap).
				 */
	TREF(expand_prev_key) = FALSE;	/* reset global (in case it is TRUE) so it does not get carried over to future operations */
	if (dollar_tlevel)
	{
		for (si = first_sgm_info;  si != NULL; si = si->next_sgm_info)
		{
			if (NULL != si->kip_csa)
			{
				csa = si->tp_csa;
				assert(si->tp_csa == si->kip_csa);
				PROBE_DECR_KIP(csa->hdr, csa, si->kip_csa);
			}
		}
	} else if (NULL != kip_csa && (NULL != kip_csa->hdr) && (NULL != kip_csa->nl))
		PROBE_DECR_KIP(kip_csa->hdr, kip_csa, kip_csa);
	if (IS_DSE_IMAGE)
	{	/* Release crit on any region that was obtained for the current erroring DSE operation.
		 * Take care NOT to release crits obtained by a previous CRIT -SEIZE command.
		 */
		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;
					assert(csa->hold_onto_crit || !csa->dse_crit_seize_done);
					assert(!csa->hold_onto_crit || csa->now_crit);
					if (csa->now_crit && (!csa->hold_onto_crit || !csa->dse_crit_seize_done))
					{
						rel_crit(reg);
						csa->hold_onto_crit = FALSE;
						t_abort(reg, csa);	/* cancel mini-transaction if any in progress */
					}
				}
			}
		}
	}
}