]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
change the api for managing callbacks to controls so that isntead of
authorRonnie Sahlberg <sahlberg@ronnie>
Fri, 24 Aug 2007 00:42:06 +0000 (10:42 +1000)
committerRonnie Sahlberg <sahlberg@ronnie>
Fri, 24 Aug 2007 00:42:06 +0000 (10:42 +1000)
passing it as a parameter we set the callback function explicitely from
the caller if the ..._send() function returned a valid state pointer.

(This used to be ctdb commit aa939570662786455f63299b62c99882cff29d42)

ctdb/client/ctdb_client.c
ctdb/include/ctdb.h
ctdb/include/ctdb_private.h
ctdb/server/ctdb_recoverd.c

index 65fb10ec0c887c42da97abf663fce7a1e9c38162..ecbe57e342b20ff18f802aa0ae22905a632a1541 100644 (file)
@@ -665,22 +665,6 @@ int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
 }
 
 
-struct ctdb_client_control_state {
-       struct ctdb_context *ctdb;
-       uint32_t reqid;
-       int32_t status;
-       TDB_DATA outdata;
-       enum control_state state;
-       char *errormsg;
-       struct ctdb_req_control *c;
-
-       /* if we have a callback registered for the completion (or failure) of
-          this control
-          if a callback is used, it MUST talloc_free the cb_data passed to it
-       */
-       control_callback callback;
-       void *cb_private;
-};
 
 /*
    called when a control completes or timesout to invoke the callback
@@ -690,10 +674,7 @@ static void invoke_control_callback(struct event_context *ev, struct timed_event
        struct timeval t, void *private_data)
 {
        struct ctdb_client_control_state *state;
-       struct ctdb_control_cb_data *cb_data;
        struct ctdb_context *ctdb;
-       control_callback callback;
-       void *cb_private;
        TALLOC_CTX *tmp_ctx = talloc_new(NULL);
        int ret;
 
@@ -701,29 +682,12 @@ static void invoke_control_callback(struct event_context *ev, struct timed_event
        talloc_steal(tmp_ctx, state);
 
        ctdb       = state->ctdb;
-       callback   = state->callback;
-       cb_private = state->cb_private;
-
-       cb_data = talloc_zero(tmp_ctx, struct ctdb_control_cb_data);
-       if (cb_data == NULL) {
-               talloc_free(tmp_ctx);
-               CTDB_NO_MEMORY_VOID(ctdb, cb_data);
-       }
 
-       cb_data->state = state->state;
-       cb_data->vnn   = state->c->hdr.destnode;
+       ret = ctdb_control_recv(ctdb, state, state,
+                       &state->outdata, 
+                       &state->status, 
+                       &state->errormsg);
 
-       ret = ctdb_control_recv(ctdb, state, cb_data,
-                       &cb_data->outdata, 
-                       &cb_data->status, 
-                       &cb_data->errormsg);
-       /* we dont check ret since we expect that ctdb_control_recv can fail
-          for example if the control timedout
-
-          state is always talloc_free()'d inside ctdb_control_recv
-       */
-
-       callback(cb_data, cb_private);
        talloc_free(tmp_ctx);
 }
 
