/*
get the transaction lock
*/
-int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
+int tdb_transaction_lock(struct tdb_context *tdb, int ltype, bool block)
{
if (tdb->have_transaction_lock || tdb->global_lock.count) {
return 0;
}
if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype,
- F_SETLKW, 0, 1) == -1) {
+ block ? F_SETLKW : F_SETLK,
+ 0, 1) == -1) {
+ if (!block && (errno == EAGAIN)) {
+ return -1;
+ }
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
tdb->ecode = TDB_ERR_LOCK;
return -1;
int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype);
int tdb_unlock(struct tdb_context *tdb, int list, int ltype);
int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len);
-int tdb_transaction_lock(struct tdb_context *tdb, int ltype);
+int tdb_transaction_lock(struct tdb_context *tdb, int ltype, bool block);
int tdb_transaction_unlock(struct tdb_context *tdb);
int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len);
int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off);
start a tdb transaction. No token is returned, as only a single
transaction is allowed to be pending per tdb_context
*/
-int tdb_transaction_start(struct tdb_context *tdb)
+static int _tdb_transaction_start(struct tdb_context *tdb, bool block)
{
/* some sanity checks */
if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) {
/* get the transaction write lock. This is a blocking lock. As
discussed with Volker, there are a number of ways we could
make this async, which we will probably do in the future */
- if (tdb_transaction_lock(tdb, F_WRLCK) == -1) {
+ if (tdb_transaction_lock(tdb, F_WRLCK, block) == -1) {
SAFE_FREE(tdb->transaction->blocks);
SAFE_FREE(tdb->transaction);
+ if (!block) {
+ tdb->ecode = TDB_ERR_NOLOCK;
+ }
return -1;
}
return -1;
}
+int tdb_transaction_start(struct tdb_context *tdb)
+{
+ return _tdb_transaction_start(tdb, true);
+}
+
+int tdb_transaction_start_nonblock(struct tdb_context *tdb)
+{
+ return _tdb_transaction_start(tdb, false);
+}
/*
cancel the current transaction
/* we need to get a read lock on the transaction lock here to
cope with the lock ordering semantics of solaris10 */
if (!in_transaction) {
- if (tdb_transaction_lock(tdb, F_RDLCK)) {
+ if (tdb_transaction_lock(tdb, F_RDLCK, true)) {
return -1;
}
}
}
if (!in_transaction) {
- if (tdb_transaction_lock(tdb, F_WRLCK)) {
+ if (tdb_transaction_lock(tdb, F_WRLCK, true)) {
return -1;
}
}
tdb_log_func tdb_log_fn(struct tdb_context *tdb);
void *tdb_get_logging_private(struct tdb_context *tdb);
int tdb_transaction_start(struct tdb_context *tdb);
+int tdb_transaction_start_nonblock(struct tdb_context *tdb);
int tdb_transaction_commit(struct tdb_context *tdb);
int tdb_transaction_cancel(struct tdb_context *tdb);
int tdb_transaction_recover(struct tdb_context *tdb);