messaging3: Add messaging_handler_send/recv
authorVolker Lendecke <vl@samba.org>
Thu, 13 Nov 2014 11:25:40 +0000 (11:25 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 16 Dec 2014 17:56:03 +0000 (18:56 +0100)
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 <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/include/messages.h
source3/lib/messages.c

index 3db675611e0051c354b984cd21ef5cf16c9a8dfc..6b5e3da71ea001ce0fb6a015119621a8073d34ee 100644 (file)
@@ -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);
index 0866e7d38c7eb5b59b3d4f6526847b0c7d134d6f..7eadb0209b9679e27075c574d5e90e9dede6b282 100644 (file)
@@ -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) {