messaging: Act on messages within the right context
authorVolker Lendecke <vl@samba.org>
Sat, 24 Sep 2016 02:35:10 +0000 (19:35 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 4 Oct 2016 22:06:23 +0000 (00:06 +0200)
Only look at "classic" messaging_register handlers in the main event
context loop

If we're sitting in a nested event context, only act upon the
messaging_filtered_read ones that are registered in the nested context.

Postpone everything else via an immediate to the main tevent context

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

index 8dd684fc6673fb31b8e7913bb27795f45c016b7c..fd128e92018dee731c1c927dbc75472b9d03c160 100644 (file)
@@ -960,18 +960,14 @@ static bool messaging_append_new_waiters(struct messaging_context *msg_ctx)
        return true;
 }
 
-/*
-  Dispatch one messaging_rec
-*/
-static void messaging_dispatch_rec(struct messaging_context *msg_ctx,
-                                  struct tevent_context *ev,
-                                  struct messaging_rec *rec)
+static void messaging_dispatch_classic(struct messaging_context *msg_ctx,
+                                      struct messaging_rec *rec)
 {
        struct messaging_callback *cb, *next;
-       unsigned i;
-       size_t j;
 
        for (cb = msg_ctx->callbacks; cb != NULL; cb = next) {
+               size_t j;
+
                next = cb->next;
                if (cb->msg_type != rec->msg_type) {
                        continue;
@@ -997,6 +993,21 @@ static void messaging_dispatch_rec(struct messaging_context *msg_ctx,
                 * message type
                 */
        }
+}
+
+/*
+  Dispatch one messaging_rec
+*/
+static void messaging_dispatch_rec(struct messaging_context *msg_ctx,
+                                  struct tevent_context *ev,
+                                  struct messaging_rec *rec)
+{
+       unsigned i;
+       size_t j;
+
+       if (ev == msg_ctx->event_ctx) {
+               messaging_dispatch_classic(msg_ctx, rec);
+       }
 
        if (!messaging_append_new_waiters(msg_ctx)) {
                for (j=0; j < rec->num_fds; j++) {
@@ -1033,7 +1044,8 @@ static void messaging_dispatch_rec(struct messaging_context *msg_ctx,
 
                state = tevent_req_data(
                        req, struct messaging_filtered_read_state);
-               if (state->filter(rec, state->private_data)) {
+               if ((ev == state->ev) &&
+                   state->filter(rec, state->private_data)) {
                        messaging_filtered_read_done(req, rec);
 
                        /*
@@ -1046,6 +1058,32 @@ static void messaging_dispatch_rec(struct messaging_context *msg_ctx,
                i += 1;
        }
 
+       if (ev != msg_ctx->event_ctx) {
+               struct iovec iov;
+               int fds[rec->num_fds];
+               int ret;
+
+               /*
+                * We've been listening on a nested event
+                * context. Messages need to be handled in the main
+                * event context, so post to ourselves
+                */
+
+               iov.iov_base = rec->buf.data;
+               iov.iov_len = rec->buf.length;
+
+               for (i=0; i<rec->num_fds; i++) {
+                       fds[i] = rec->fds[i];
+               }
+
+               ret = messaging_post_self(
+                       msg_ctx, rec->src, rec->dest, rec->msg_type,
+                       &iov, 1, fds, rec->num_fds);
+               if (ret == 0) {
+                       return;
+               }
+       }
+
        /*
         * If the fd-array isn't used, just close it.
         */