Author: abartlet
Date: 2006-08-10 10:03:42 +0000 (Thu, 10 Aug 2006)
New Revision: 17475

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=17475

Log:
When we make more than one remote search, we need to wait for them all
to finish.

Andrew Bartlett

Modified:
   branches/SOC/mkhl/ldb-map/modules/ldb_map.c


Changeset:
Modified: branches/SOC/mkhl/ldb-map/modules/ldb_map.c
===================================================================
--- branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-08-10 01:51:27 UTC (rev 
17474)
+++ branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-08-10 10:03:42 UTC (rev 
17475)
@@ -134,6 +134,10 @@
        struct ldb_request *remote_req;
        struct ldb_request *down_req;
        struct ldb_request *search_req;
+
+       /* for search, we may have a lot of contexts */
+       int num_searches;
+       struct ldb_request **search_reqs;
 };
 
 /* Context data for mapped search requests */
@@ -2073,6 +2077,7 @@
                    const struct ldb_dn *dn,
                    const char * const *attrs,
                    const struct ldb_parse_tree *tree,
+                   void *context,
                    ldb_search_callback callback)
 {
        struct ldb_request *req;
@@ -2099,7 +2104,7 @@
        }
 
        req->controls = NULL;
-       req->context = ac;
+       req->context = context;
        req->callback = callback;
        ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, req);
 
@@ -2129,7 +2134,7 @@
        tree->operation = LDB_OP_PRESENT;
        tree->u.present.attr = talloc_strdup(tree, IS_MAPPED);
 
-       return map_search_base_req(ac, dn, attrs, tree, 
map_search_self_callback);
+       return map_search_base_req(ac, dn, attrs, tree, ac, 
map_search_self_callback);
 }
 
 /* Build a request to update the 'IS_MAPPED' attribute */
@@ -2325,13 +2330,23 @@
 
        /* Prepare local search request */
        /* TODO: use GUIDs here instead? */
-       req = map_search_base_req(ac, ares->message->dn, NULL, NULL, 
map_local_merge_callback);
+
+       ac->search_reqs = talloc_realloc(ac, ac->search_reqs, struct 
ldb_request *, ac->num_searches + 2);
+       if (ac->search_reqs == NULL) {
+               talloc_free(ares);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       ac->search_reqs[ac->num_searches]
+               = req = map_search_base_req(ac, ares->message->dn, 
+                                           NULL, NULL, sc, 
map_local_merge_callback);
        if (req == NULL) {
                talloc_free(sc);
                talloc_free(ares);
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       req->context = sc;
+       ac->num_searches++;
+       ac->search_reqs[ac->num_searches] = NULL;
 
        return ldb_next_request(ac->module, req);
 }
@@ -2367,30 +2382,38 @@
        }
        ac = talloc_get_type(h->private_data, struct map_context);
 
