svn commit: samba r20656 - in branches/SAMBA_4_0/source/lib/ldb/modules: .

idra at samba.org idra at samba.org
Wed Jan 10 18:18:13 GMT 2007


Author: idra
Date: 2007-01-10 18:18:13 +0000 (Wed, 10 Jan 2007)
New Revision: 20656

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

Log:

This way the process flow should be much more readable.
We need to make it easier, but this should be a step in
the right direction.


Modified:
   branches/SAMBA_4_0/source/lib/ldb/modules/asq.c


Changeset:
Modified: branches/SAMBA_4_0/source/lib/ldb/modules/asq.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/modules/asq.c	2007-01-10 17:47:53 UTC (rev 20655)
+++ branches/SAMBA_4_0/source/lib/ldb/modules/asq.c	2007-01-10 18:18:13 UTC (rev 20656)
@@ -38,12 +38,13 @@
 
 struct asq_context {
 
-	enum {ASQ_SEARCH_BASE, ASQ_SEARCH_MULTI} step;
+	enum {ASQ_INIT, ASQ_SEARCH_BASE, ASQ_SEARCH_MULTI} step;
 
 	struct ldb_module *module;
-	void *up_context;
-	int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *);
+	struct ldb_request *orig_req;
 
+	struct ldb_asq_control *asq_ctrl;
+
 	const char * const *req_attrs;
 	char *req_attribute;
 	enum {
@@ -63,14 +64,12 @@
 	struct ldb_control **controls;
 };
 
-static struct ldb_handle *init_handle(void *mem_ctx, struct ldb_module *module,
-					    void *context,
-					    int (*callback)(struct ldb_context *, void *, struct ldb_reply *))
+static struct ldb_handle *init_handle(struct ldb_request *req, struct ldb_module *module)
 {
 	struct asq_context *ac;
 	struct ldb_handle *h;
 
-	h = talloc_zero(mem_ctx, struct ldb_handle);
+	h = talloc_zero(req, struct ldb_handle);
 	if (h == NULL) {
 		ldb_set_errstring(module->ldb, "Out of Memory");
 		return NULL;
@@ -90,9 +89,9 @@
 	h->state = LDB_ASYNC_INIT;
 	h->status = LDB_SUCCESS;
 
+	ac->step = ASQ_INIT;
 	ac->module = module;
-	ac->up_context = context;
-	ac->up_callback = callback;
+	ac->orig_req = req;
 
 	return h;
 }
@@ -147,7 +146,7 @@
 
 	ares->controls[i + 1] = NULL;
 
-	ac->up_callback(ac->module->ldb, ac->up_context, ares);
+	ac->orig_req->callback(ac->module->ldb, ac->orig_req->context, ares);
 
 	return LDB_SUCCESS;
 }
@@ -198,7 +197,7 @@
 
 		/* pass the message up to the original callback as we
 		 * do not have to elaborate on it any further */
-		return ac->up_callback(ac->module->ldb, ac->up_context, ares);
+		return ac->orig_req->callback(ac->module->ldb, ac->orig_req->context, ares);
 		
 	} else { /* ignore any REFERRAL or DONE reply */
 		talloc_free(ares);
@@ -210,96 +209,38 @@
 	return LDB_ERR_OPERATIONS_ERROR;
 }
 
