summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-05-22 22:30:09 +0200
committerVolker Lendecke <vl@samba.org>2009-05-24 13:50:43 +0200
commit4906d7fc679210555871bcb080e504fcc11734c6 (patch)
tree170da497fee5fe7c09644c12ad43b0844c6ab6d7
parente337124c555aee32f0d075b8008c77da3065c1e1 (diff)
downloadsamba-4906d7fc679210555871bcb080e504fcc11734c6.tar.gz
samba-4906d7fc679210555871bcb080e504fcc11734c6.tar.bz2
samba-4906d7fc679210555871bcb080e504fcc11734c6.zip
Do queueing in wbclient.c
The _trigger fn must know about wbc_context, while we were waiting in the queue the fd might have changed
-rw-r--r--source3/lib/wb_reqtrans.c29
-rw-r--r--source3/lib/wbclient.c76
2 files changed, 59 insertions, 46 deletions
diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c
index 038e5bda17..55883ba8c7 100644
--- a/source3/lib/wb_reqtrans.c
+++ b/source3/lib/wb_reqtrans.c
@@ -338,30 +338,6 @@ ssize_t wb_resp_write_recv(struct tevent_req *req, int *err)
return state->ret;
}
-static bool closed_fd(int fd)
-{
- struct timeval tv;
- fd_set r_fds;
- int selret;
-
- if (fd == -1) {
- return true;
- }
-
- FD_ZERO(&r_fds);
- FD_SET(fd, &r_fds);
- ZERO_STRUCT(tv);
-
- selret = select(fd+1, &r_fds, NULL, NULL, &tv);
- if (selret == -1) {
- return true;
- }
- if (selret == 0) {
- return false;
- }
- return (FD_ISSET(fd, &r_fds));
-}
-
struct wb_simple_trans_state {
struct tevent_context *ev;
int fd;
@@ -384,11 +360,6 @@ struct tevent_req *wb_simple_trans_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- if (closed_fd(fd)) {
- tevent_req_error(req, EPIPE);
- return tevent_req_post(req, ev);
- }
-
wb_req->length = sizeof(struct winbindd_request);
state->ev = ev;
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
index 63401fad46..979aa94d40 100644
--- a/source3/lib/wbclient.c
+++ b/source3/lib/wbclient.c
@@ -376,7 +376,7 @@ static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq)
state->wb_req.cmd = WINBINDD_INTERFACE_VERSION;
state->wb_req.pid = getpid();
- subreq = wb_simple_trans_send(state, state->ev, state->wb_ctx->queue,
+ subreq = wb_simple_trans_send(state, state->ev, NULL,
state->wb_ctx->fd, &state->wb_req);
if (tevent_req_nomem(subreq, req)) {
return;
@@ -408,7 +408,7 @@ static void wb_open_pipe_ping_done(struct tevent_req *subreq)
state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR;
state->wb_req.pid = getpid();
- subreq = wb_simple_trans_send(state, state->ev, state->wb_ctx->queue,
+ subreq = wb_simple_trans_send(state, state->ev, NULL,
state->wb_ctx->fd, &state->wb_req);
if (tevent_req_nomem(subreq, req)) {
return;
@@ -477,6 +477,31 @@ struct wb_trans_state {
bool need_priv;
};
+static bool closed_fd(int fd)
+{
+ struct timeval tv;
+ fd_set r_fds;
+ int selret;
+
+ if (fd == -1) {
+ return true;
+ }
+
+ FD_ZERO(&r_fds);
+ FD_SET(fd, &r_fds);
+ ZERO_STRUCT(tv);
+
+ selret = select(fd+1, &r_fds, NULL, NULL, &tv);
+ if (selret == -1) {
+ return true;
+ }
+ if (selret == 0) {
+ return false;
+ }
+ return (FD_ISSET(fd, &r_fds));
+}
+
+static void wb_trans_trigger(struct tevent_req *req, void *private_data);
static void wb_trans_connect_done(struct tevent_req *subreq);
static void wb_trans_done(struct tevent_req *subreq);
static void wb_trans_retry_wait_done(struct tevent_req *subreq);
@@ -486,7 +511,7 @@ struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
struct wb_context *wb_ctx, bool need_priv,
struct winbindd_request *wb_req)
{
- struct tevent_req *req, *subreq;
+ struct tevent_req *req;
struct wb_trans_state *state;
req = tevent_req_create(mem_ctx, &state, struct wb_trans_state);
@@ -499,27 +524,44 @@ struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
state->num_retries = 10;
state->need_priv = need_priv;
- if ((wb_ctx->fd == -1) || (need_priv && !wb_ctx->is_priv)) {
- subreq = wb_open_pipe_send(state, ev, wb_ctx, need_priv);
- if (subreq == NULL) {
- goto fail;
+ if (!tevent_queue_add(wb_ctx->queue, ev, req, wb_trans_trigger,
+ NULL)) {
+ tevent_req_nomem(NULL, req);
+ return tevent_req_post(req, ev);
+ }
+ return req;
+}
+
+static void wb_trans_trigger(struct tevent_req *req, void *private_data)
+{
+ struct wb_trans_state *state = tevent_req_data(
+ req, struct wb_trans_state);
+ struct tevent_req *subreq;
+
+ if ((state->wb_ctx->fd != -1) && closed_fd(state->wb_ctx->fd)) {
+ close(state->wb_ctx->fd);
+ state->wb_ctx->fd = -1;
+ }
+
+ if ((state->wb_ctx->fd == -1)
+ || (state->need_priv && !state->wb_ctx->is_priv)) {
+ subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
+ state->need_priv);
+ if (tevent_req_nomem(subreq, req)) {
+ return;
}
tevent_req_set_callback(subreq, wb_trans_connect_done, req);
- return req;
+ return;
}
state->wb_req->pid = getpid();
- subreq = wb_simple_trans_send(state, ev, wb_ctx->queue, wb_ctx->fd,
- wb_req);
- if (subreq == NULL) {
- goto fail;
+ subreq = wb_simple_trans_send(state, state->ev, NULL,
+ state->wb_ctx->fd, state->wb_req);
+ if (tevent_req_nomem(subreq, req)) {
+ return;
}
tevent_req_set_callback(subreq, wb_trans_done, req);
- return req;
- fail:
- TALLOC_FREE(req);
- return NULL;
}
static bool wb_trans_retry(struct tevent_req *req,
@@ -603,7 +645,7 @@ static void wb_trans_connect_done(struct tevent_req *subreq)
return;
}
- subreq = wb_simple_trans_send(state, state->ev, state->wb_ctx->queue,
+ subreq = wb_simple_trans_send(state, state->ev, NULL,
state->wb_ctx->fd, state->wb_req);
if (tevent_req_nomem(subreq, req)) {
return;