#include "db_config.h"
#include "db_int.h"
#include "dbinc/lock.h"
#include "dbinc/txn.h"
int
__lock_failchk(env)
ENV *env;
{
DB_ENV *dbenv;
DB_LOCKER *lip;
DB_LOCKREGION *lrp;
DB_LOCKREQ request;
DB_LOCKTAB *lt;
u_int32_t i;
int ret;
char buf[DB_THREADID_STRLEN];
dbenv = env->dbenv;
lt = env->lk_handle;
lrp = lt->reginfo.primary;
retry: LOCK_LOCKERS(env, lrp);
ret = 0;
for (i = 0; i < lrp->locker_t_size; i++)
SH_TAILQ_FOREACH(lip, <->locker_tab[i], links, __db_locker) {
if ((lip->id >= TXN_MINIMUM) &&
(SH_LIST_EMPTY(&lip->heldby) ||
lip->nlocks == lip->nwrites))
continue;
if (dbenv->is_alive(dbenv, lip->pid, lip->tid,
F_ISSET(lip, DB_LOCKER_HANDLE_LOCKER) ?
DB_MUTEX_PROCESS_ONLY : 0))
continue;
if (lip->id < TXN_MINIMUM && lip->nwrites != 0) {
ret = __db_failed(env, DB_STR_A("2052",
"locker has write locks", ""),
lip->pid, lip->tid);
break;
}
if (!SH_LIST_EMPTY(&lip->heldby)) {
__db_msg(env, DB_STR_A("2053",
"Freeing read locks for locker %#lx: %s",
"%#lx %s"), (u_long)lip->id,
dbenv->thread_id_string(
dbenv, lip->pid, lip->tid, buf));
UNLOCK_LOCKERS(env, lrp);
memset(&request, 0, sizeof(request));
request.op = DB_LOCK_PUT_READ;
if ((ret = __lock_vec(env,
lip, 0, &request, 1, NULL)) != 0)
return (ret);
}
else
UNLOCK_LOCKERS(env, lrp);
if (lip->id < TXN_MINIMUM &&
(ret = __lock_freelocker(lt, lip)) != 0)
return (ret);
goto retry;
}
UNLOCK_LOCKERS(env, lrp);
return (ret);
}