messaging3: Enforce just one messaging context
authorVolker Lendecke <vl@samba.org>
Tue, 18 Feb 2014 19:51:23 +0000 (20:51 +0100)
committerJeremy Allison <jra@samba.org>
Fri, 30 May 2014 23:59:18 +0000 (01:59 +0200)
The current messaging implementation is based on a tdb indexed by server_id. If
we have more than one messaging context in a process, messages might not arrive
at the right context and be dropped, depending on which signal handler is
triggered first.

This is the same patch as bd55fdb lifted to messaging.c

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/lib/messages.c

index 364bbbcea4f30ecfc22c6c759005c3b4da2b4d0c..1263bf1698c15c07b010d35b0e82acf6d854fd82 100644 (file)
@@ -74,8 +74,12 @@ struct messaging_context {
 
        struct messaging_backend *local;
        struct messaging_backend *remote;
+
+       bool *have_context;
 };
 
+static int messaging_context_destructor(struct messaging_context *msg_ctx);
+
 /****************************************************************************
  A useful function for testing the message system.
 ****************************************************************************/
@@ -205,6 +209,13 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
 {
        struct messaging_context *ctx;
        NTSTATUS status;
+       static bool have_context = false;
+
+       if (have_context) {
+               DEBUG(0, ("No two messaging contexts per process\n"));
+               return NULL;
+       }
+
 
        if (!(ctx = talloc_zero(mem_ctx, struct messaging_context))) {
                return NULL;
@@ -212,6 +223,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
 
        ctx->id = procid_self();
        ctx->event_ctx = ev;
+       ctx->have_context = &have_context;
 
        status = messaging_dgm_init(ctx, ctx, &ctx->local);
 
@@ -242,9 +254,19 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
        register_dmalloc_msgs(ctx);
        debug_register_msgs(ctx);
 
+       have_context = true;
+       talloc_set_destructor(ctx, messaging_context_destructor);
+
        return ctx;
 }
 
+static int messaging_context_destructor(struct messaging_context *msg_ctx)
+{
+       SMB_ASSERT(*msg_ctx->have_context);
+       *msg_ctx->have_context = false;
+       return 0;
+}
+
 struct server_id messaging_server_id(const struct messaging_context *msg_ctx)
 {
        return msg_ctx->id;