summaryrefslogtreecommitdiff
path: root/lib/async_req
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2016-09-15 11:41:56 +0200
committerAndreas Schneider <asn@cryptomilk.org>2016-10-26 11:20:12 +0200
commit4c08920b8389ddc646ac1793930fefb9f2b92cc9 (patch)
tree264bd6b4afac86279b9c8af85b9fb06d6b7bdadf /lib/async_req
parent754672ce7678a686718179731225c7cc4e13db36 (diff)
downloadsamba-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.c38
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)) {