diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2010-06-21 14:47:34 +0930 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-06-21 14:47:34 +0930 |
commit | cfe0edc0b992acec42a620fdbc09a034d7f91d91 (patch) | |
tree | c1a74581e7f0bbcab49301179f95d2da02204e58 | |
parent | b93e65eaf74ff637bc960356a418ab55f4ca9330 (diff) | |
download | samba-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.h | 4 | ||||
-rw-r--r-- | ctdb/libctdb/ctdb.c | 1 | ||||
-rw-r--r-- | ctdb/libctdb/sync.c | 53 |
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; +} |