-static int asq_search(struct ldb_module *module, struct ldb_request *req)
+static int asq_build_first_request(struct asq_context *ac)
 {
-	struct ldb_control *control;
-	struct ldb_asq_control *asq_ctrl;
-	struct asq_context *ac;
-	struct ldb_handle *h;
 	char **base_attrs;
-	int ret;
 
-	/* check if there's a paged request control */
-	control = get_control_from_list(req->controls, LDB_CONTROL_ASQ_OID);
-	if (control == NULL) {
-		/* not found go on */
-		return ldb_next_request(module, req);
-	}
+	ac->base_req = talloc_zero(ac, struct ldb_request);
+	if (ac->base_req == NULL) return LDB_ERR_OPERATIONS_ERROR;
 
-	req->handle = NULL;
+	ac->base_req->operation = ac->orig_req->operation;
+	ac->base_req->op.search.base = ac->orig_req->op.search.base;
+	ac->base_req->op.search.scope = LDB_SCOPE_BASE;
+	ac->base_req->op.search.tree = ac->orig_req->op.search.tree;
+	base_attrs = talloc_array(ac->base_req, char *, 2);
+	if (base_attrs == NULL) return LDB_ERR_OPERATIONS_ERROR;
 
-	if (!req->callback || !req->context) {
-		ldb_set_errstring(module->ldb,
-				  "Async interface called with NULL callback function or NULL context");
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	
-	asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control);
-	if (!asq_ctrl) {
-		return LDB_ERR_PROTOCOL_ERROR;
-	}
+	base_attrs[0] = talloc_strdup(base_attrs, ac->asq_ctrl->source_attribute);
+	if (base_attrs[0] == NULL) return LDB_ERR_OPERATIONS_ERROR;
 
-	h = init_handle(req, module, req->context, req->callback);
-	if (!h) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	ac = talloc_get_type(h->private_data, struct asq_context);
-
-	req->handle = h;
-
-	/* check the search is well formed */
-	if (req->op.search.scope != LDB_SCOPE_BASE) {
-		ac->asq_ret = ASQ_CTRL_UNWILLING_TO_PERFORM;
-		return asq_terminate(h);
-	}
-
-	ac->req_attrs = req->op.search.attrs;
-	ac->req_attribute = talloc_strdup(ac, asq_ctrl->source_attribute);
-	if (ac->req_attribute == NULL)
-		return LDB_ERR_OPERATIONS_ERROR;
-
-	/* get the object to retrieve the DNs to search */
-	ac->base_req = talloc_zero(req, struct ldb_request);
-	if (ac->base_req == NULL)
-		return LDB_ERR_OPERATIONS_ERROR;
-	ac->base_req->operation = req->operation;
-	ac->base_req->op.search.base = req->op.search.base;
-	ac->base_req->op.search.scope = LDB_SCOPE_BASE;
-	ac->base_req->op.search.tree = req->op.search.tree;
-	base_attrs = talloc_array(ac->base_req, char *, 2);
-	if (base_attrs == NULL)
-		return LDB_ERR_OPERATIONS_ERROR;
-	base_attrs[0] = talloc_strdup(base_attrs, asq_ctrl->source_attribute);
-	if (base_attrs[0] == NULL)
-		return LDB_ERR_OPERATIONS_ERROR;
 	base_attrs[1] = NULL;
 	ac->base_req->op.search.attrs = (const char * const *)base_attrs;
 
 	ac->base_req->context = ac;
 	ac->base_req->callback = asq_base_callback;
-	ldb_set_timeout_from_prev_req(module->ldb, req, ac->base_req);
+	ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->base_req);
 
-	ac->step = ASQ_SEARCH_BASE;
-
-	ret = ldb_request(module->ldb, ac->base_req);
-
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
 	return LDB_SUCCESS;
 }
 
-static int asq_requests(struct ldb_handle *handle) {
-	struct asq_context *ac;
+static int asq_build_multiple_requests(struct asq_context *ac, struct ldb_handle *handle)
+{
 	struct ldb_message_element *el;
 	int i;
 
-	ac = talloc_get_type(handle->private_data, struct asq_context);
-	if (ac == NULL) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
 	/* look up the DNs */
 	if (ac->base_res == NULL) {
 		return LDB_ERR_NO_SUCH_OBJECT;
@@ -311,7 +252,6 @@
 		return asq_terminate(handle);
 	}
 
-	/* build up the requests call chain */
 	ac->num_reqs = el->num_values;
 	ac->cur_req = 0;
 	ac->reqs = talloc_array(ac, struct ldb_request *, ac->num_reqs);
@@ -339,11 +279,114 @@
 		ldb_set_timeout_from_prev_req(ac->module->ldb, ac->base_req, ac->reqs[i]);
 	}
 
-	ac->step = ASQ_SEARCH_MULTI;
-
 	return LDB_SUCCESS;
 }
 
