s3-winbind: make child_process_request async
authorDavid Disseldorp <ddiss@samba.org>
Tue, 16 Apr 2013 13:17:53 +0000 (15:17 +0200)
committerDavid Disseldorp <ddiss@samba.org>
Tue, 16 Apr 2013 13:51:57 +0000 (15:51 +0200)
Back-end dispatch is still done synchronously, but this will be changed
to async in future.

source3/winbindd/winbindd_dual.c

index dc5e50f67a18106d3c0bd0e17716c464889bb1c2..d77aa33c75e014e73b7e7d87435224dbe770bd27 100644 (file)
@@ -451,11 +451,22 @@ int wb_domain_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
        return 0;
 }
 
-static void child_process_request(struct winbindd_child *child,
-                                 struct winbindd_cli_state *state)
+struct child_req_state {
+};
+
+static struct tevent_req *child_process_request_send(TALLOC_CTX *mem_ctx,
+                                       struct event_context *ev,
+                                       struct winbindd_domain *domain,
+                            const struct winbindd_child_dispatch_table *table,
+                                       struct winbindd_cli_state *state)
 {
-       struct winbindd_domain *domain = child->domain;
-       const struct winbindd_child_dispatch_table *table = child->table;
+       struct tevent_req *req;
+       struct child_req_state *cr_state;
+
+       req = tevent_req_create(mem_ctx, &cr_state, struct child_req_state);
+       if (req == NULL) {
+               return NULL;
+       }
 
        /* Free response data - we may be interrupted and receive another
           command before being able to send this data off. */
@@ -472,13 +483,33 @@ static void child_process_request(struct winbindd_child *child,
                        SMB_ASSERT(table->type == WINBINDD_CHILD_DISPATCH_SYNC);
                        state->response->result = table->sync.struct_fn(domain,
                                                                        state);
-                       return;
+                       tevent_req_done(req);
+                       return tevent_req_post(req, ev);
                }
        }
 
        DEBUG(1, ("child_process_request: unknown request fn number %d\n",
                  (int)state->request->cmd));
        state->response->result = WINBINDD_ERROR;
+       tevent_req_done(req);
+       return tevent_req_post(req, ev);
+}
+
+/*
+ * TODO: child_process_request_send code path fills state->response, nothing to
+ * do here until async support is added.
+ */
+static NTSTATUS child_process_request_recv(struct tevent_req *req,
+                                          struct winbindd_response *rsp)
+{
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+
+       return NT_STATUS_OK;
 }
 
 void setup_child(struct winbindd_domain *domain, struct winbindd_child *child,
@@ -1322,6 +1353,8 @@ struct winbindd_domain *wb_child_domain(void)
        return child_domain;
 }
 
+static void domain_child_loop_done(struct tevent_req *req);
+
 static bool fork_domain_child(struct winbindd_child *child)
 {
        int fdpair[2];
@@ -1498,6 +1531,7 @@ static bool fork_domain_child(struct winbindd_child *child)
                int timeout;
                struct timeval t;
                struct timeval *tp;
+               struct tevent_req *req;
                TALLOC_CTX *mem_ctx = talloc_new(NULL);
                if (mem_ctx == NULL) {
                        _exit(1);
@@ -1586,17 +1620,37 @@ static bool fork_domain_child(struct winbindd_child *child)
                }
 
                state.mem_ctx = mem_ctx;
-               child_process_request(child, &state);
-
-               DEBUG(4, ("Finished processing child request %d\n",
-                         (int)state.request->cmd));
-
-               status = child_write_response(state.sock, state.response);
-               if (!NT_STATUS_IS_OK(status)) {
+               req = child_process_request_send(mem_ctx, ev, child->domain,
+                                                child->table, &state);
+               if (req == NULL) {
+                       DEBUG(0, ("failed to dispatch child request\n"));
+                       TALLOC_FREE(mem_ctx);
                        _exit(1);
                }
-               TALLOC_FREE(mem_ctx);
+               tevent_req_set_callback(req,
+                                       domain_child_loop_done,
+                                       &state);
+
+       }
+}
+
+static void domain_child_loop_done(struct tevent_req *req)
+{
+       NTSTATUS status;
+       struct winbindd_cli_state *state = tevent_req_callback_data(req,
+                                               struct winbindd_cli_state);
+
+       DEBUG(4, ("Finished processing child request %d\n",
+                 (int)state->request->cmd));
+
+       child_process_request_recv(req, state->response);
+       talloc_free(req);
+
+       status = child_write_response(state->sock, state->response);
+       if (!NT_STATUS_IS_OK(status)) {
+               _exit(1);
        }
+       TALLOC_FREE(state->mem_ctx);
 }
 
 void winbind_msg_ip_dropped_parent(struct messaging_context *msg_ctx,