update getpnn to use a generic "set_callback" call to register the callback on the...
[sahlberg/ctdb.git] / libctdb / libctdb.c
index 02b40abaafdbb66e607088a0a51613ab3a2533b5..a17ad143f8676ccd17fc1ed31eb50be374ba00f6 100644 (file)
 #include "system/filesys.h"
 
 
+struct ctdb_control_cb_data {
+       void *callback;
+       void *private_data;
+       uint32_t db_id;
+};
+
+
+static void
+ctdb_control_cb(struct ctdb_client_control_state *state)
+{
+       struct ctdb_control_cb_data *cb_data = state->async.private_data;
+       ctdb_callback callback = (ctdb_callback)cb_data->callback;
+
+       /* dont recurse */
+       state->async.fn = NULL;
+
+       if (state->state != CTDB_CONTROL_DONE) {
+               DEBUG(DEBUG_ERR, (__location__ " ctdb_getpnn_recv_cb failed with state:%d\n", state->state));
+               callback(-1, NULL, NULL, cb_data->private_data);
+               return;
+       }
+
+       callback(0, state->ctdb, state, cb_data->private_data);
+}
+
+
+/*
+ * This function is used to set the callback action for a handle
+ */
+int ctdb_set_callback(ctdb_handle *handle, ctdb_callback callback, void *private_data)
+{
+       struct ctdb_client_control_state *control_state = talloc_get_type(handle, struct ctdb_client_control_state);
+
+       if (control_state != NULL) {
+               struct ctdb_control_cb_data *cb_data;
+
+               if (callback == NULL) {
+                       if (control_state->async.private_data != NULL) {
+                               talloc_free(control_state->async.private_data);
+                               control_state->async.private_data = NULL;
+                       }
+                       control_state->async.fn           = NULL;
+
+                       return 0;
+               }
+
+               cb_data = talloc(control_state, struct ctdb_control_cb_data);
+               if (cb_data == NULL) {
+                       DEBUG(DEBUG_ERR, (__location__ " Failed to alloc cb_data\n"));
+                       return -1;
+               }
+
+               cb_data->callback     = callback;
+               cb_data->private_data = private_data;
+
+               control_state->async.fn           = ctdb_control_cb;
+               control_state->async.private_data = cb_data;
+
+               return 0;
+       }
+
+       DEBUG(DEBUG_ERR, (__location__ " Unknown type of handle passed to ctdb_set_callback.\n"));
+       return -1;
+}
+
+
+
 /*
   this is the dummy null procedure that all databases support
 */
@@ -165,41 +232,17 @@ int ctdb_free(ctdb_handle *handle)
        return 0;
 }
 
-struct ctdb_control_cb_data {
-       void *callback;
-       void *private_data;
-       uint32_t db_id;
-};
-
 
 
 
 /*************************
  * GET PNN of local node *
  *************************/
-static void
-ctdb_getpnn_recv_cb(struct ctdb_client_control_state *state)
-{
-       struct ctdb_control_cb_data *cb_data = state->async.private_data;
-       ctdb_getpnn_cb callback = (ctdb_getpnn_cb)cb_data->callback;
-
-       if (state->state != CTDB_CONTROL_DONE) {
-               DEBUG(DEBUG_ERR, (__location__ " ctdb_getpnn_recv_cb failed with state:%d\n", state->state));
-               callback(-1, 0, cb_data->private_data);
-               return;
-       }
-
-       callback(0, state->status, cb_data->private_data);
-}
-
 ctdb_handle *
 ctdb_getpnn_send(struct ctdb_context *ctdb,
-                       uint32_t destnode,
-                       ctdb_getpnn_cb callback,
-                       void *private_data)
+                       uint32_t destnode)
 {
        struct ctdb_client_control_state *state;
-       struct ctdb_control_cb_data *cb_data;
 
        state = ctdb_control_send(ctdb, destnode, 0, 
                           CTDB_CONTROL_GET_PNN, 0, tdb_null, 
@@ -210,15 +253,6 @@ ctdb_getpnn_send(struct ctdb_context *ctdb,
                return NULL;
        }
 
-       if (callback != NULL) {
-               cb_data = talloc(state, struct ctdb_control_cb_data);
-               cb_data->callback     = callback;
-               cb_data->private_data = private_data;
-
-               state->async.fn           = ctdb_getpnn_recv_cb;
-               state->async.private_data = cb_data;
-       }
-
        return (ctdb_handle *)state;
 }
 
@@ -226,16 +260,15 @@ int ctdb_getpnn_recv(struct ctdb_context *ctdb, ctdb_handle *handle, uint32_t *p
 {
        struct ctdb_client_control_state *state = talloc_get_type(handle, struct ctdb_client_control_state);
        int ret;
-       int32_t res;
 
-       ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
+       ret = ctdb_control_recv(ctdb, state, state, NULL, NULL, NULL);
        if (ret != 0) {
                DEBUG(DEBUG_ERR,(__location__ " ctdb_getpnn_recv failed\n"));
                return -1;
        }
 
        if (pnn != NULL) {
-               *pnn = (uint32_t)res;
+               *pnn = (uint32_t)state->status;
        }
 
        return 0;
@@ -245,7 +278,7 @@ int ctdb_getpnn(struct ctdb_context *ctdb, uint32_t destnode, uint32_t *pnn)
 {
        struct ctdb_client_control_state *state;
        
-       state = ctdb_getpnn_send(ctdb, destnode, NULL, NULL);
+       state = ctdb_getpnn_send(ctdb, destnode);
        if (state == NULL) {
                DEBUG(DEBUG_ERR,(__location__ " ctdb_getpnn_send() failed.\n"));
                return -1;