@@ -770,7 +734,7 @@ static void ctdb_client_reply_control(struct ctdb_context *ctdb,
        /* if we had a callback registered for this control, pull the response
           and call the callback.
        */
-       if (state->callback) {
+       if (state->async.fn) {
                event_add_timed(ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
        }
 }
@@ -799,7 +763,7 @@ static void control_timeout_func(struct event_context *ev, struct timed_event *t
        /* if we had a callback registered for this control, pull the response
           and call the callback.
        */
-       if (state->callback) {
+       if (state->async.fn) {
                event_add_timed(state->ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
        }
 }
@@ -810,8 +774,7 @@ struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
                uint32_t opcode, uint32_t flags, TDB_DATA data, 
                TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
                struct timeval *timeout,
-               char **errormsg,
-               control_callback callback, void *cb_private)
+               char **errormsg)
 {
        struct ctdb_client_control_state *state;
        size_t len;
@@ -834,8 +797,6 @@ struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
        state->reqid      = ctdb_reqid_new(ctdb, state);
        state->state      = CTDB_CONTROL_WAIT;
        state->errormsg   = NULL;
-       state->callback   = callback;
-       state->cb_private = cb_private;
 
        talloc_set_destructor(state, ctdb_control_destructor);
 
@@ -892,8 +853,12 @@ int ctdb_control_recv(struct ctdb_context *ctdb,
        while (state->state == CTDB_CONTROL_WAIT) {
                event_loop_once(ctdb->ev);
        }
+
        if (state->state != CTDB_CONTROL_DONE) {
                DEBUG(0,(__location__ " ctdb_control_recv failed\n"));
+               if (state->async.fn) {
+                       state->async.fn(state);
+               }
                talloc_free(state);
                return -1;
        }
@@ -903,11 +868,13 @@ int ctdb_control_recv(struct ctdb_context *ctdb,
                if (errormsg) {
                        (*errormsg) = talloc_move(mem_ctx, &state->errormsg);
                }
+               if (state->async.fn) {
+                       state->async.fn(state);
+               }
                talloc_free(state);
                return -1;
        }
 
-
        if (outdata) {
                *outdata = state->outdata;
                outdata->dptr = talloc_memdup(mem_ctx, outdata->dptr, outdata->dsize);
@@ -918,6 +885,10 @@ int ctdb_control_recv(struct ctdb_context *ctdb,
        }
 
 
+
+       if (state->async.fn) {
+               state->async.fn(state);
+       }
        talloc_free(state);
        return 0;
 }
@@ -939,8 +910,7 @@ int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
 
        state = ctdb_control_send(ctdb, destnode, srvid, opcode, 
                        flags, data, mem_ctx, outdata,
-                       timeout, errormsg,
-                       NULL, NULL);
+                       timeout, errormsg);
        return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status, 
                        errormsg);
 }
@@ -1066,8 +1036,7 @@ ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct
 {
        return ctdb_control_send(ctdb, destnode, 0, 
                           CTDB_CONTROL_GET_RECMODE, 0, tdb_null, 
-                          mem_ctx, NULL, &timeout, NULL,
-                          NULL, NULL);
+                          mem_ctx, NULL, &timeout, NULL);
 }
 
 int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
@@ -1129,13 +1098,11 @@ int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint
  */
 struct ctdb_client_control_state *
 ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, 
-                       struct timeval timeout, uint32_t destnode,
-                       control_callback callback, void *cb_private)
+                       struct timeval timeout, uint32_t destnode)
 {
        return ctdb_control_send(ctdb, destnode, 0, 
                           CTDB_CONTROL_GET_RECMASTER, 0, tdb_null, 
-                          mem_ctx, NULL, &timeout, NULL,
-                          callback, cb_private);
+                          mem_ctx, NULL, &timeout, NULL);
 }
 
 int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
@@ -1160,7 +1127,7 @@ int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struc
 {
        struct ctdb_client_control_state *state;
 
-       state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode, NULL, NULL);
+       state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
        return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
 }
 
