TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n",
tdb->fd, offset, rw_type, lck_type, (int)len));
}
- return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ return -1;
}
return 0;
}
}
if (tdb->global_lock.count) {
- return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ tdb->ecode = TDB_ERR_LOCK;
+ return -1;
}
if (list < -1 || list >= (int)tdb->header.hash_size) {
+ tdb->ecode = TDB_ERR_LOCK;
TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid list %d for ltype=%d\n",
list, ltype));
return -1;
}
if (tdb->global_lock.count) {
- return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ tdb->ecode = TDB_ERR_LOCK;
+ return -1;
}
if (tdb->flags & TDB_NOLOCK)
*/
int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
{
- if (tdb->have_transaction_lock || tdb->global_lock.count) {
+ if (tdb->global_lock.count) {
+ return 0;
+ }
+ if (tdb->transaction_lock_count > 0) {
+ tdb->transaction_lock_count++;
return 0;
}
+
if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype,
F_SETLKW, 0, 1) == -1) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
tdb->ecode = TDB_ERR_LOCK;
return -1;
}
- tdb->have_transaction_lock = 1;
+ tdb->transaction_lock_count++;
return 0;
}
int tdb_transaction_unlock(struct tdb_context *tdb)
{
int ret;
- if (!tdb->have_transaction_lock) {
+ if (tdb->global_lock.count) {
+ return 0;
+ }
+ if (tdb->transaction_lock_count > 1) {
+ tdb->transaction_lock_count--;
return 0;
}
ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
if (ret == 0) {
- tdb->have_transaction_lock = 0;
+ tdb->transaction_lock_count = 0;
}
return ret;
}
ltype &= ~TDB_MARK_LOCK;
/* There are no locks on read-only dbs */
- if (tdb->read_only || tdb->traverse_read)
- return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ if (tdb->read_only || tdb->traverse_read) {
+ tdb->ecode = TDB_ERR_LOCK;
+ return -1;
+ }
if (tdb->global_lock.count && tdb->global_lock.ltype == ltype) {
tdb->global_lock.count++;
if (tdb->global_lock.count) {
/* a global lock of a different type exists */
- return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ tdb->ecode = TDB_ERR_LOCK;
+ return -1;
}
if (tdb->num_locks != 0) {
/* can't combine global and chain locks */
- return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ tdb->ecode = TDB_ERR_LOCK;
+ return -1;
}
if (!mark_lock &&
/* There are no locks on read-only dbs */
if (tdb->read_only || tdb->traverse_read) {
- return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ tdb->ecode = TDB_ERR_LOCK;
+ return -1;
}
if (tdb->global_lock.ltype != ltype || tdb->global_lock.count == 0) {
- return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ tdb->ecode = TDB_ERR_LOCK;
+ return -1;
}
if (tdb->global_lock.count > 1) {
/* lock entire database with write lock */
int tdb_lockall(struct tdb_context *tdb)
{
+ tdb_trace(tdb, "tdb_lockall");
return _tdb_lockall(tdb, F_WRLCK, F_SETLKW);
}
/* lock entire database with write lock - mark only */
int tdb_lockall_mark(struct tdb_context *tdb)
{
+ tdb_trace(tdb, "tdb_lockall_mark");
return _tdb_lockall(tdb, F_WRLCK | TDB_MARK_LOCK, F_SETLKW);
}
/* unlock entire database with write lock - unmark only */
int tdb_lockall_unmark(struct tdb_context *tdb)
{
+ tdb_trace(tdb, "tdb_lockall_unmark");
return _tdb_unlockall(tdb, F_WRLCK | TDB_MARK_LOCK);
}
/* lock entire database with write lock - nonblocking varient */
int tdb_lockall_nonblock(struct tdb_context *tdb)
{
- return _tdb_lockall(tdb, F_WRLCK, F_SETLK);
+ int ret = _tdb_lockall(tdb, F_WRLCK, F_SETLK);
+ tdb_trace_ret(tdb, "tdb_lockall_nonblock", ret);
+ return ret;
}
/* unlock entire database with write lock */
int tdb_unlockall(struct tdb_context *tdb)
{
+ tdb_trace(tdb, "tdb_unlockall");
return _tdb_unlockall(tdb, F_WRLCK);
}
/* lock entire database with read lock */
int tdb_lockall_read(struct tdb_context *tdb)
{
+ tdb_trace(tdb, "tdb_lockall_read");
return _tdb_lockall(tdb, F_RDLCK, F_SETLKW);
}
/* lock entire database with read lock - nonblock varient */
int tdb_lockall_read_nonblock(struct tdb_context *tdb)
{
- return _tdb_lockall(tdb, F_RDLCK, F_SETLK);
+ int ret = _tdb_lockall(tdb, F_RDLCK, F_SETLK);
+ tdb_trace_ret(tdb, "tdb_lockall_read_nonblock", ret);
+ return ret;
}
/* unlock entire database with read lock */
int tdb_unlockall_read(struct tdb_context *tdb)
{
+ tdb_trace(tdb, "tdb_unlockall_read");
return _tdb_unlockall(tdb, F_RDLCK);
}
contention - it cannot guarantee how many records will be locked */
int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key)
{
- return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
+ int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
+ tdb_trace_1rec(tdb, "tdb_chainlock", key);
+ return ret;
}
/* lock/unlock one hash chain, non-blocking. This is meant to be used
locked */
int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key)
{
- return tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
+ int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
+ tdb_trace_1rec_ret(tdb, "tdb_chainlock_nonblock", key, ret);
+ return ret;
}
/* mark a chain as locked without actually locking it. Warning! use with great caution! */
int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key)
{
- return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
+ int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
+ tdb_trace_1rec(tdb, "tdb_chainlock_mark", key);
+ return ret;
}
/* unmark a chain as locked without actually locking it. Warning! use with great caution! */
int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key)
{
+ tdb_trace_1rec(tdb, "tdb_chainlock_unmark", key);
return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
}
int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key)
{
+ tdb_trace_1rec(tdb, "tdb_chainunlock", key);
return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
}
int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key)
{
- return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
+ int ret;
+ ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
+ tdb_trace_1rec(tdb, "tdb_chainlock_read", key);
+ return ret;
}
int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key)
{
+ tdb_trace_1rec(tdb, "tdb_chainunlock_read", key);
return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
}
-
-
/* record lock stops delete underneath */
int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off)
{