File: process_gvt_pending_list.c

package info (click to toggle)
fis-gtm 6.3-007-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 36,284 kB
  • sloc: ansic: 328,861; asm: 5,182; csh: 5,102; sh: 1,918; awk: 291; makefile: 69; sed: 13
file content (139 lines) | stat: -rw-r--r-- 5,282 bytes parent folder | download | duplicates (2)
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/****************************************************************
 *								*
 * Copyright (c) 2008-2017 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 "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "dpgbldir.h"
#include "process_gvt_pending_list.h"
#include "targ_alloc.h"
#include "buddy_list.h"
#include "hashtab_mname.h"

GBLREF	gvt_container	*gvt_pending_list;
GBLREF	buddy_list	*gvt_pending_buddy_list;

gvt_container *is_gvt_in_pending_list(gv_namehead *gvt)
{
	gvt_container	*gvtc;

	for (gvtc = gvt_pending_list; NULL != gvtc; gvtc = (gvt_container *)gvtc->next_gvtc)
	{
		if (*gvtc->gvt_ptr == gvt)
			return gvtc;
	}
	return NULL;
}

/* Now that "reg" is being opened, process list of gv_targets that were allocated BEFORE reg got opened to see
 * if they need to be re-allocated (due to differences in reg->max_key_size versus csa->hdr->max_key_size).
 */
void process_gvt_pending_list(gd_region *reg, sgmnt_addrs *csa)
{
	gvt_container		*gvtc, *next_gvtc, *prev_gvtc;
	gv_namehead		*old_gvt, *new_gvt, *gvtarg;
	int4			db_max_key_size;
	boolean_t		added, first_wasopen;
	ht_ent_mname		*stayent, *old_gvt_ent;
	hash_table_mname	*gvt_hashtab;
	gd_addr			*gd_iter;
#	ifdef DEBUG
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
#	endif
	for (prev_gvtc = NULL, gvtc = gvt_pending_list; NULL != gvtc; gvtc = next_gvtc)
	{
		/* note down next_gvtc first thing before any continues or frees as next iteration relies on this */
		next_gvtc = (gvt_container *)gvtc->next_gvtc;
		old_gvt = *gvtc->gvt_ptr;
		assert(NULL == old_gvt->gd_csa);
		if (reg != gvtc->gd_reg)
		{
			prev_gvtc = gvtc;
			continue;
		}
		old_gvt->gd_csa = csa;	/* set csa now that we have just opened the region */
		db_max_key_size = csa->hdr->max_key_size;
		/* Remove the to-be-processed gvtc from the linked list since TARG_FREE_IF_NEEDED relies on this */
		if (NULL == prev_gvtc)
			gvt_pending_list = next_gvtc;	/* removing first element in linked list */
		else
		{
			assert(prev_gvtc->gd_reg != reg);
			prev_gvtc->next_gvtc = (struct gvt_container_struct *)next_gvtc;
		}
		if (NULL != (gvt_hashtab = csa->gvt_hashtab))
			added = add_hashtab_mname(gvt_hashtab, &old_gvt->gvname, old_gvt, &stayent);
		else
		{
			added = TRUE;	/* even though there is no hashtable set added so we go through the appropriate codepath */
			stayent = NULL;
		}
		if (added)
		{	/* Global name not already present in csa->gvt_hashtab. So old_gvt got added into the hashtable.
			 * But before that, check for differing key sizes between reg and db hdr in which case we need to
			 * allocate a new_gvt (with the bigger key size) and add new_gvt instead into csa->gvt_hashtab.
			 */
			if (reg->max_key_size != db_max_key_size)
			{	/* key sizes are different, need to reallocate */
				assert(IS_REG_BG_OR_MM(reg));
				new_gvt = (gv_namehead *)targ_alloc(db_max_key_size, &old_gvt->gvname, reg);
				new_gvt->noisolation = old_gvt->noisolation;	/* Copy over noisolation status from old_gvt */
				new_gvt->act = old_gvt->act; /* copy over act,nct,ver from old_gvt (actually from the gld file) */
				new_gvt->nct = old_gvt->nct;
				new_gvt->ver = old_gvt->ver;
				assert(!reg->open);
				/* reg is not yet open but we know csa is already available so set it appropriately */
				new_gvt->gd_csa = csa;
				if (NULL != stayent)
					stayent->value = new_gvt;
			} else
				new_gvt = NULL; /* No change to any gvt. Reset new_gvt to prevent allocation/free done later. */
		} else
		{	/* Global name already present in csa->gvt_hashtab. No need to allocate new_gvt.
			 * Only need to free up old_gvt. Also increment gvt->regcnt.
			 * If NOISOLATION status differs between the two, choose the more pessimistic one.
			 */
			new_gvt = (gv_namehead *)stayent->value;
			assert(new_gvt != old_gvt);
			if (FALSE == old_gvt->noisolation)
				new_gvt->noisolation = FALSE;
			assert(1 <= new_gvt->regcnt);
			new_gvt->regcnt++;
		}
		if (NULL != new_gvt)
		{
			*gvtc->gvt_ptr = new_gvt;	/* change hash-table to eventually point to new gvt */
			if (NULL != gvtc->gvt_ptr2)
			{	/* this is true only for spanning globals. Update one more location to point to new gvt */
				assert(TREF(spangbl_seen));
				assert(old_gvt == *gvtc->gvt_ptr2);
				*gvtc->gvt_ptr2 = new_gvt;
			}
			assert(1 == old_gvt->regcnt); /* assert that TARG_FREE will happen below */
			for (gd_iter = get_next_gdr(NULL); gd_iter; gd_iter = get_next_gdr(gd_iter))
			{	/* If gd_iter->tab_ptr still has old_gvt, remove it before freeing old_gvt. */
				old_gvt_ent = (ht_ent_mname *)lookup_hashtab_mname(gd_iter->tab_ptr, &old_gvt->gvname);
				if (old_gvt_ent)
					delete_hashtab_ent_mname(gd_iter->tab_ptr, old_gvt_ent);
			}
			TARG_FREE_IF_NEEDED(old_gvt);
		}
		/* else: new_gvt is NULL which means old_gvt stays as is */
		free_element(gvt_pending_buddy_list, (char *)gvtc);
	}
}