1
0
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:
Rusty Russell 2010-05-24 13:52:17 +09:30
parent 30f4d01df1
commit bd8d302589
5 changed files with 29 additions and 29 deletions

View File

@ -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) \

View File

@ -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)

View File

@ -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. */

View File

@ -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;

View File

@ -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);