diff options
author | Volker Lendecke <vl@samba.org> | 2014-11-13 10:38:40 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2014-12-09 04:12:07 +0100 |
commit | 3a6a6f19410606a9028861ca95ac80d2651e2830 (patch) | |
tree | 6fc54a2f9a6417be42119e62e5542b4b38c4eb66 /source3/lib/messages.c | |
parent | e2ee1a42cf5b57e09604792f46dd173182a014e5 (diff) | |
download | samba-3a6a6f19410606a9028861ca95ac80d2651e2830.tar.gz samba-3a6a6f19410606a9028861ca95ac80d2651e2830.tar.xz samba-3a6a6f19410606a9028861ca95ac80d2651e2830.zip |
messaging3: Avoid self-send complexity
With the notify code I've hit another case where self-sends caused
a problem. This time messages were lost because we tried to do
multiple dispatch_rec calls from within a single inotify callback.
Only the first one was being taken care of, the others did not find
receivers.
This patch makes self-sends go through the kernel as well, the
kernel queues everything nicely for us. With dgram messaging this
should be pretty fast. If it turns out to be a performance problem,
we can solve it later by doing proper queueing in user space. We
need to completely decouple any processing from callbacks.
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/lib/messages.c')
-rw-r--r-- | source3/lib/messages.c | 113 |
1 files changed, 3 insertions, 110 deletions
diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 5b4daa2932..1fd7601f82 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -507,36 +507,6 @@ NTSTATUS messaging_send_iov(struct messaging_context *msg_ctx, return NT_STATUS_OK; } - if (server_id_same_process(&msg_ctx->id, &server)) { - struct messaging_rec rec; - uint8_t *buf; - - /* - * Self-send, directly dispatch - */ - - if (num_fds > 0) { - return NT_STATUS_NOT_SUPPORTED; - } - - buf = iov_buf(talloc_tos(), iov, iovlen); - if (buf == NULL) { - return NT_STATUS_NO_MEMORY; - } - - rec = (struct messaging_rec) { - .msg_version = MESSAGE_VERSION, - .msg_type = msg_type & MSG_TYPE_MASK, - .dest = server, - .src = msg_ctx->id, - .buf = data_blob_const(buf, talloc_get_size(buf)), - }; - - messaging_dispatch_rec(msg_ctx, &rec); - TALLOC_FREE(buf); - return NT_STATUS_OK; - } - ZERO_STRUCT(hdr); hdr = (struct messaging_hdr) { .msg_type = msg_type, @@ -826,68 +796,6 @@ static bool messaging_append_new_waiters(struct messaging_context *msg_ctx) return true; } -struct messaging_defer_callback_state { - struct messaging_context *msg_ctx; - struct messaging_rec *rec; - void (*fn)(struct messaging_context *msg, void *private_data, - uint32_t msg_type, struct server_id server_id, - DATA_BLOB *data); - void *private_data; -}; - -static void messaging_defer_callback_trigger(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_data); - -static void messaging_defer_callback( - struct messaging_context *msg_ctx, struct messaging_rec *rec, - void (*fn)(struct messaging_context *msg, void *private_data, - uint32_t msg_type, struct server_id server_id, - DATA_BLOB *data), - void *private_data) -{ - struct messaging_defer_callback_state *state; - struct tevent_immediate *im; - - state = talloc(msg_ctx, struct messaging_defer_callback_state); - if (state == NULL) { - DEBUG(1, ("talloc failed\n")); - return; - } - state->msg_ctx = msg_ctx; - state->fn = fn; - state->private_data = private_data; - - state->rec = messaging_rec_dup(state, rec); - if (state->rec == NULL) { - DEBUG(1, ("talloc failed\n")); - TALLOC_FREE(state); - return; - } - - im = tevent_create_immediate(state); - if (im == NULL) { - DEBUG(1, ("tevent_create_immediate failed\n")); - TALLOC_FREE(state); - return; - } - tevent_schedule_immediate(im, msg_ctx->event_ctx, - messaging_defer_callback_trigger, state); -} - -static void messaging_defer_callback_trigger(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_data) -{ - struct messaging_defer_callback_state *state = talloc_get_type_abort( - private_data, struct messaging_defer_callback_state); - struct messaging_rec *rec = state->rec; - - state->fn(state->msg_ctx, state->private_data, rec->msg_type, rec->src, - &rec->buf); - TALLOC_FREE(state); -} - /* Dispatch one messaging_rec */ @@ -914,24 +822,9 @@ void messaging_dispatch_rec(struct messaging_context *msg_ctx, rec->num_fds = 0; rec->fds = NULL; - if (server_id_same_process(&rec->src, &rec->dest)) { - /* - * This is a self-send. We are called here from - * messaging_send(), and we don't want to directly - * recurse into the callback but go via a - * tevent_loop_once - */ - messaging_defer_callback(msg_ctx, rec, cb->fn, - cb->private_data); - } else { - /* - * This comes from a different process. we are called - * from the event loop, so we should call back - * directly. - */ - cb->fn(msg_ctx, cb->private_data, rec->msg_type, - rec->src, &rec->buf); - } + cb->fn(msg_ctx, cb->private_data, rec->msg_type, + rec->src, &rec->buf); + /* * we continue looking for matching messages after finding * one. This matters for subsystems like the internal notify |