if ((ret = __lock_getobj(lt, lp->holder, NULL, DB_LOCK_LOCKER, &lockerp)) != 0) {
if (__lock_getobj(lt, lp->holder, NULL, DB_LOCK_LOCKER, &lockerp) != 0) {
__dd_build(dbenv, bmp, nlockers, idmap)	DB_ENV *dbenv;	u_int32_t **bmp, *nlockers;	locker_info **idmap;{	struct __db_lock *lp;	DB_LOCKTAB *lt;	DB_LOCKOBJ *op, *lo, *lockerp;	u_int8_t *pptr;	locker_info *id_array;	u_int32_t *bitmap, count, *entryp, i, id, nentries, *tmpmap;	int is_first, ret;	lt = dbenv->lk_info;	/*	 * We'll check how many lockers there are, add a few more in for	 * good measure and then allocate all the structures.  Then we'll	 * verify that we have enough room when we go back in and get the	 * mutex the second time.	 */	LOCK_LOCKREGION(lt);retry:	count = lt->region->nlockers;	lt->region->need_dd = 0;	UNLOCK_LOCKREGION(lt);	if (count == 0) {		*nlockers = 0;		return (0);	}	if (dbenv->db_verbose)		__db_err(dbenv, "%lu lockers", (u_long)count);	count += 10;	nentries = ALIGN(count, 32) / 32;	/*	 * Allocate enough space for a count by count bitmap matrix.	 *	 * XXX	 * We can probably save the malloc's between iterations just	 * reallocing if necessary because count grew by too much.	 */	if ((bitmap = (u_int32_t *)__db_calloc((size_t)count,	    sizeof(u_int32_t) * nentries)) == NULL) {		__db_err(dbenv, "%s", strerror(ENOMEM));		return (ENOMEM);	}	if ((tmpmap =	    (u_int32_t *)__db_calloc(sizeof(u_int32_t), nentries)) == NULL) {		__db_err(dbenv, "%s", strerror(ENOMEM));		__db_free(bitmap);		return (ENOMEM);	}	if ((id_array = (locker_info *)__db_calloc((size_t)count,	    sizeof(locker_info))) == NULL) {		__db_err(dbenv, "%s", strerror(ENOMEM));		__db_free(bitmap);		__db_free(tmpmap);		return (ENOMEM);	}	/*	 * Now go back in and actually fill in the matrix.	 */	LOCK_LOCKREGION(lt);	if (lt->region->nlockers > count) {		__db_free(bitmap);		__db_free(tmpmap);		__db_free(id_array);		goto retry;	}	/*	 * First we go through and assign each locker a deadlock detector id.	 * Note that we fill in the idmap in the next loop since that's the	 * only place where we conveniently have both the deadlock id and the	 * actual locker.	 */	for (id = 0, i = 0; i < lt->region->table_size; i++)		for (op = SH_TAILQ_FIRST(&lt->hashtab[i], __db_lockobj);		    op != NULL; op = SH_TAILQ_NEXT(op, links, __db_lockobj))			if (op->type == DB_LOCK_LOCKER)				op->dd_id = id++;	/*	 * We go through the hash table and find each object.  For each object,	 * we traverse the waiters list and add an entry in the waitsfor matrix	 * for each waiter/holder combination.	 */	for (i = 0; i < lt->region->table_size; i++) {		for (op = SH_TAILQ_FIRST(&lt->hashtab[i], __db_lockobj);		    op != NULL; op = SH_TAILQ_NEXT(op, links, __db_lockobj)) {			if (op->type != DB_LOCK_OBJTYPE)				continue;			CLEAR_MAP(tmpmap, nentries);			/*			 * First we go through and create a bit map that			 * represents all the holders of this object.			 */			for (lp = SH_TAILQ_FIRST(&op->holders, __db_lock);			    lp != NULL;			    lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {				if (__lock_getobj(lt, lp->holder,				    NULL, DB_LOCK_LOCKER, &lockerp) != 0) {					__db_err(dbenv,					    "warning unable to find object");					continue;				}				id_array[lockerp->dd_id].id = lp->holder;				id_array[lockerp->dd_id].valid = 1;				/*				 * If the holder has already been aborted, then				 * we should ignore it for now.				 */				if (lp->status == DB_LSTAT_HELD)					SET_MAP(tmpmap, lockerp->dd_id);			}			/*			 * Next, for each waiter, we set its row in the matrix			 * equal to the map of holders we set up above.			 */			for (is_first = 1,			    lp = SH_TAILQ_FIRST(&op->waiters, __db_lock);			    lp != NULL;			    is_first = 0,			    lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {				if ((ret = __lock_getobj(lt, lp->holder,				    NULL, DB_LOCK_LOCKER, &lockerp)) != 0) {					__db_err(dbenv,					    "warning unable to find object");					continue;				}				id_array[lockerp->dd_id].id = lp->holder;				id_array[lockerp->dd_id].valid = 1;				/*				 * If the transaction is pending abortion, then				 * ignore it on this iteration.				 */				if (lp->status != DB_LSTAT_WAITING)					continue;				entryp = bitmap + (nentries * lockerp->dd_id);				OR_MAP(entryp, tmpmap, nentries);				/*				 * If this is the first waiter on the queue,				 * then we remove the waitsfor relationship				 * with oneself.  However, if it's anywhere				 * else on the queue, then we have to keep				 * it and we have an automatic deadlock.				 */				if (is_first)					CLR_MAP(entryp, lockerp->dd_id);			}		}	}	/* Now for each locker; record its last lock. */	for (id = 0; id < count; id++) {		if (!id_array[id].valid)			continue;		if ((ret = __lock_getobj(lt,		    id_array[id].id, NULL, DB_LOCK_LOCKER, &lockerp)) != 0) {			__db_err(dbenv,			    "No locks for locker %lu", (u_long)id_array[id].id);			continue;		}		lp = SH_LIST_FIRST(&lockerp->heldby, __db_lock);		if (lp != NULL) {			id_array[id].last_lock = LOCK_TO_OFFSET(lt, lp);			lo = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj);			pptr = SH_DBT_PTR(&lo->lockobj);			if (lo->lockobj.size >= sizeof(db_pgno_t))				memcpy(&id_array[id].pgno, pptr,				    sizeof(db_pgno_t));			else				id_array[id].pgno = 0;		}	}	/* Pass complete, reset the deadlock detector bit. */	lt->region->need_dd = 0;	UNLOCK_LOCKREGION(lt);	/*	 * Now we can release everything except the bitmap matrix that we	 * created.	 */	*nlockers = id;	*idmap = id_array;	*bmp = bitmap;	__db_free(tmpmap);	return (0);}