s3: Add "g_lock_do" as a convenience wrapper function
authorVolker Lendecke <vl@samba.org>
Fri, 12 Mar 2010 13:22:54 +0000 (14:22 +0100)
committerVolker Lendecke <vl@samba.org>
Fri, 12 Mar 2010 13:23:25 +0000 (14:23 +0100)
source3/include/g_lock.h
source3/lib/g_lock.c
source3/utils/net_g_lock.c

index 13daf3f5562e743705ea91190e6d661988a737fd..becb71bb670dba1f0f1faddf007d3413f724052f 100644 (file)
@@ -43,6 +43,10 @@ NTSTATUS g_lock_unlock(struct g_lock_ctx *ctx, const char *name);
 NTSTATUS g_lock_get(struct g_lock_ctx *ctx, const char *name,
                struct server_id *pid);
 
+NTSTATUS g_lock_do(const char *name, enum g_lock_type lock_type,
+                  struct timeval timeout,
+                  void (*fn)(void *private_data), void *private_data);
+
 int g_lock_locks(struct g_lock_ctx *ctx,
                 int (*fn)(const char *name, void *private_data),
                 void *private_data);
index e4c6d7c660e4d4abbfc7eed4e2d1728a5cb2f0f9..17260478865aa0edd8c01b2c08b9b68079e0863b 100644 (file)
@@ -700,3 +700,67 @@ NTSTATUS g_lock_get(struct g_lock_ctx *ctx, const char *name,
        }
        return NT_STATUS_OK;
 }
+
+static bool g_lock_init_all(TALLOC_CTX *mem_ctx,
+                           struct tevent_context **pev,
+                           struct messaging_context **pmsg,
+                           struct g_lock_ctx **pg_ctx)
+{
+       struct tevent_context *ev = NULL;
+       struct messaging_context *msg = NULL;
+       struct g_lock_ctx *g_ctx = NULL;
+
+       ev = tevent_context_init(mem_ctx);
+       if (ev == NULL) {
+               d_fprintf(stderr, "ERROR: could not init event context\n");
+               goto fail;
+       }
+       msg = messaging_init(mem_ctx, procid_self(), ev);
+       if (msg == NULL) {
+               d_fprintf(stderr, "ERROR: could not init messaging context\n");
+               goto fail;
+       }
+       g_ctx = g_lock_ctx_init(mem_ctx, msg);
+       if (g_ctx == NULL) {
+               d_fprintf(stderr, "ERROR: could not init g_lock context\n");
+               goto fail;
+       }
+
+       *pev = ev;
+       *pmsg = msg;
+       *pg_ctx = g_ctx;
+       return true;
+fail:
+       TALLOC_FREE(g_ctx);
+       TALLOC_FREE(msg);
+       TALLOC_FREE(ev);
+       return false;
+}
+
+NTSTATUS g_lock_do(const char *name, enum g_lock_type lock_type,
+                  struct timeval timeout,
+                  void (*fn)(void *private_data), void *private_data)
+{
+       struct tevent_context *ev = NULL;
+       struct messaging_context *msg = NULL;
+       struct g_lock_ctx *g_ctx = NULL;
+       NTSTATUS status;
+
+       if (!g_lock_init_all(talloc_tos(), &ev, &msg, &g_ctx)) {
+               status = NT_STATUS_ACCESS_DENIED;
+               goto done;
+       }
+
+       status = g_lock_lock(g_ctx, name, lock_type, timeout);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+       fn(private_data);
+       g_lock_unlock(g_ctx, name);
+
+done:
+       TALLOC_FREE(g_ctx);
+       TALLOC_FREE(msg);
+       TALLOC_FREE(ev);
+       return status;
+}
index 54cb2d439e8c12d99844445c827ee1db9163b677..a683b552de474523928af2052c55c9438d5ad3da 100644 (file)
@@ -57,17 +57,24 @@ fail:
        return false;
 }
 
+struct net_g_lock_do_state {
+       const char *cmd;
+       int result;
+};
+
+static void net_g_lock_do_fn(void *private_data)
+{
+       struct net_g_lock_do_state *state =
+               (struct net_g_lock_do_state *)private_data;
+       state->result = system(state->cmd);
+}
 
 static int net_g_lock_do(struct net_context *c, int argc, const char **argv)
 {
-       struct tevent_context *ev = NULL;
-       struct messaging_context *msg = NULL;
-       struct g_lock_ctx *g_ctx = NULL;
+       struct net_g_lock_do_state state;
        const char *name, *cmd;
-       int timeout, res;
-       bool locked = false;
+       int timeout;
        NTSTATUS status;
-       int ret = -1;
 
        if (argc != 3) {
                d_printf("Usage: net g_lock do <lockname> <timeout> "
@@ -78,38 +85,26 @@ static int net_g_lock_do(struct net_context *c, int argc, const char **argv)
        timeout = atoi(argv[1]);
        cmd = argv[2];
 
-       if (!net_g_lock_init(talloc_tos(), &ev, &msg, &g_ctx)) {
-               goto done;
-       }
+       state.cmd = cmd;
+       state.result = -1;
 
-       status = g_lock_lock(g_ctx, name, G_LOCK_WRITE,
-                            timeval_set(timeout / 1000, timeout % 1000));
+       status = g_lock_do(name, G_LOCK_WRITE,
+                          timeval_set(timeout / 1000, timeout % 1000),
+                          net_g_lock_do_fn, &state);
        if (!NT_STATUS_IS_OK(status)) {
-               d_fprintf(stderr, "ERROR: Could not get lock: %s\n",
+               d_fprintf(stderr, "ERROR: g_lock_do failed: %s\n",
                          nt_errstr(status));
                goto done;
        }
-       locked = true;
-
-       res = system(cmd);
-
-       if (res == -1) {
+       if (state.result == -1) {
                d_fprintf(stderr, "ERROR: system() returned %s\n",
                          strerror(errno));
                goto done;
        }
-       d_fprintf(stderr, "command returned %d\n", res);
-
-       ret = 0;
+       d_fprintf(stderr, "command returned %d\n", state.result);
 
 done:
-       if (locked) {
-               g_lock_unlock(g_ctx, name);
-       }
-       TALLOC_FREE(g_ctx);
-       TALLOC_FREE(msg);
-       TALLOC_FREE(ev);
-       return ret;
+       return state.result;
 }
 
 static int net_g_lock_dump_fn(struct server_id pid, enum g_lock_type lock_type,