aboutsummaryrefslogtreecommitdiffstats
path: root/src/cynagora.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cynagora.c')
-rw-r--r--src/cynagora.c222
1 files changed, 138 insertions, 84 deletions
diff --git a/src/cynagora.c b/src/cynagora.c
index 2e35876..7f3f001 100644
--- a/src/cynagora.c
+++ b/src/cynagora.c
@@ -756,6 +756,121 @@ async_reply_process(
return 1;
}
+static
+int
+async_check(
+ cynagora_t *cynagora,
+ const cynagora_key_t *key,
+ int force,
+ int simple,
+ cynagora_async_check_cb_t *callback,
+ void *closure,
+ const char *askid
+) {
+ int rc;
+ asreq_t *ar;
+ ascb_t *ac;
+ char *p;
+ int nf;
+ const char *fields[8];
+
+ /* ensure connection */
+ rc = ensure_opened(cynagora);
+ if (rc < 0)
+ return rc;
+
+ /* check cache item */
+ if (!force) {
+ /* ensure there is no clear cache pending */
+ flushr(cynagora);
+
+ rc = cache_search(cynagora->cache, key);
+ if (rc >= 0) {
+ callback(closure, rc);
+ return 0;
+ }
+ }
+
+ /* allocates the callback */
+ ac = malloc(sizeof *ac);
+ if (ac == NULL)
+ return -ENOMEM;
+ ac->callback = callback;
+ ac->closure = closure;
+
+ /* common request only if not subqueries of agents */
+ if (!askid) {
+ /* search the request */
+ ar = cynagora->async.requests;
+ while (ar && (strcmp(key->client, ar->key.client)
+ || strcmp(key->session, ar->key.session)
+ || strcmp(key->user, ar->key.user)
+ || strcmp(key->permission, ar->key.permission)))
+ ar = ar->next;
+
+ /* a same request is pending, use it */
+ if (ar) {
+ ac->next = ar->callbacks;
+ ar->callbacks = ac;
+ return 0;
+ }
+ }
+
+ /* allocate for the request */
+ ar = malloc(sizeof *ar + strlen(key->client) + strlen(key->session) + strlen(key->user) + strlen(key->permission) + 4);
+ if (ar == NULL) {
+ free(ac);
+ return -ENOMEM;
+ }
+
+ /* init */
+ ac->next = NULL;
+ ar->callbacks = ac;
+ p = (char*)(ar + 1);
+ ar->key.client = p;
+ p = stpcpy(p, key->client) + 1;
+ ar->key.session = p;
+ p = stpcpy(p, key->session) + 1;
+ ar->key.user = p;
+ p = stpcpy(p, key->user) + 1;
+ ar->key.permission = p;
+ stpcpy(p, key->permission);
+ do {
+ idgen_next(cynagora->idgen);
+ } while (search_async_request(cynagora, cynagora->idgen, false));
+ strcpy(ar->id, cynagora->idgen);
+ ar->next = cynagora->async.requests;
+ cynagora->async.requests = ar;
+
+ /* send the request */
+ if (askid) {
+ fields[0] = _sub_;
+ fields[1] = askid;
+ nf = 2;
+ } else {
+ fields[0] = simple ? _test_ : _check_;
+ nf = 1;
+ }
+ fields[nf++] = ar->id;
+ fields[nf++] = key->client;
+ fields[nf++] = key->session;
+ fields[nf++] = key->user;
+ fields[nf++] = key->permission;
+ rc = send_reply(cynagora, fields, nf);
+ if (rc < 0) {
+ ar = search_async_request(cynagora, ar->id, true);
+ while((ac = ar->callbacks)) {
+ ar->callbacks = ac->next;
+ free(ac);
+ }
+ free(ar);
+ return rc;
+ }
+
+ /* record the request */
+ return 0;
+}
+
/******************************************************************************/
/*** PUBLIC COMMON METHODS ***/
/******************************************************************************/
@@ -951,90 +1066,7 @@ cynagora_async_check(
cynagora_async_check_cb_t *callback,
void *closure
) {
- int rc;
- asreq_t *ar;
- ascb_t *ac;
- char *p;
-
- /* ensure connection */
- rc = ensure_opened(cynagora);
- if (rc < 0)
- return rc;
-
- /* check cache item */
- if (!force) {
- /* ensure there is no clear cache pending */
- flushr(cynagora);
-
- rc = cache_search(cynagora->cache, key);
- if (rc >= 0) {
- callback(closure, rc);
- return 0;
- }
- }
-
- /* allocates the callback */
- ac = malloc(sizeof *ac);
- if (ac == NULL)
- return -ENOMEM;
- ac->callback = callback;
- ac->closure = closure;
-
- /* search the request */
- ar = cynagora->async.requests;
- while (ar && (strcmp(key->client, ar->key.client)
- || strcmp(key->session, ar->key.session)
- || strcmp(key->user, ar->key.user)
- || strcmp(key->permission, ar->key.permission)))
- ar = ar->next;
-
- /* a same request is pending, use it */
- if (ar) {
- ac->next = ar->callbacks;
- ar->callbacks = ac;
- return 0;
- }
-
- /* allocate for the request */
- ar = malloc(sizeof *ar + strlen(key->client) + strlen(key->session) + strlen(key->user) + strlen(key->permission) + 4);
- if (ar == NULL) {
- free(ac);
- return -ENOMEM;
- }
-
- /* init */
- ac->next = NULL;
- ar->callbacks = ac;
- p = (char*)(ar + 1);
- ar->key.client = p;
- p = stpcpy(p, key->client) + 1;
- ar->key.session = p;
- p = stpcpy(p, key->session) + 1;
- ar->key.user = p;
- p = stpcpy(p, key->user) + 1;
- ar->key.permission = p;
- stpcpy(p, key->permission);
- do {
- idgen_next(cynagora->idgen);
- } while (search_async_request(cynagora, cynagora->idgen, false));
- strcpy(ar->id, cynagora->idgen);
- ar->next = cynagora->async.requests;
- cynagora->async.requests = ar;
-
- /* send the request */
- rc = putxkv(cynagora, simple ? _test_ : _check_, ar->id, key, 0);
- if (rc < 0) {
- ar = search_async_request(cynagora, ar->id, true);
- while((ac = ar->callbacks)) {
- ar->callbacks = ac->next;
- free(ac);
- }
- free(ar);
- return rc;
- }
-
- /* record the request */
- return 0;
+ return async_check(cynagora, key, force, simple, callback, closure, NULL);
}
/******************************************************************************/
@@ -1465,3 +1497,25 @@ cynagora_agent_reply(
free(query);
return rc;
}
+
+/* see cynagora.h */
+int
+cynagora_agent_subquery_async(
+ cynagora_query_t *_query,
+ const cynagora_key_t *key,
+ int force,
+ cynagora_async_check_cb_t *callback,
+ void *closure
+) {
+ int rc;
+ query_t *query = (query_t*)_query;
+ cynagora_t *cynagora;
+
+ cynagora = query->cynagora;
+ if (!cynagora)
+ rc = -ECANCELED;
+ else
+ rc = async_check(cynagora, key, force, false,
+ callback, closure, query->askid);
+ return rc;
+}