From cf2c12baa8a5031fbe419399e1a00e89c465cf52 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 13 Nov 2014 11:25:40 +0000 Subject: [PATCH] messaging3: Add messaging_handler_send/recv This repeatedly listens on msg_type. It's similar to messaging_register with talloc based autocleanup. The handler is free to talloc_move a way the record for later use. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- source3/include/messages.h | 8 ++++ source3/lib/messages.c | 81 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/source3/include/messages.h b/source3/include/messages.h index 3db675611e0..6b5e3da71ea 100644 --- a/source3/include/messages.h +++ b/source3/include/messages.h @@ -150,6 +150,14 @@ struct tevent_req *messaging_read_send(TALLOC_CTX *mem_ctx, int messaging_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct messaging_rec **presult); +struct tevent_req *messaging_handler_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct messaging_context *msg_ctx, uint32_t msg_type, + bool (*handler)(struct messaging_context *msg_ctx, + struct messaging_rec **rec, void *private_data), + void *private_data); +int messaging_handler_recv(struct tevent_req *req); + int messaging_cleanup(struct messaging_context *msg_ctx, pid_t pid); bool messaging_parent_dgm_cleanup_init(struct messaging_context *msg); diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 0866e7d38c7..7eadb0209b9 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -792,6 +792,87 @@ int messaging_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, return 0; } +struct messaging_handler_state { + struct tevent_context *ev; + struct messaging_context *msg_ctx; + uint32_t msg_type; + bool (*handler)(struct messaging_context *msg_ctx, + struct messaging_rec **rec, void *private_data); + void *private_data; +}; + +static void messaging_handler_got_msg(struct tevent_req *subreq); + +struct tevent_req *messaging_handler_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct messaging_context *msg_ctx, uint32_t msg_type, + bool (*handler)(struct messaging_context *msg_ctx, + struct messaging_rec **rec, void *private_data), + void *private_data) +{ + struct tevent_req *req, *subreq; + struct messaging_handler_state *state; + + req = tevent_req_create(mem_ctx, &state, + struct messaging_handler_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->msg_ctx = msg_ctx; + state->msg_type = msg_type; + state->handler = handler; + state->private_data = private_data; + + subreq = messaging_read_send(state, state->ev, state->msg_ctx, + state->msg_type); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, messaging_handler_got_msg, req); + return req; +} + +static void messaging_handler_got_msg(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct messaging_handler_state *state = tevent_req_data( + req, struct messaging_handler_state); + struct messaging_rec *rec; + int ret; + bool ok; + + ret = messaging_read_recv(subreq, state, &rec); + TALLOC_FREE(subreq); + if (tevent_req_error(req, ret)) { + return; + } + + subreq = messaging_read_send(state, state->ev, state->msg_ctx, + state->msg_type); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, messaging_handler_got_msg, req); + + ok = state->handler(state->msg_ctx, &rec, state->private_data); + TALLOC_FREE(rec); + if (ok) { + /* + * Next round + */ + return; + } + TALLOC_FREE(subreq); + tevent_req_done(req); +} + +int messaging_handler_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_unix(req); +} + static bool messaging_append_new_waiters(struct messaging_context *msg_ctx) { if (msg_ctx->num_new_waiters == 0) {