This file is indexed.

/usr/include/htdig_db/lock.h is in htdig 1:3.2.0b6-12.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/*-
 * See the file LICENSE for redistribution information.
 *
 * Copyright (c) 1996, 1997, 1998, 1999
 *	Sleepycat Software.  All rights reserved.
 *
 *	@(#)lock.h	11.5 (Sleepycat) 10/27/99
 */

#ifndef DB_LOCK_DEFAULT_N
#define DB_LOCK_DEFAULT_N	1000	/* Default # of locks in region. */
#endif

/*
 * Out of band value for a lock.  Locks contain an offset into a lock region,
 * so we use an invalid region offset to indicate an invalid or unset lock.
 */
#define	LOCK_INVALID	INVALID_ROFF

/*
 * The locker id space is divided between the transaction manager and the lock
 * manager.  Lock IDs start at 0 and go to DB_LOCK_MAXID.  Txn IDs start at
 * DB_LOCK_MAXID + 1 and go up to TXN_INVALID.
 */
#define DB_LOCK_MAXID		0x7fffffff

/*
 * DB_LOCKREGION --
 *	The lock shared region.
 */
typedef struct __db_lockregion {
	u_int32_t	id;		/* unique id generator */
	u_int32_t	need_dd;	/* flag for deadlock detector */
	u_int32_t	detect;		/* run dd on every conflict */
					/* free lock header */
	SH_TAILQ_HEAD(__flock) free_locks;
					/* free obj header */
	SH_TAILQ_HEAD(__fobj) free_objs;
					/* free locker header */
	SH_TAILQ_HEAD(__flocker) free_lockers;
	u_int32_t	maxlocks;	/* maximum number of locks in table */
	u_int32_t	table_size;	/* size of hash table */
	u_int32_t	nmodes;		/* number of lock modes */
	u_int32_t	nlockers;	/* number of lockers */
	u_int32_t	maxnlockers;	/* maximum number of lockers */
	roff_t		memlock_off;	/* offset of memory mutex */
	roff_t		conf_off;	/* offset of conflicts array */
	roff_t		obj_off;	/* offset of object hash table */
	roff_t		osynch_off;	/* offset of the object mutex table */
	roff_t		locker_off;	/* offset of locker hash table */
	roff_t		lsynch_off;	/* offset of the locker mutex table */
	u_int32_t	nconflicts;	/* number of lock conflicts */
	u_int32_t	nrequests;	/* number of lock gets */
	u_int32_t	nreleases;	/* number of lock puts */
	u_int32_t	ndeadlocks;	/* number of deadlocks */
} DB_LOCKREGION;

/*
 * Since we will store DBTs in shared memory, we need the equivalent of a
 * DBT that will work in shared memory.
 */
typedef struct __sh_dbt {
	u_int32_t size;			/* Byte length. */
	ssize_t   off;			/* Region offset. */
} SH_DBT;

#define SH_DBT_PTR(p)	((void *)(((u_int8_t *)(p)) + (p)->off))

/*
 * Object structures;  these live in the object hash table.
 */
typedef struct __db_lockobj {
	SH_DBT	lockobj;		/* Identifies object locked. */
	SH_TAILQ_ENTRY links;		/* Links for free list. */
	SH_TAILQ_HEAD(__wait) waiters;	/* List of waiting locks. */
	SH_TAILQ_HEAD(__hold) holders;	/* List of held locks. */
					/* Declare room in the object to hold
					 * typical DB lock structures so that
					 * we do not have to allocate them from
					 * shalloc at run-time. */
	u_int8_t objdata[sizeof(struct __db_ilock)];
} DB_LOCKOBJ;

/*
 * Locker structures; these live in the locker hash table.
 */
