add a sync wrapper for the getpnn control
[rusty/ctdb.git] / libctdb / sync.c
index 8c4892de54665335a4a53793b56a2b217d240893..df8655279da10ea322f52c5e2f26fb1ba8110e13 100644 (file)
 #include <errno.h>
 #include <stdlib.h>
 
-/* FIXME: Find a way to share more code here. */
-struct ctdb_getrecmaster {
-       bool done;
-       int status;
-       uint32_t *recmaster;
-};
-
-static bool ctdb_service_flush(struct ctdb_connection *ctdb)
+/* On failure, frees req and returns NULL. */
+static struct ctdb_request *wait_for(struct ctdb_connection *ctdb,
+                                    struct ctdb_request *req,
+                                    bool *done)
 {
        struct pollfd fds;
 
+       /* Pass through allocation failures. */
+       if (!req)
+               return NULL;
+
        fds.fd = ctdb_get_fd(ctdb);
-       fds.events = ctdb_which_events(ctdb);
-       if (poll(&fds, 1, -1) < 0) {
-               /* Signalled is OK, other error is bad. */
-               return errno == EINTR;
+       while (!*done) {
+               fds.events = ctdb_which_events(ctdb);
+               if (poll(&fds, 1, -1) < 0) {
+                       /* Signalled is OK, other error is bad. */
+                       if (errno == EINTR)
+                               continue;
+                       ctdb_request_free(req);
+                       return NULL;
+               }
+               if (ctdb_service(ctdb, fds.revents) < 0) {
+                       ctdb_request_free(req);
+                       return NULL;
+               }
        }
-       return ctdb_service(ctdb, fds.revents) >= 0;
+       return req;
 }
 
-static void getrecmaster_done(int status, uint32_t recmaster, void *priv_data)
+static void set(struct ctdb_connection *ctdb,
+               struct ctdb_request *req, bool *done)
 {
-       struct ctdb_getrecmaster *grm = priv_data;
-       *grm->recmaster = recmaster;
-       grm->status = status;
-       grm->done = true;
+       *done = true;
 }
 
 int ctdb_getrecmaster(struct ctdb_connection *ctdb,
                      uint32_t destnode, uint32_t *recmaster)
 {
        struct ctdb_request *req;
-       struct ctdb_getrecmaster grm;
-
-       grm.done = false;
-       grm.recmaster = recmaster;
-       req = ctdb_getrecmaster_send(ctdb, destnode, getrecmaster_done, &grm);
-       if (!req)
-               return -1;
-
-       while (!grm.done) {
-               if (!ctdb_service_flush(ctdb)) {
-                       ctdb_cancel(req);
-                       return -1;
-               }
+       bool done = false;
+       int ret = -1;
+
+       req = wait_for(ctdb,
+                      ctdb_getrecmaster_send(ctdb, destnode, set, &done),
+                      &done);
+       if (req != NULL) {
+               ret = ctdb_getrecmaster_recv(req, recmaster);
+               ctdb_request_free(req);
        }
-       return grm.status;
-}
-
-struct ctdb_attachdb {
-       bool done;
-       int status;
-       struct ctdb_db *ctdb_db;
-};
-
-static void attachdb_sync_done(int status,
-                              struct ctdb_db *ctdb_db, void *private_data)
-{
-       struct ctdb_attachdb *atb = private_data;
-       atb->ctdb_db = ctdb_db;
-       atb->status = status;
-       atb->done = true;
+       return ret;
 }
 
 struct ctdb_db *ctdb_attachdb(struct ctdb_connection *ctdb,
@@ -91,21 +79,33 @@ struct ctdb_db *ctdb_attachdb(struct ctdb_connection *ctdb,
                              uint32_t tdb_flags)
 {
        struct ctdb_request *req;
-       struct ctdb_attachdb atb;
-
-       atb.done = false;
-       req = ctdb_attachdb_send(ctdb, name, persistent, tdb_flags,
-                                attachdb_sync_done, &atb);
-       if (!req)
-               return NULL;
+       bool done = false;
+       struct ctdb_db *ret = NULL;
+
+       req = wait_for(ctdb,
+                      ctdb_attachdb_send(ctdb, name, persistent, tdb_flags,
+                                         set, &done),
+                      &done);
+       if (req != NULL) {
+               ret = ctdb_attachdb_recv(req);
+               ctdb_request_free(req);
+       }
+       return ret;
+}
 
-       while (!atb.done) {
-               if (!ctdb_service_flush(ctdb)) {
-                       ctdb_cancel(req);
-                       return NULL;
-               }
+int ctdb_getpnn(struct ctdb_connection *ctdb,
+               uint32_t destnode, uint32_t *pnn)
+{
+       struct ctdb_request *req;
+       bool done = false;
+       int ret = -1;
+
+       req = wait_for(ctdb,
+                      ctdb_getpnn_send(ctdb, destnode, set, &done),
+                      &done);
+       if (req != NULL) {
+               ret = ctdb_getpnn_recv(req, pnn);
+               ctdb_request_free(req);
        }
-       if (atb.status != 0)
-               return NULL;
-       return atb.ctdb_db;
+       return ret;
 }