libctdb: tweak interface for readrecordlock
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 24 May 2010 04:22:17 +0000 (13:52 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 24 May 2010 04:22:17 +0000 (13:52 +0930)
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?

include/ctdb.h
libctdb/ctdb.c
libctdb/libctdb_private.h
libctdb/messages.c
libctdb/tst.c

index 9aabc4e25fd7a29445565e289fe2d525f4fa4948..bd4fdc12b16cef47bae226d0b6840f9e3fece611 100644 (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)        \
index 5461d3c132d21323ac38ed29377987f66fb950b2..c9adfdaa2ce28185d88e9d355fc92b5e10e114f8 100644 (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)
index 5727012747286117d8996401a1b0cadda33432ce..f016be0c68daf0a779f711b6092db61aaae601eb 100644 (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. */
index 864ec3e7ea668f9adf80d80bb51a47d4a4dac94d..26f90aa0d98365d0513c891fca9a8739a3de5d18 100644 (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;
index 2b0aa14a801b383364703ac5985ba51d2ec11160..8ab631dd2a9bae3be50537a206ffd902b79e2ded 100644 (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);