+       ac->search_reqs = talloc_array(ac, struct ldb_request *, 2);
+       if (ac->search_reqs == NULL) {
+               talloc_free(h);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       ac->num_searches = 1;
+       ac->search_reqs[1] = NULL;
+
        /* Prepare the remote operation */
-       ac->remote_req = talloc(ac, struct ldb_request);
-       if (ac->remote_req == NULL) {
+       ac->search_reqs[0] = talloc(ac, struct ldb_request);
+       if (ac->search_reqs[0] == NULL) {
                goto oom;
        }
 
-       *(ac->remote_req) = *req;       /* copy the request */
+       *(ac->search_reqs[0]) = *req;   /* copy the request */
 
-       ac->remote_req->handle = h;     /* return our own handle to deal with 
this call */
+       ac->search_reqs[0]->handle = h; /* return our own handle to deal with 
this call */
 
-       ac->remote_req->context = ac;
-       ac->remote_req->callback = map_remote_search_callback;
+       ac->search_reqs[0]->context = ac;
+       ac->search_reqs[0]->callback = map_remote_search_callback;
 
        /* Split local from remote attrs */
-       ret = map_flarp(module, ac, ac->remote_req, &local_attrs, 
&remote_attrs, req->op.search.attrs, req->op.search.tree);
+       ret = map_flarp(module, ac, ac->search_reqs[0], &local_attrs, 
&remote_attrs, req->op.search.attrs, req->op.search.tree);
        if (ret) {
                goto failed;
        }
 
        ac->local_attrs = local_attrs;
-       ac->remote_req->op.search.attrs = remote_attrs;
+       ac->search_reqs[0]->op.search.attrs = remote_attrs;
 
        /* Split local from remote tree */
-       ret = ldb_parse_tree_partition(module, ac, ac->remote_req, &local_tree, 
&remote_tree, req->op.search.tree);
+       ret = ldb_parse_tree_partition(module, ac, ac->search_reqs[0], 
&local_tree, &remote_tree, req->op.search.tree);
        if (ret) {
                goto failed;
        }
@@ -2415,25 +2438,25 @@
        }
        if (remote_tree == NULL) {
                /* Construct default remote parse tree */
-               remote_tree = ldb_parse_tree(ac->remote_req, NULL);
+               remote_tree = ldb_parse_tree(ac->search_reqs[0], NULL);
                if (remote_tree == NULL) {
                        goto failed;
                }
        }
 
        ac->local_tree = local_tree;
-       ac->remote_req->op.search.tree = remote_tree;
+       ac->search_reqs[0]->op.search.tree = remote_tree;
 
-       ldb_set_timeout_from_prev_req(module->ldb, req, ac->remote_req);
+       ldb_set_timeout_from_prev_req(module->ldb, req, ac->search_reqs[0]);
 
        h->state = LDB_ASYNC_INIT;
        h->status = LDB_SUCCESS;
 
        ac->step = MAP_SEARCH_REMOTE;
 
-       ret = ldb_next_remote_request(module, ac->remote_req);
+       ret = ldb_next_remote_request(module, ac->search_reqs[0]);
        if (ret == LDB_SUCCESS) {
-               req->handle = ac->remote_req->handle;
+               req->handle = h;
        }
        return ret;
 
@@ -3046,12 +3069,15 @@
        case MAP_RENAME_FIXUP:
                return ac->down_req;
 
-       case MAP_SEARCH_REMOTE:
        case MAP_ADD_LOCAL:
        case MAP_MODIFY_LOCAL:
        case MAP_DELETE_LOCAL:
        case MAP_RENAME_LOCAL:
                return ac->local_req;
+
+       case MAP_SEARCH_REMOTE:
+               /* Can't happen */
+               break;
        }
 
        return NULL;            /* unreachable; silences a warning */
@@ -3123,27 +3149,48 @@
 
        ac = talloc_get_type(handle->private_data, struct map_context);
 
-       req = map_get_req(ac);
-
-       ret = ldb_wait(req->handle, LDB_WAIT_NONE);
-
-       if (ret != LDB_SUCCESS) {
-               handle->status = ret;
-               goto done;
-       }
-       if (req->handle->status != LDB_SUCCESS) {
+       if (ac->step == MAP_SEARCH_REMOTE) {
+               int i;
+               for (i=0; i < ac->num_searches; i++) {
+                       req = ac->search_reqs[i];
+                       ret = ldb_wait(req->handle, LDB_WAIT_NONE);
+                       
+                       if (ret != LDB_SUCCESS) {
+                               handle->status = ret;
+                               goto done;
+                       }
+                       if (req->handle->status != LDB_SUCCESS) {
+                               handle->status = req->handle->status;
+                               goto done;
+                       }
+                       if (req->handle->state != LDB_ASYNC_DONE) {
+                               return LDB_SUCCESS;
+                       }
+               }
+       } else {
+               
+               req = map_get_req(ac);
+               
+               ret = ldb_wait(req->handle, LDB_WAIT_NONE);
+               
+               if (ret != LDB_SUCCESS) {
+                       handle->status = ret;
+                       goto done;
+               }
+               if (req->handle->status != LDB_SUCCESS) {
                handle->status = req->handle->status;
                goto done;
+               }
+               if (req->handle->state != LDB_ASYNC_DONE) {
+                       return LDB_SUCCESS;
+               }
+               
+               next = map_get_next(ac);
+               if (next) {
+                       return next(handle);
+               }
        }
-       if (req->handle->state != LDB_ASYNC_DONE) {
-               return LDB_SUCCESS;
-       }
 
-       next = map_get_next(ac);
-       if (next) {
-               return next(handle);
-       }
-
        ret = LDB_SUCCESS;
 
 done:

Reply via email to