mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
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)
This commit is contained in:
parent
b93e65eaf7
commit
cfe0edc0b9
@ -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);
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user