typedef struct __db_locker {
	u_int32_t id;			/* Locker id. */
	u_int32_t dd_id;		/* Deadlock detector id. */
	size_t master_locker; 		/* Locker of master transaction. */
	size_t parent_locker;		/* Parent of this child. */
        SH_LIST_HEAD(_child) child_locker; 	/* List of descendant txns;
						   only used in a "master"
						   txn. */
        SH_LIST_ENTRY child_link; 	/* Links transactions in the family;
					   elements of the child_locker
					   list. */
	SH_TAILQ_ENTRY links;		/* Links for free list. */
	SH_LIST_HEAD(_held) heldby;	/* Locks held by this locker. */

#define DB_LOCKER_DELETED	0x0001
	u_int32_t flags;
} DB_LOCKER;

/*
 * Lockers can be freed if they are not poart of a transaction
 * family.  Members of a family either point at the master
 * transaction or are the master transaction and have
 * children lockers.
 */
#define LOCKER_FREEABLE(lp)	((lp)->master_locker 			\
			 == TXN_INVALID_ID && 			\
			SH_LIST_FIRST(&(lp)->child_locker, __db_locker) \
			 == NULL)

/*
 * DB_LOCKTAB --
 *	The primary library lock data structure (i.e., the one referenced
 * by the environment, as opposed to the internal one laid out in the region.)
 */
typedef struct __db_locktab {
	DB_ENV		*dbenv;		/* Environment. */
	REGINFO		 reginfo;	/* Region information. */
	MUTEX		*memlock;	/* Mutex to protect memory alloc. */
	u_int8_t 	*conflicts;	/* Pointer to conflict matrix. */
	DB_HASHTAB 	*obj_tab; 	/* Beginning of object hash table. */
	MUTEX		*osynch_tab;	/* Object mutex table. */
	DB_HASHTAB 	*locker_tab; 	/* Beginning of locker hash table. */
	MUTEX		*lsynch_tab;	/* Locker mutex table. */
} DB_LOCKTAB;

/* Test for conflicts. */
#define CONFLICTS(T, R, HELD, WANTED) \
	(T)->conflicts[(HELD) * (R)->nmodes + (WANTED)]

#define OBJ_LINKS_VALID(L) ((L)->links.stqe_prev != -1)

struct __db_lock {
	/*
	 * Wait on mutex to wait on lock.  You reference your own mutex with
	 * ID 0 and others reference your mutex with ID 1.
	 */
	MUTEX		mutex;

	u_int32_t	holder;		/* Who holds this lock. */
	u_int32_t	gen;		/* Generation count. */
	SH_TAILQ_ENTRY	links;		/* Free or holder/waiter list. */
	SH_LIST_ENTRY	locker_links;	/* List of locks held by a locker. */
	u_int32_t	refcount;	/* Reference count the lock. */
	db_lockmode_t	mode;		/* What sort of lock. */
	ssize_t		obj;		/* Relative offset of object struct. */
	roff_t		txnoff;		/* Offset of holding transaction. */
	db_status_t	status;		/* Status of this lock. */
};

/*
 * This is a serious layering violation.  To support nested transactions, we
 * need to be able to tell that a lock is held by a transaction (as opposed to
 * some other locker) and to be able to traverse the parent/descendent chain.
 * In order to do this, each lock held by a transaction maintains a reference
 * to the shared memory transaction structure so it can be accessed during lock
 * promotion.  As the structure is in shared memory, we cannot store a pointer
 * to it, so we use the offset within the region.  An invalid region offset is
 * used to indicate that there is no transaction associated with the current
 * lock.
 */
#define TXN_IS_HOLDING(L)	((L)->txnoff != INVALID_ROFF)

/*
 * Flag values for CDB___lock_put_internal:
 * DB_LOCK_DOALL:     Unlock all references in this lock (instead of only 1).
 * DB_LOCK_FREE:      Free the lock (used in checklocker).
 * DB_LOCK_IGNOREDEL: Remove from the locker hash table even if already
		      deleted (used in checklocker).
 * DB_LOCK_NOPROMOTE: Don't bother running promotion when releasing locks
 *		      (used by CDB___lock_put_internal).
 * DB_LOCK_UNLINK:    Remove from the locker links (used in checklocker).
 */
