mirror of
https://github.com/samba-team/samba.git
synced 2025-03-22 02:50:28 +03:00
libctdb: tweak interface for readrecordlock
Previously we could hang in poll with the callback pending (since we fake it): explicitly call it immediately. Note: I experienced corruption using DLIST_ADD_END (ctdb->pnn was blatted when adding to the message_handler list). I switched them all to DLIST_ADD, but maybe I'm using it wrong? (This used to be ctdb commit 3727165f0d206999d2cfc2800ff8868640868c7c)
This commit is contained in:
parent
30f4d01df1
commit
bd8d302589
@ -22,6 +22,7 @@
|
||||
#define _CTDB_H
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <tdb.h>
|
||||
|
||||
/* All *_send() functions are guaranteed to be non-blocking and fully
|
||||
@ -97,9 +98,13 @@ struct ctdb_lock;
|
||||
*
|
||||
* When the lock is released, data is freed too, so make sure to copy the data
|
||||
* before that.
|
||||
*
|
||||
* This returns true on success, and req will be non-NULL if a request was
|
||||
* actually sent, otherwise callback will have already been called.
|
||||
*/
|
||||
struct ctdb_request *
|
||||
bool
|
||||
ctdb_readrecordlock_send(struct ctdb_db *ctdb_db, TDB_DATA key,
|
||||
struct ctdb_request **req,
|
||||
ctdb_callback_t callback, void *private_data);
|
||||
struct ctdb_lock *ctdb_readrecordlock_recv(struct ctdb_db *ctdb_db,
|
||||
struct ctdb_request *handle,
|
||||
@ -215,8 +220,8 @@ int ctdb_cancel(struct ctdb_request *);
|
||||
ctdb_attachdb_send((ctdb), (name), (persistent), (tdb_flags), \
|
||||
ctdb_sendcb((cb), (cbdata)), (cbdata))
|
||||
|
||||
#define ctdb_readrecordlock_send(ctdb_db, key, cb, cbdata) \
|
||||
ctdb_readrecordlock_send((ctdb_db), (key), \
|
||||
#define ctdb_readrecordlock_send(ctdb_db, key, reqp, cb, cbdata) \
|
||||
ctdb_readrecordlock_send((ctdb_db), (key), (reqp), \
|
||||
ctdb_sendcb((cb), (cbdata)), (cbdata))
|
||||
|
||||
#define ctdb_set_message_handler_send(ctdb, srvid, handler, cb, cbdata) \
|
||||
|
@ -87,9 +87,10 @@ struct ctdb_connection *ctdb_connect(const char *addr)
|
||||
goto fail;
|
||||
ctdb->outq = NULL;
|
||||
ctdb->doneq = NULL;
|
||||
ctdb->immediateq = NULL;
|
||||
ctdb->in = NULL;
|
||||
ctdb->message_handlers = NULL;
|
||||
ctdb->next_id = 0;
|
||||
ctdb->broken = false;
|
||||
|
||||
memset(&sun, 0, sizeof(sun));
|
||||
sun.sun_family = AF_UNIX;
|
||||
@ -270,8 +271,9 @@ int ctdb_service(struct ctdb_connection *ctdb, int revents)
|
||||
if (io_elem_finished(ctdb->outq->io)) {
|
||||
struct ctdb_request *done = ctdb->outq;
|
||||
DLIST_REMOVE(ctdb->outq, done);
|
||||
DLIST_ADD_END(ctdb->doneq, done,
|
||||
struct ctdb_request);
|
||||
/* We add at the head: any dead ones
|
||||
* sit and end. */
|
||||
DLIST_ADD(ctdb->doneq, done);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -303,12 +305,6 @@ int ctdb_service(struct ctdb_connection *ctdb, int revents)
|
||||
}
|
||||
}
|
||||
|
||||
while (ctdb->immediateq) {
|
||||
struct ctdb_request *imm = ctdb->immediateq;
|
||||
imm->callback(ctdb, imm, imm->priv_data);
|
||||
DLIST_REMOVE(ctdb->immediateq, imm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -363,7 +359,7 @@ struct ctdb_request *new_ctdb_control_request(struct ctdb_connection *ctdb,
|
||||
pkt->flags = 0;
|
||||
pkt->datalen = extra;
|
||||
memcpy(pkt->data, extra_data, extra);
|
||||
DLIST_ADD_END(ctdb->outq, req, struct ctdb_request);
|
||||
DLIST_ADD(ctdb->outq, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
@ -610,12 +606,13 @@ static void readrecordlock_retry(struct ctdb_connection *ctdb,
|
||||
|
||||
/* Retransmit the same request again (we lost race). */
|
||||
io_elem_reset(req->io);
|
||||
DLIST_ADD_END(ctdb->outq, req, struct ctdb_request);
|
||||
DLIST_ADD(ctdb->outq, req);
|
||||
return;
|
||||
}
|
||||
|
||||
struct ctdb_request *
|
||||
bool
|
||||
ctdb_readrecordlock_send(struct ctdb_db *ctdb_db, TDB_DATA key,
|
||||
struct ctdb_request **reqp,
|
||||
ctdb_callback_t callback, void *cbdata)
|
||||
{
|
||||
struct ctdb_request *req;
|
||||
@ -644,10 +641,9 @@ ctdb_readrecordlock_send(struct ctdb_db *ctdb_db, TDB_DATA key,
|
||||
req->extra_destructor = destroy_lock;
|
||||
|
||||
if (try_readrecordlock(lock)) {
|
||||
/* Already got it: prepare for immediate callback. */
|
||||
DLIST_ADD_END(ctdb_db->ctdb->immediateq,
|
||||
req, struct ctdb_request);
|
||||
return req;
|
||||
*reqp = NULL;
|
||||
callback(ctdb_db->ctdb, req, cbdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We store the original callback in the lock, and use our own. */
|
||||
@ -664,8 +660,9 @@ ctdb_readrecordlock_send(struct ctdb_db *ctdb_db, TDB_DATA key,
|
||||
req->hdr.call->keylen = key.dsize;
|
||||
req->hdr.call->calldatalen = 0;
|
||||
memcpy(req->hdr.call->data, key.dptr, key.dsize);
|
||||
DLIST_ADD_END(ctdb_db->ctdb->outq, req, struct ctdb_request);
|
||||
return req;
|
||||
DLIST_ADD(ctdb_db->ctdb->outq, req);
|
||||
*reqp = req;
|
||||
return true;
|
||||
}
|
||||
|
||||
int ctdb_writerecord(struct ctdb_lock *lock, TDB_DATA data)
|
||||
|
@ -42,8 +42,6 @@ struct ctdb_connection {
|
||||
struct ctdb_request *outq;
|
||||
/* Finished outgoings (awaiting response) */
|
||||
struct ctdb_request *doneq;
|
||||
/* Successful sync requests, waiting for next service. */
|
||||
struct ctdb_request *immediateq;
|
||||
/* Current incoming. */
|
||||
struct io_elem *in;
|
||||
/* Guess at a good reqid to try next. */
|
||||
|
@ -49,8 +49,7 @@ int ctdb_set_message_handler_recv(struct ctdb_connection *ctdb,
|
||||
}
|
||||
|
||||
/* Put ourselves in list of handlers. */
|
||||
DLIST_ADD_END(ctdb->message_handlers, info,
|
||||
struct message_handler_info);
|
||||
DLIST_ADD(ctdb->message_handlers, info);
|
||||
/* Keep safe from destructor */
|
||||
req->extra = NULL;
|
||||
return 0;
|
||||
|
@ -164,13 +164,14 @@ int main(int argc, char *argv[])
|
||||
exit(10);
|
||||
}
|
||||
|
||||
handle = ctdb_readrecordlock_send(ctdb_db_context, key, rrl_cb,
|
||||
ctdb_db_context);
|
||||
if (handle == NULL) {
|
||||
if (!ctdb_readrecordlock_send(ctdb_db_context, key, &handle,
|
||||
rrl_cb, ctdb_db_context)) {
|
||||
printf("Failed to send READRECORDLOCK\n");
|
||||
exit(10);
|
||||
}
|
||||
|
||||
if (handle) {
|
||||
printf("READRECORDLOCK is async\n");
|
||||
}
|
||||
for (;;) {
|
||||
|
||||
pfd.events = ctdb_which_events(ctdb_connection);
|
||||
|
Loading…
x
Reference in New Issue
Block a user