File: gtcml_chklck.c

package info (click to toggle)
fis-gtm 6.3-007-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • 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 (130 lines) | stat: -rwxr-xr-x 3,966 bytes parent folder | download
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
/****************************************************************
 *								*
 * Copyright (c) 2001-2018 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 <sys/shm.h>

#include "mdef.h"

#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "mlkdef.h"
#include "mlk_ops.h"
#include "lockdefs.h"
#include "cmidef.h"
#include "hashtab_mname.h"	/* needed for cmmdef.h */
#include "cmmdef.h"
#include "gt_timer.h"
#include "gtcmlkdef.h"
#include "is_proc_alive.h"
#include "gtcml.h"
#include "interlock.h"
#include "rel_quant.h"
#include "do_shmat.h"

GBLREF gd_region	*gv_cur_region;
GBLREF uint4            process_id;
GBLREF short		crash_count;

void gtcml_chklck(cm_lckblkreg *reg, bool timed)
{
	cm_lckblklck	*lck, *lckroot, *lcktofree;
	cm_lckblkprc 	*prc, *prc1;
	mlk_shrblk_ptr_t d;
	boolean_t	stop_waking, timeout, was_crit;
	sgmnt_addrs	*csa;
	int4		icount, status, time[2];
	mlk_pvtctl	pctl;

	timeout = TRUE;
	lckroot = reg->lock;
	lck = lckroot->next;
	lcktofree = NULL;

	/* it appears that the design assumes that lck should never be null, but we have empirical that it happens.
	 * because we do not (at the moment of writing) have resources to pursue the discrepancy, we simply protect
	 * against it, and hope that we don't encounter other symptoms
	*/
	while (lck != NULL)
	{
		if (timed)
		{
			if (timeout = gtcml_lcktime(lck))
			{
				prc = prc1 = lck->prc;
				if (prc)
				{	/* Check if blocking processes exists. */
					do
					{	/* Note that previous code in this section would manipulate the sequence
						   numbers in the shared blocks rather than in the private blocks. This was
						   deemed to not always be safe, especially in the case of parent/child
						   locking since when a lock it held, the sequence number at its release
						   MUST match the sequence number at it's inception or the lock cannot and
						   will not be released by mlk_unlock. By always manipulating the sequence
						   number in private storage instead, we avoid this problem totally. se 8/2001 */
						if ((d = prc1->blocked))
						{	/* Blocking process shrblk exists. Check it under crit lock */
							csa = &FILE_INFO(gv_cur_region)->s_addrs;
							MLK_PVTCTL_INIT(pctl, gv_cur_region);
							GRAB_LOCK_CRIT_AND_SYNC(pctl, was_crit);
							if (d->sequence != prc1->blk_sequence)
							{	/* Blocking structure no longer ours - do artificial wakeup */
								lck->sequence = csa->hdr->trans_hist.lock_sequence++;
							} else if (d->owner)
							{	/* Blocking struct still has owner. Check if alive */
								if (PROC_DEAD(d, time, icount, status))
								{	/* process that owned lock has died, free lock */
									d->owner = 0;
									lck->sequence = csa->hdr->trans_hist.lock_sequence++;
								}
							} else
							{	/* No longer any owner (lke stole?). Wake up */
								lck->sequence = csa->hdr->trans_hist.lock_sequence++;
							}
							REL_LOCK_CRIT(pctl, was_crit);
						}
						prc1 = prc1->next;
					} while (prc1 != prc);
				}
			}
		}
		if (timeout)
		{
			gtcml_chkprc(lck);
			if (lck->prc == 0)
			{
				lck->next->last = lck->last;
				lck->last->next = lck->next;
				if (lck->next == lckroot && lck->last == lckroot)
				{  /* no more lcks for reg */
					reg->lock = 0;
					free(lck);
					free(lckroot);    /* list header */
					break;
				}
				lcktofree = lck;   /* not yet */
			}
		}

		lck = lck->next;
		if (NULL != lcktofree)
		{
			free(lcktofree);
			lcktofree = NULL;
		}
		if (lck == lckroot)
			break;		/* at end of list */
	}
}