index 17cf2c598f42037e41eb705d634d6ee378970994..8f52aa79a0babde453797e0ea81076b14d221ef8 100644 (file)
@@ -98,16 +98,25 @@ struct ctdb_call_info {
 
 enum control_state {CTDB_CONTROL_WAIT, CTDB_CONTROL_DONE, CTDB_CONTROL_ERROR, CTDB_CONTROL_TIMEOUT};
 
-struct ctdb_control_cb_data {
-       enum control_state state;
-       uint32_t vnn;
+struct ctdb_client_control_state {
+       struct ctdb_context *ctdb;
+       uint32_t reqid;
        int32_t status;
        TDB_DATA outdata;
+       enum control_state state;
        char *errormsg;
+       struct ctdb_req_control *c;
+
+       /* if we have a callback registered for the completion (or failure) of
+          this control
+          if a callback is used, it MUST talloc_free the cb_data passed to it
+       */
+       struct {
+               void (*fn)(struct ctdb_client_control_state *);
+               void *private;
+       } async;        
 };
 
-typedef int (*control_callback)(struct ctdb_control_cb_data *cb_data, void *cb_private);
-
 
 struct event_context;
 
@@ -340,7 +349,7 @@ int ctdb_ctrl_setmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint
  */
 int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster);
 
-struct ctdb_client_control_state *ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, control_callback callback, void *cb_private);
+struct ctdb_client_control_state *ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode);
 
 int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster);
 
index 1c63daf469bc33e3d836dd785a3a0088080db0cc..8a61131593dbba06887ca02f001634fc96be901a 100644 (file)
@@ -861,8 +861,7 @@ ctdb_control_send(struct ctdb_context *ctdb,
                uint32_t opcode, uint32_t flags, TDB_DATA data, 
                TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
                struct timeval *timeout,
-               char **errormsg,
-               control_callback callback, void *cb_private);
+               char **errormsg);
 
 
 
index 208db3963d5508fe0ace88d8dd3a0bf7186c235f..f23dcea27047e1ce36b8ed9333485a75872f417f 100644 (file)
@@ -1209,9 +1209,9 @@ struct verify_recmaster_data {
        enum monitor_result status;
 };
 
-static int verify_recmaster_callback(struct ctdb_control_cb_data *cb_data, void *cb_private)
+static void verify_recmaster_callback(struct ctdb_client_control_state *state)
 {
-       struct verify_recmaster_data *rmdata = talloc_get_type(cb_private, struct verify_recmaster_data);
+       struct verify_recmaster_data *rmdata = talloc_get_type(state->async.private, struct verify_recmaster_data);
 
 
        /* one more node has responded with recmaster data*/
@@ -1220,22 +1220,22 @@ static int verify_recmaster_callback(struct ctdb_control_cb_data *cb_data, void
        /* if we failed to get the recmaster, then return an error and let
           the main loop try again.
        */
-       if (cb_data->state != CTDB_CONTROL_DONE) {
+       if (state->state != CTDB_CONTROL_DONE) {
                if (rmdata->status == MONITOR_OK) {
                        rmdata->status = MONITOR_FAILED;
                }
-               return 0;
+               return;
        }
 
        /* if we got a response, then the recmaster will be stored in the
           status field
        */
-       if (cb_data->status != rmdata->vnn) {
-               DEBUG(0,("Node %d does not agree we are the recmaster. Need a new recmaster election\n",cb_data->vnn));
+       if (state->status != rmdata->vnn) {
+               DEBUG(0,("Node %d does not agree we are the recmaster. Need a new recmaster election\n", state->c->hdr.destnode));
                rmdata->status = MONITOR_ELECTION_NEEDED;
        }
 
-       return 0;
+       return;
 }
 
 
@@ -1262,8 +1262,7 @@ static enum monitor_result verify_recmaster(struct ctdb_context *ctdb, struct ct
                }
                state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, 
                                        CONTROL_TIMEOUT(),
-                                       nodemap->nodes[j].vnn,
-                                       verify_recmaster_callback, rmdata);
+                                       nodemap->nodes[j].vnn);
                if (state == NULL) {
                        /* we failed to send the control, treat this as 
                           an error and try again next iteration
@@ -1273,6 +1272,10 @@ static enum monitor_result verify_recmaster(struct ctdb_context *ctdb, struct ct
                        return MONITOR_FAILED;
                }
 
+               /* set up the callback functions */
+               state->async.fn = verify_recmaster_callback;
+               state->async.private = rmdata;
+
                /* one more control to wait for to complete */
                rmdata->count++;
        }