s3-winbind: handle async child dispatch table entries
authorDavid Disseldorp <ddiss@samba.org>
Tue, 16 Apr 2013 14:09:45 +0000 (16:09 +0200)
committerDavid Disseldorp <ddiss@samba.org>
Tue, 16 Apr 2013 14:13:50 +0000 (16:13 +0200)
source3/winbindd/winbindd_dual.c

index d77aa33c75e014e73b7e7d87435224dbe770bd27..9a8f2482f9c6a876285063df8f58263bcff1ecd4 100644 (file)
@@ -452,7 +452,10 @@ int wb_domain_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 }
 
 struct child_req_state {
+       const struct winbindd_child_dispatch_table *table;
+       struct winbindd_response *response;
 };
+static void child_process_request_done(struct tevent_req *subreq);
 
 static struct tevent_req *child_process_request_send(TALLOC_CTX *mem_ctx,
                                        struct event_context *ev,
@@ -477,24 +480,52 @@ static struct tevent_req *child_process_request_send(TALLOC_CTX *mem_ctx,
        /* Process command */
 
        for (; table->name; table++) {
-               if (state->request->cmd == table->struct_cmd) {
-                       DEBUG(10,("child_process_request: request fn %s\n",
-                                 table->name));
-                       SMB_ASSERT(table->type == WINBINDD_CHILD_DISPATCH_SYNC);
+               if (state->request->cmd != table->struct_cmd)
+                       continue;
+
+               DEBUG(10,("request fn %s\n", table->name));
+               cr_state->table = table;
+               cr_state->response = state->response;;
+               if (table->type == WINBINDD_CHILD_DISPATCH_SYNC) {
                        state->response->result = table->sync.struct_fn(domain,
                                                                        state);
                        tevent_req_done(req);
                        return tevent_req_post(req, ev);
+               } else if (table->type == WINBINDD_CHILD_DISPATCH_ASYNC) {
+                       struct tevent_req *subreq;
+                       subreq = table->async.struct_fn_send(cr_state, ev,
+                                                            domain, state);
+                       if (tevent_req_nomem(subreq, req)) {
+                               return tevent_req_post(req, ev);
+                       }
+                       tevent_req_set_callback(subreq,
+                                               child_process_request_done,
+                                               req);
+                       return req;
+               } else {
+                       DEBUG(0, ("invalid dispatch table entry!\n"));
                }
        }
 
-       DEBUG(1, ("child_process_request: unknown request fn number %d\n",
-                 (int)state->request->cmd));
+       DEBUG(1, ("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);
 }
 
+/* only used for async dispatch table entries */
+static void child_process_request_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct child_req_state *cr_state = tevent_req_data(req,
+                                                       struct child_req_state);
+
+       SMB_ASSERT(cr_state->table->type == WINBINDD_CHILD_DISPATCH_ASYNC);
+       cr_state->response->result = cr_state->table->async.struct_fn_recv(subreq);
+       tevent_req_done(req);
+}
+
 /*
  * TODO: child_process_request_send code path fills state->response, nothing to
  * do here until async support is added.