Commit 5a5b9f8d authored by Rusty Russell's avatar Rusty Russell

tdb2: implement tdb_chainlock_read/tdb_chainunlock_read.

parent 63e80faf
......@@ -875,3 +875,24 @@ void tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key)
tdb_trace_1rec(tdb, "tdb_chainunlock", key);
tdb_unlock_hashes(tdb, lockstart, locksize, F_WRLCK);
}
enum TDB_ERROR tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key)
{
return tdb->last_error = chainlock(tdb, &key, F_RDLCK, TDB_LOCK_WAIT,
"tdb_chainlock_read");
}
void tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key)
{
uint64_t h = tdb_hash(tdb, key.dptr, key.dsize);
tdb_off_t lockstart, locksize;
unsigned int group, gbits;
gbits = TDB_TOPLEVEL_HASH_BITS - TDB_HASH_GROUP_BITS;
group = bits_from(h, 64 - gbits, gbits);
lockstart = hlock_range(group, &locksize);
tdb_trace_1rec(tdb, "tdb_chainunlock_read", key);
tdb_unlock_hashes(tdb, lockstart, locksize, F_RDLCK);
}
......@@ -395,7 +395,7 @@ enum TDB_ERROR tdb_nextkey(struct tdb_context *tdb, struct tdb_data *key);
* @tdb: the tdb context returned from tdb_open()
* @key: the key to lock.
*
* This prevents any changes from occurring to a group of keys including @key,
* This prevents any access occurring to a group of keys including @key,
* even if @key does not exist. This allows primitive atomic updates of
* records without using transactions.
*
......@@ -417,6 +417,33 @@ enum TDB_ERROR tdb_chainlock(struct tdb_context *tdb, TDB_DATA key);
*/
void tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key);
/**
* tdb_chainlock_read - lock a record in the TDB, for reading
* @tdb: the tdb context returned from tdb_open()
* @key: the key to lock.
*
* This prevents any changes from occurring to a group of keys including @key,
* even if @key does not exist. This allows primitive atomic updates of
* records without using transactions.
*
* You cannot begin a transaction while holding a tdb_chainlock_read(), nor can
* you do any operations on any other keys in the database. This also means
* that you cannot hold more than one tdb_chainlock()/read() at a time.
*
* See Also:
* tdb_chainlock()
*/
enum TDB_ERROR tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key);
/**
* tdb_chainunlock_read - unlock a record in the TDB for reading
* @tdb: the tdb context returned from tdb_open()
* @key: the key to unlock.
*
* The key must have previously been locked by tdb_chainlock_read().
*/
void tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key);
/**
* tdb_lockall - lock the entire TDB
* @tdb: the tdb context returned from tdb_open()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment