lib: Add g_lock_set_lock_order()
[amitay/samba.git] / source3 / lib / g_lock.c
index 8789b43feeeccd3bd994ee0c8f195a01b2f046a6..65dc3e76f26f4897611b9693b4e6a0a63d35d1d1 100644 (file)
@@ -36,6 +36,7 @@
 struct g_lock_ctx {
        struct db_context *db;
        struct messaging_context *msg;
+       enum dbwrap_lock_order lock_order;
 };
 
 struct g_lock {
@@ -193,6 +194,7 @@ struct g_lock_ctx *g_lock_ctx_init_backend(
                return NULL;
        }
        result->msg = msg;
+       result->lock_order = DBWRAP_LOCK_ORDER_NONE;
 
        result->db = db_open_watched(result, backend, msg);
        if (result->db == NULL) {
@@ -203,6 +205,12 @@ struct g_lock_ctx *g_lock_ctx_init_backend(
        return result;
 }
 
+void g_lock_set_lock_order(struct g_lock_ctx *ctx,
+                          enum dbwrap_lock_order lock_order)
+{
+       ctx->lock_order = lock_order;
+}
+
 struct g_lock_ctx *g_lock_ctx_init(TALLOC_CTX *mem_ctx,
                                   struct messaging_context *msg)
 {
@@ -690,7 +698,23 @@ static void g_lock_lock_retry(struct tevent_req *subreq)
 
 NTSTATUS g_lock_lock_recv(struct tevent_req *req)
 {
-       return tevent_req_simple_recv_ntstatus(req);
+       struct g_lock_lock_state *state = tevent_req_data(
+               req, struct g_lock_lock_state);
+       struct g_lock_ctx *ctx = state->ctx;
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+
+       if ((ctx->lock_order != DBWRAP_LOCK_ORDER_NONE) &&
+           ((state->type == G_LOCK_READ) ||
+            (state->type == G_LOCK_WRITE))) {
+               const char *name = dbwrap_name(ctx->db);
+               dbwrap_lock_order_lock(name, ctx->lock_order);
+       }
+
+       return NT_STATUS_OK;
 }
 
 struct g_lock_lock_simple_state {
@@ -769,6 +793,10 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key,
                        return status;
                }
                if (NT_STATUS_IS_OK(state.status)) {
+                       if (ctx->lock_order != DBWRAP_LOCK_ORDER_NONE) {
+                               const char *name = dbwrap_name(ctx->db);
+                               dbwrap_lock_order_lock(name, ctx->lock_order);
+                       }
                        return NT_STATUS_OK;
                }
                if (!NT_STATUS_EQUAL(
@@ -889,6 +917,11 @@ NTSTATUS g_lock_unlock(struct g_lock_ctx *ctx, TDB_DATA key)
                return state.status;
        }
 
+       if (ctx->lock_order != DBWRAP_LOCK_ORDER_NONE) {
+               const char *name = dbwrap_name(ctx->db);
+               dbwrap_lock_order_unlock(name, ctx->lock_order);
+       }
+
        return NT_STATUS_OK;
 }