#include "db_config.h"
#include "db_int.h"
#include "dbinc/lock.h"
int
__lock_set_timeout(dbenv, locker, timeout, op)
DB_ENV *dbenv;
DB_LOCKER *locker;
db_timeout_t timeout;
u_int32_t op;
{
int ret;
if (locker == NULL)
return (0);
LOCK_REGION_LOCK(dbenv);
ret = __lock_set_timeout_internal(dbenv, locker, timeout, op);
LOCK_REGION_UNLOCK(dbenv);
return (ret);
}
int
__lock_set_timeout_internal(dbenv, sh_locker, timeout, op)
DB_ENV *dbenv;
DB_LOCKER *sh_locker;
db_timeout_t timeout;
u_int32_t op;
{
DB_LOCKREGION *region;
region = dbenv->lk_handle->reginfo.primary;
if (op == DB_SET_TXN_TIMEOUT) {
if (timeout == 0)
timespecclear(&sh_locker->tx_expire);
else
__lock_expires(dbenv, &sh_locker->tx_expire, timeout);
} else if (op == DB_SET_LOCK_TIMEOUT) {
sh_locker->lk_timeout = timeout;
F_SET(sh_locker, DB_LOCKER_TIMEOUT);
} else if (op == DB_SET_TXN_NOW) {
timespecclear(&sh_locker->tx_expire);
__lock_expires(dbenv, &sh_locker->tx_expire, 0);
sh_locker->lk_expire = sh_locker->tx_expire;
if (!timespecisset(®ion->next_timeout) ||
timespeccmp(
®ion->next_timeout, &sh_locker->lk_expire, >))
region->next_timeout = sh_locker->lk_expire;
} else
return (EINVAL);
return (0);
}
int
__lock_inherit_timeout(dbenv, parent, locker)
DB_ENV *dbenv;
DB_LOCKER *parent, *locker;
{
int ret;
ret = 0;
LOCK_REGION_LOCK(dbenv);
if (parent == NULL ||
(timespecisset(&parent->tx_expire) &&
!F_ISSET(parent, DB_LOCKER_TIMEOUT))) {
ret = EINVAL;
goto err;
}
locker->tx_expire = parent->tx_expire;
if (F_ISSET(parent, DB_LOCKER_TIMEOUT)) {
locker->lk_timeout = parent->lk_timeout;
F_SET(locker, DB_LOCKER_TIMEOUT);
if (!timespecisset(&parent->tx_expire))
ret = EINVAL;
}
err: LOCK_REGION_UNLOCK(dbenv);
return (ret);
}
void
__lock_expires(dbenv, timespecp, timeout)
DB_ENV *dbenv;
db_timespec *timespecp;
db_timeout_t timeout;
{
db_timespec v;
if (!timespecisset(timespecp))
__os_gettime(dbenv, timespecp);
DB_TIMEOUT_TO_TIMESPEC(timeout, &v);
timespecadd(timespecp, &v);
}
int
__lock_expired(dbenv, now, timespecp)
DB_ENV *dbenv;
db_timespec *now, *timespecp;
{
if (!timespecisset(timespecp))
return (0);
if (!timespecisset(now))
__os_gettime(dbenv, now);
return (timespeccmp(now, timespecp, >=));
}