#define	DB_LOCK_DOALL		0x001
#define	DB_LOCK_FREE		0x002
#define	DB_LOCK_IGNOREDEL	0x004
#define	DB_LOCK_NOPROMOTE	0x008
#define	DB_LOCK_UNLINK		0x010

/*
 * Macros to get/release different types of mutexes.
 */
#define OBJECT_LOOKUP(lt, ndx, dbt, sh_obj)				\
	HASHLOOKUP((lt)->objtab,					\
	    ndx, __db_lockobj, links, dbt, sh_obj, CDB___lock_cmp);

#ifdef FINE_GRAIN
#define OBJECT_LOCK_NDX(lt, ndx)					\
	MUTEX_LOCK(&(lt)->osynch_tab[ndx], (lt)->dbenv->lockfhp)
#define OBJECT_LOCK(lt, reg, obj, ndx) 					\
	HASHACCESS((lt)->osynch_tab, obj,				\
	    (reg)->table_size, CDB___lock_ohash, ndx, (lt)->dbenv->lockfhp)
#define SHOBJECT_LOCK(lt, reg, shobj, ndx)				\
	HASHACCESS((lt)->osynch_tab, shobj,				\
	    (reg)->table_size, CDB___lock_lhash, ndx, (lt)->dbenv->lockfhp)
#define	OBJECT_UNLOCK(lt, ndx)						\
	MUTEX_UNLOCK(&(lt)->osynch_tab[ndx])
#else
#define	OBJECT_LOCK_NDX(lt, ndx)
#define OBJECT_LOCK(lt, reg, obj, ndx) 					\
	ndx = CDB___lock_ohash(obj) % (reg)->table_size
#define SHOBJECT_LOCK(lt, reg, shobj, ndx)				\
	ndx = CDB___lock_lhash(shobj) % (reg)->table_size
#define	OBJECT_UNLOCK(lt, ndx)
#endif

#define LOCKER_LOOKUP(lt, ndx, locker, sh_locker)			\
	HASHLOOKUP((lt)->lockertab,					\
	    ndx, __db_locker, links, locker, sh_locker, CDB___lock_locker_cmp);

#ifdef FINE_GRAIN
#define	LOCKER_LOCK_NDX(lt, ndx)					\
	MUTEX_LOCK(&(lt)->lsynch_tab[ndx], (lt)->dbenv->lockfhp)
#define	LOCKER_LOCK(lt, reg, locker, ndx)				\
	HASHACCESS((lt)->lsynch_tab, locker,				\
	    reg->table_size, CDB___lock_locker_hash, ndx, (lt)->dbenv->lockfhp)
#define	LOCKER_UNLOCK(lt, ndx)						\
	MUTEX_UNLOCK(&(lt)->lsynch_tab[ndx])

#define MEMORY_LOCK(lt)							\
	MUTEX_LOCK((lt)->memlock, (lt)->dbenv->lockfhp)
#define MEMORY_UNLOCK(lt)						\
	MUTEX_UNLOCK((lt)->memlock)
#else
#define	LOCKER_LOCK_NDX(lt, ndx)
#define	LOCKER_LOCK(lt, reg, locker, ndx)				\
	ndx = CDB___lock_locker_hash(locker) % (reg)->table_size
#define	LOCKER_UNLOCK(lt, ndx)
#define MEMORY_LOCK(lt)
#define MEMORY_UNLOCK(lt)
#endif

#ifdef FINE_GRAIN
#define	LOCKREGION(dbenv, lt)
#define	UNLOCKREGION(dbenv, lt)
#else
#define	LOCKREGION(dbenv, lt)  R_LOCK((dbenv), &(lt)->reginfo)
#define	UNLOCKREGION(dbenv, lt)  R_UNLOCK((dbenv), &(lt)->reginfo)
#endif
#include "lock_ext.h"