summaryrefslogtreecommitdiff
path: root/lib/async_req
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-05-21 22:28:14 +0200
committerStefan Metzmacher <metze@samba.org>2015-06-12 17:08:18 +0200
commitd5a4b30f894f0d4d4fa728ebd2c435254bf3b142 (patch)
treeeec447f3806c280fbb807c65a7a2f19cba814afe /lib/async_req
parentbe8c2ff10353df00f05cd378c251a33a9e08563a (diff)
downloadsamba-d5a4b30f894f0d4d4fa728ebd2c435254bf3b142.tar.gz
lib/async_req: simplify async_connect_* using a _cleanup() hook
This makes sure we remove the tevent_fd as soon as possible and always reset the old_sockflags. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org>
Diffstat (limited to 'lib/async_req')
-rw-r--r--lib/async_req/async_sock.c68
1 files changed, 33 insertions, 35 deletions
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index fec306dd01b..afa14567071 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -35,8 +35,8 @@
struct async_connect_state {
int fd;
+ struct tevent_fd *fde;
int result;
- int sys_errno;
long old_sockflags;
socklen_t address_len;
struct sockaddr_storage address;
@@ -46,6 +46,8 @@ struct async_connect_state {
void *private_data;
};
+static void async_connect_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state);
static void async_connect_connected(struct tevent_context *ev,
struct tevent_fd *fde, uint16_t flags,
void *priv);
@@ -72,7 +74,6 @@ struct tevent_req *async_connect_send(
{
struct tevent_req *req;
struct async_connect_state *state;
- struct tevent_fd *fde;
req = tevent_req_create(mem_ctx, &state, struct async_connect_state);
if (req == NULL) {
@@ -85,20 +86,22 @@ struct tevent_req *async_connect_send(
*/
state->fd = fd;
- state->sys_errno = 0;
state->before_connect = before_connect;
state->after_connect = after_connect;
state->private_data = private_data;
state->old_sockflags = fcntl(fd, F_GETFL, 0);
if (state->old_sockflags == -1) {
- goto post_errno;
+ tevent_req_error(req, errno);
+ return tevent_req_post(req, ev);
}
+ tevent_req_set_cleanup_fn(req, async_connect_cleanup);
+
state->address_len = address_len;
if (address_len > sizeof(state->address)) {
- errno = EINVAL;
- goto post_errno;
+ tevent_req_error(req, EINVAL);
+ return tevent_req_post(req, ev);
}
memcpy(&state->address, address, address_len);
@@ -116,7 +119,7 @@ struct tevent_req *async_connect_send(
if (state->result == 0) {
tevent_req_done(req);
- goto done;
+ return tevent_req_post(req, ev);
}
/**
@@ -131,23 +134,31 @@ struct tevent_req *async_connect_send(
errno == EISCONN ||
#endif
errno == EAGAIN || errno == EINTR)) {
- state->sys_errno = errno;
- goto post_errno;
+ tevent_req_error(req, errno);
+ return tevent_req_post(req, ev);
}
- fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE,
- async_connect_connected, req);
- if (fde == NULL) {
- state->sys_errno = ENOMEM;
- goto post_errno;
+ state->fde = tevent_add_fd(ev, state, fd,
+ TEVENT_FD_READ | TEVENT_FD_WRITE,
+ async_connect_connected, req);
+ if (state->fde == NULL) {
+ tevent_req_error(req, ENOMEM);
+ return tevent_req_post(req, ev);
}
return req;
+}
- post_errno:
- tevent_req_error(req, state->sys_errno);
- done:
- fcntl(fd, F_SETFL, state->old_sockflags);
- return tevent_req_post(req, ev);
+static void async_connect_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state)
+{
+ struct async_connect_state *state =
+ tevent_req_data(req, struct async_connect_state);
+
+ TALLOC_FREE(state->fde);
+ if (state->fd != -1) {
+ fcntl(state->fd, F_SETFL, state->old_sockflags);
+ state->fd = -1;
+ }
}
/**
@@ -180,8 +191,6 @@ static void async_connect_connected(struct tevent_context *ev,
}
if (ret == 0) {
- state->sys_errno = 0;
- TALLOC_FREE(fde);
tevent_req_done(req);
return;
}
@@ -189,31 +198,20 @@ static void async_connect_connected(struct tevent_context *ev,
/* Try again later, leave the fde around */
return;
}
- state->sys_errno = errno;
- TALLOC_FREE(fde);
tevent_req_error(req, errno);
return;
}
int async_connect_recv(struct tevent_req *req, int *perrno)
{
- struct async_connect_state *state =
- tevent_req_data(req, struct async_connect_state);
- int err;
-
- fcntl(state->fd, F_SETFL, state->old_sockflags);
+ int err = tevent_req_simple_recv_unix(req);
- if (tevent_req_is_unix_error(req, &err)) {
+ if (err != 0) {
*perrno = err;
return -1;
}
- if (state->sys_errno == 0) {
- return 0;
- }
-
- *perrno = state->sys_errno;
- return -1;
+ return 0;
}
struct writev_state {