ctdb-locking: Remove multiple lock requests per lock context (part 2)
authorAmitay Isaacs <amitay@gmail.com>
Fri, 30 May 2014 05:36:03 +0000 (15:36 +1000)
committerVolker Lendecke <vl@samba.org>
Mon, 4 Aug 2014 15:59:52 +0000 (17:59 +0200)
Store only a single request instead of storing a queue in lock context.
Lock request structure does not need to be a linked list any more.

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Volker Lendecke <vl@samba.org>
ctdb/server/ctdb_lock.c

index 28ba79c0ac396a61d869847b0415059b3e845f67..a54f0bc8f6e91915888b5ca51eb27d649485b6b3 100644 (file)
@@ -71,18 +71,18 @@ struct lock_context {
        TDB_DATA key;
        uint32_t priority;
        bool auto_mark;
-       struct lock_request *req_queue;
+       struct lock_request *request;
        pid_t child;
        int fd[2];
        struct tevent_fd *tfd;
        struct tevent_timer *ttimer;
        struct timeval start_time;
        uint32_t key_hash;
+       bool can_schedule;
 };
 
 /* lock_request is the client specific part for a lock request */
 struct lock_request {
-       struct lock_request *next, *prev;
        struct lock_context *lctx;
        void (*callback)(void *, bool);
        void *private_data;
@@ -305,11 +305,10 @@ static int ctdb_lock_context_destructor(struct lock_context *lock_ctx)
  */
 static int ctdb_lock_request_destructor(struct lock_request *lock_request)
 {
-       DLIST_REMOVE(lock_request->lctx->req_queue, lock_request);
+       lock_request->lctx->request = NULL;
        return 0;
 }
 
-
 void ctdb_lock_free_request_context(struct lock_request *lock_req)
 {
        struct lock_context *lock_ctx;
@@ -327,7 +326,7 @@ void ctdb_lock_free_request_context(struct lock_request *lock_req)
  */
 static void process_callbacks(struct lock_context *lock_ctx, bool locked)
 {
-       struct lock_request *request, *next;
+       struct lock_request *request;
 
        if (lock_ctx->auto_mark && locked) {
                switch (lock_ctx->type) {
@@ -349,19 +348,12 @@ static void process_callbacks(struct lock_context *lock_ctx, bool locked)
                }
        }
 
-       /* Iterate through all callbacks */
-       request = lock_ctx->req_queue;
-       while (request) {
-               if (lock_ctx->auto_mark) {
-                       /* Reset the destructor, so request is not removed from the list */
-                       talloc_set_destructor(request, NULL);
-               }
-
-               /* In case, callback frees the request, store next */
-               next = request->next;
-               request->callback(request->private_data, locked);
-               request = next;
+       request = lock_ctx->request;
+       if (lock_ctx->auto_mark) {
+               /* Reset the destructor, so request is not removed from the list */
+               talloc_set_destructor(request, NULL);
        }
+       request->callback(request->private_data, locked);
 
        if (lock_ctx->auto_mark && locked) {
                switch (lock_ctx->type) {
@@ -750,8 +742,8 @@ static void ctdb_lock_schedule(struct ctdb_context *ctdb)
        lock_ctx = ctdb->lock_pending;
        while (lock_ctx != NULL) {
                next_ctx = lock_ctx->next;
-               if (! lock_ctx->req_queue) {
-                       DEBUG(DEBUG_INFO, ("Removing lock context without lock requests\n"));
+               if (! lock_ctx->request) {
+                       DEBUG(DEBUG_INFO, ("Removing lock context without lock request\n"));
                        DLIST_REMOVE(ctdb->lock_pending, lock_ctx);
                        ctdb->lock_num_pending--;
                        CTDB_DECREMENT_STAT(ctdb, locks.num_pending);
@@ -949,7 +941,7 @@ static struct lock_request *ctdb_lock_internal(struct ctdb_context *ctdb,
        request->private_data = private_data;
 
        talloc_set_destructor(request, ctdb_lock_request_destructor);
-       DLIST_ADD_END(lock_ctx->req_queue, request, NULL);
+       lock_ctx->request = request;
 
        ctdb_lock_schedule(ctdb);