+static int asq_search_continue(struct ldb_handle *h)
+{
+	struct asq_context *ac;
+	int ret;
+
+	ac = talloc_get_type(h->private_data, struct asq_context);
+
+	switch (ac->step) {
+	case ASQ_INIT:
+		/* check the search is well formed */
+		if (ac->orig_req->op.search.scope != LDB_SCOPE_BASE) {
+			ac->asq_ret = ASQ_CTRL_UNWILLING_TO_PERFORM;
+			return asq_terminate(h);
+		}
+
+		ac->req_attrs = ac->orig_req->op.search.attrs;
+		ac->req_attribute = talloc_strdup(ac, ac->asq_ctrl->source_attribute);
+		if (ac->req_attribute == NULL)
+			return LDB_ERR_OPERATIONS_ERROR;
+
+		/* get the object to retrieve the DNs to search */
+		ret = asq_build_first_request(ac);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	
+		ac->step = ASQ_SEARCH_BASE;
+
+		return ldb_request(ac->module->ldb, ac->base_req);
+
+	case ASQ_SEARCH_BASE:
+
+		/* build up the requests call chain */
+		ret = asq_build_multiple_requests(ac, h);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+		if (h->state == LDB_ASYNC_DONE) {
+			return LDB_SUCCESS;
+		}
+
+		ac->step = ASQ_SEARCH_MULTI;
+
+		/* no break nor return,
+		 * the set of requests is performed in ASQ_SEARCH_MULTI
+		 */
+		/* fall through */
+
+	case ASQ_SEARCH_MULTI:
+
+		if (ac->cur_req >= ac->num_reqs) {
+			return asq_terminate(h);
+		}
+
+		return ldb_request(ac->module->ldb, ac->reqs[ac->cur_req]);
+
+	default:
+		ret = LDB_ERR_OPERATIONS_ERROR;
+		break;
+	}
+
+	/* this is reached only in case of error */
+	/* FIXME: fire an async reply ? */
+	h->status = ret;
+	h->state = LDB_ASYNC_DONE;
+	return ret;
+}
+
+static int asq_search(struct ldb_module *module, struct ldb_request *req)
+{
+	struct ldb_control *control;
+	struct asq_context *ac;
+	struct ldb_handle *h;
+
+	/* check if there's a paged request control */
+	control = get_control_from_list(req->controls, LDB_CONTROL_ASQ_OID);
+	if (control == NULL) {
+		/* not found go on */
+		return ldb_next_request(module, req);
+	}
+
+	req->handle = NULL;
+
+	if (!req->callback || !req->context) {
+		ldb_set_errstring(module->ldb,
+				  "Async interface called with NULL callback function or NULL context");
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	h = init_handle(req, module);
+	if (!h) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	ac = talloc_get_type(h->private_data, struct asq_context);
+
+	ac->asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control);
+	if (!ac->asq_ctrl) {
+		return LDB_ERR_PROTOCOL_ERROR;
+	}
+
+	req->handle = h;
+
+	return asq_search_continue(h);
+}
+
 static int asq_wait_none(struct ldb_handle *handle)
 {
 	struct asq_context *ac;
@@ -382,22 +425,10 @@
 			return LDB_SUCCESS;
 		}
 
-		ret = asq_requests(handle);
+		return asq_search_continue(handle);
 
-		/* no break nor return,
-		 * the set of requests is performed in ASQ_SEARCH_MULTI
-		 */
-		/* fall through */
-
 	case ASQ_SEARCH_MULTI:
 
-		if (ac->reqs[ac->cur_req]->handle == NULL) {
-			ret = ldb_request(ac->module->ldb, ac->reqs[ac->cur_req]);
-			if (ret != LDB_SUCCESS) {
-				return ret;
-			}
-		}
-
 		ret = ldb_wait(ac->reqs[ac->cur_req]->handle, LDB_WAIT_NONE);
 		
 		if (ret != LDB_SUCCESS) {
@@ -412,12 +443,8 @@
 			ac->cur_req++;
 		}
 
-		if (ac->cur_req < ac->num_reqs) {
-			return LDB_SUCCESS;
-		}
+		return asq_search_continue(handle);
 
-		return asq_terminate(handle);
-
 	default:
 		ret = LDB_ERR_OPERATIONS_ERROR;
 		goto done;



More information about the samba-cvs mailing list