summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2010-06-21 14:47:34 +0930
committerRusty Russell <rusty@rustcorp.com.au>2010-06-21 14:47:34 +0930
commitcfe0edc0b992acec42a620fdbc09a034d7f91d91 (patch)
treec1a74581e7f0bbcab49301179f95d2da02204e58
parentb93e65eaf74ff637bc960356a418ab55f4ca9330 (diff)
downloadsamba-cfe0edc0b992acec42a620fdbc09a034d7f91d91.tar.gz
samba-cfe0edc0b992acec42a620fdbc09a034d7f91d91.tar.xz
samba-cfe0edc0b992acec42a620fdbc09a034d7f91d91.zip
libctdb: implement synchronous readrecordlock interface.
Because this doesn't use a generic callback, it's not quite as trivial as the other sync wrappers. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (This used to be ctdb commit 1f20b938d46d4fcd50d2b473c1ab8dc31d178d2d)
-rw-r--r--ctdb/include/ctdb.h4
-rw-r--r--ctdb/libctdb/ctdb.c1
-rw-r--r--ctdb/libctdb/sync.c53
3 files changed, 57 insertions, 1 deletions
diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h
index a9ee63ff25..c5e6f935e4 100644
--- a/ctdb/include/ctdb.h
+++ b/ctdb/include/ctdb.h
@@ -475,6 +475,7 @@ void ctdb_detachdb(struct ctdb_connection *ctdb, struct ctdb_db *db);
/**
* ctdb_readrecordlock - read and lock a record (synchronous)
+ * @ctdb: the ctdb_connection from ctdb_connect.
* @ctdb_db: the database handle from ctdb_attachdb/ctdb_attachdb_recv.
* @key: the key of the record to lock.
* @req: a pointer to the request, if one is needed.
@@ -482,7 +483,8 @@ void ctdb_detachdb(struct ctdb_connection *ctdb, struct ctdb_db *db);
* Do a ctdb_readrecordlock_send and wait for it to complete.
* Returns NULL on failure.
*/
-struct ctdb_lock *ctdb_readrecordlock(struct ctdb_db *ctdb_db, TDB_DATA key,
+struct ctdb_lock *ctdb_readrecordlock(struct ctdb_connection *ctdb,
+ struct ctdb_db *ctdb_db, TDB_DATA key,
TDB_DATA *data);
diff --git a/ctdb/libctdb/ctdb.c b/ctdb/libctdb/ctdb.c
index 096a9264f0..23acef4ada 100644
--- a/ctdb/libctdb/ctdb.c
+++ b/ctdb/libctdb/ctdb.c
@@ -794,6 +794,7 @@ static void readrecordlock_retry(struct ctdb_connection *ctdb,
/* Now it's their responsibility to free lock & request! */
req->extra_destructor = NULL;
lock->callback(lock->ctdb_db, lock, data, private);
+ ctdb_request_free(ctdb, req);
return;
}
diff --git a/ctdb/libctdb/sync.c b/ctdb/libctdb/sync.c
index 43db2cf6b5..2e6ba9926f 100644
--- a/ctdb/libctdb/sync.c
+++ b/ctdb/libctdb/sync.c
@@ -115,3 +115,56 @@ bool ctdb_getpnn(struct ctdb_connection *ctdb,
}
return ret;
}
+
+struct rrl_info {
+ bool done;
+ struct ctdb_lock *lock;
+ TDB_DATA *data;
+};
+
+static void rrl_callback(struct ctdb_db *ctdb_db,
+ struct ctdb_lock *lock,
+ TDB_DATA data,
+ struct rrl_info *rrl)
+{
+ rrl->done = true;
+ rrl->lock = lock;
+ *rrl->data = data;
+}
+
+struct ctdb_lock *ctdb_readrecordlock(struct ctdb_connection *ctdb,
+ struct ctdb_db *ctdb_db, TDB_DATA key,
+ TDB_DATA *data)
+{
+ struct pollfd fds;
+ struct rrl_info rrl;
+
+ rrl.done = false;
+ rrl.lock = NULL;
+ rrl.data = data;
+
+ /* Immediate failure is easy. */
+ if (!ctdb_readrecordlock_async(ctdb_db, key, rrl_callback, &rrl))
+ return NULL;
+
+ /* Immediate success is easy. */
+ if (!rrl.done) {
+ /* Otherwise wait until callback called. */
+ fds.fd = ctdb_get_fd(ctdb);
+ while (!rrl.done) {
+ fds.events = ctdb_which_events(ctdb);
+ if (poll(&fds, 1, -1) < 0) {
+ /* Signalled is OK, other error is bad. */
+ if (errno == EINTR)
+ continue;
+ DEBUG(ctdb, LOG_ERR,
+ "ctdb_readrecordlock: poll failed");
+ return NULL;
+ }
+ if (!ctdb_service(ctdb, fds.revents)) {
+ break;
+ }
+ }
+ }
+ return rrl.lock;
+}