messaging: Optimize self-sends
authorVolker Lendecke <vl@samba.org>
Mon, 25 Jul 2016 14:31:18 +0000 (16:31 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 4 Oct 2016 22:06:22 +0000 (00:06 +0200)
We need to go through the event loop, which messaging_dgm_send does. We can
also use a tevent_immediate for the same purpose. Right now the main user is
messaging_ctdb: Here strace looks a bit weird when we receive a message.

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

index a3695e9b788ba977da8b4a799c9241590de33cab..a396091f774ad3c50ca43049e38009297970bdf6 100644 (file)
@@ -479,6 +479,59 @@ NTSTATUS messaging_send_buf(struct messaging_context *msg_ctx,
        return messaging_send(msg_ctx, server, msg_type, &blob);
 }
 
+struct messaging_post_state {
+       struct messaging_context *msg_ctx;
+       struct messaging_rec *rec;
+};
+
+static void messaging_post_handler(struct tevent_context *ev,
+                                  struct tevent_immediate *ti,
+                                  void *private_data);
+
+static int messaging_post_self(struct messaging_context *msg_ctx,
+                              struct server_id src, struct server_id dst,
+                              uint32_t msg_type,
+                              const struct iovec *iov, int iovlen,
+                              const int *fds, size_t num_fds)
+{
+       struct tevent_immediate *ti;
+       struct messaging_post_state *state;
+
+       state = talloc(msg_ctx, struct messaging_post_state);
+       if (state == NULL) {
+               return ENOMEM;
+       }
+       state->msg_ctx = msg_ctx;
+
+       ti = tevent_create_immediate(state);
+       if (ti == NULL) {
+               goto fail;
+       }
+       state->rec = messaging_rec_create(
+               state, src, dst, msg_type, iov, iovlen, fds, num_fds);
+       if (state->rec == NULL) {
+               goto fail;
+       }
+
+       tevent_schedule_immediate(ti, msg_ctx->event_ctx,
+                                 messaging_post_handler, state);
+       return 0;
+
+fail:
+       TALLOC_FREE(state);
+       return ENOMEM;
+}
+
+static void messaging_post_handler(struct tevent_context *ev,
+                                  struct tevent_immediate *ti,
+                                  void *private_data)
+{
+       struct messaging_post_state *state = talloc_get_type_abort(
+               private_data, struct messaging_post_state);
+       messaging_dispatch_rec(state->msg_ctx, state->rec);
+       TALLOC_FREE(state);
+}
+
 int messaging_send_iov_from(struct messaging_context *msg_ctx,
                            struct server_id src, struct server_id dst,
                            uint32_t msg_type,
@@ -509,6 +562,12 @@ int messaging_send_iov_from(struct messaging_context *msg_ctx,
                return ret;
        }
 
+       if (server_id_equal(&dst, &msg_ctx->id)) {
+               ret = messaging_post_self(msg_ctx, src, dst, msg_type,
+                                         iov, iovlen, fds, num_fds);
+               return ret;
+       }
+
        message_hdr_put(hdr, msg_type, src, dst);
        iov2[0] = (struct iovec){ .iov_base = hdr, .iov_len = sizeof(hdr) };
        memcpy(&iov2[1], iov, iovlen * sizeof(*iov));