diff options
author | Volker Lendecke <vl@samba.org> | 2014-11-13 11:25:40 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2014-12-16 18:56:03 +0100 |
commit | cf2c12baa8a5031fbe419399e1a00e89c465cf52 (patch) | |
tree | 8ddcde4b34f149437dd0ae05415af4cd9b9b93f8 /source3/lib/messages.c | |
parent | 28f750643bac2049eeeaab23d7d2d9a5a6256bcd (diff) | |
download | samba-cf2c12baa8a5031fbe419399e1a00e89c465cf52.tar.gz samba-cf2c12baa8a5031fbe419399e1a00e89c465cf52.tar.xz samba-cf2c12baa8a5031fbe419399e1a00e89c465cf52.zip |
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 <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/lib/messages.c')
-rw-r--r-- | source3/lib/messages.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 0866e7d38c..7eadb0209b 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) { |