diff options
author | Stefan Metzmacher <metze@samba.org> | 2016-09-15 11:41:56 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2016-10-26 11:20:12 +0200 |
commit | 4c08920b8389ddc646ac1793930fefb9f2b92cc9 (patch) | |
tree | 264bd6b4afac86279b9c8af85b9fb06d6b7bdadf /lib/async_req | |
parent | 754672ce7678a686718179731225c7cc4e13db36 (diff) | |
download | samba-4c08920b8389ddc646ac1793930fefb9f2b92cc9.tar.gz |
lib/async_req: add writev_cancel()
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'lib/async_req')
-rw-r--r-- | lib/async_req/async_sock.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 3af17484a2b..db3916e07e7 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -235,6 +235,7 @@ int async_connect_recv(struct tevent_req *req, int *perrno) struct writev_state { struct tevent_context *ev; + struct tevent_queue_entry *queue_entry; int fd; struct tevent_fd *fde; struct iovec *iov; @@ -246,6 +247,7 @@ struct writev_state { static void writev_cleanup(struct tevent_req *req, enum tevent_req_state req_state); +static bool writev_cancel(struct tevent_req *req); static void writev_trigger(struct tevent_req *req, void *private_data); static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data); @@ -275,6 +277,7 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, state->err_on_readability = err_on_readability; tevent_req_set_cleanup_fn(req, writev_cleanup); + tevent_req_set_cancel_fn(req, writev_cancel); if (queue == NULL) { state->fde = tevent_add_fd(state->ev, state, state->fd, @@ -285,8 +288,9 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return req; } - if (!tevent_queue_add(queue, ev, req, writev_trigger, NULL)) { - tevent_req_oom(req); + state->queue_entry = tevent_queue_add_entry(queue, ev, req, + writev_trigger, NULL); + if (tevent_req_nomem(state->queue_entry, req)) { return tevent_req_post(req, ev); } return req; @@ -297,13 +301,43 @@ static void writev_cleanup(struct tevent_req *req, { struct writev_state *state = tevent_req_data(req, struct writev_state); + TALLOC_FREE(state->queue_entry); TALLOC_FREE(state->fde); } +static bool writev_cancel(struct tevent_req *req) +{ + struct writev_state *state = tevent_req_data(req, struct writev_state); + + TALLOC_FREE(state->queue_entry); + TALLOC_FREE(state->fde); + + if (state->count == 0) { + /* + * already completed. + */ + return false; + } + + tevent_req_defer_callback(req, state->ev); + if (state->total_size > 0) { + /* + * We've already started to write :-( + */ + tevent_req_error(req, EIO); + return false; + } + + tevent_req_error(req, ECANCELED); + return true; +} + static void writev_trigger(struct tevent_req *req, void *private_data) { struct writev_state *state = tevent_req_data(req, struct writev_state); + state->queue_entry = NULL; + state->fde = tevent_add_fd(state->ev, state, state->fd, state->flags, writev_handler, req); if (tevent_req_nomem(state->fde, req)) { |