Make noconcurrency more efficient
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 31 Aug 2017 17:21:03 +0000 (19:21 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 31 Aug 2017 17:21:03 +0000 (19:21 +0200)
The previous handling of noconcurrency suffered of
inefficiency, was complicated and dedicated to
api-so-v2.

Change-Id: I32aea9187663ac533819496e9dc9b944db0d89ec
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/afb-api-dbus.c
src/afb-api-so-v1.c
src/afb-api-so-v2.c
src/afb-api.h
src/afb-stub-ws.c
src/afb-xreq.c

index 0e51c63..3884b60 100644 (file)
@@ -610,6 +610,7 @@ int afb_api_dbus_add_client(const char *path, struct afb_apiset *apiset)
        /* record it as an API */
        afb_api.closure = api;
        afb_api.itf = &dbus_api_itf;
+       afb_api.noconcurrency = 0;
        if (afb_apiset_add(apiset, api->api, afb_api) < 0)
                goto error2;
 
index 3eea464..2a5dc08 100644 (file)
@@ -304,6 +304,7 @@ int afb_api_so_v1_add(const char *path, void *handle, struct afb_apiset *apiset)
        afb_ditf_rename(&desc->ditf, desc->binding->v1.prefix);
        afb_api.closure = desc;
        afb_api.itf = &so_v1_api_itf;
+       afb_api.noconcurrency = 0;
        if (afb_apiset_add(apiset, desc->binding->v1.prefix, afb_api) < 0) {
                ERROR("binding [%s] can't be registered...", path);
                goto error2;
index 038f1ce..871be52 100644 (file)
@@ -76,31 +76,6 @@ static void call_cb(void *closure, struct afb_xreq *xreq)
        afb_xreq_call_verb_v2(xreq, verb);
 }
 
-struct call_sync
-{
-       struct api_so_v2 *desc;
-       struct afb_xreq *xreq;
-};
-
-static void call_sync_cb_cb(int signum, void *closure)
-{
-       struct call_sync *cs = closure;
-       if (!signum)
-               call_cb(cs->desc, cs->xreq);
-       else  {
-               if (!cs->xreq->replied)
-                       afb_xreq_fail(cs->xreq, "aborted", "internal error");
-       }
-}
-
-static void call_sync_cb(void *closure, struct afb_xreq *xreq)
-{
-       struct call_sync cs = { .desc = closure, .xreq = xreq };
-
-       if (jobs_call(closure, 0, call_sync_cb_cb, &cs))
-               call_cb(closure, xreq);
-}
-
 static int service_start_cb(void *closure, int share_session, int onneed, struct afb_apiset *apiset)
 {
        int rc;
@@ -280,15 +255,6 @@ static struct afb_api_itf so_v2_api_itf = {
        .describe = describe_cb
 };
 
-static struct afb_api_itf so_v2_sync_api_itf = {
-       .call = call_sync_cb,
-       .service_start = service_start_cb,
-       .update_hooks = update_hooks_cb,
-       .get_verbosity = get_verbosity_cb,
-       .set_verbosity = set_verbosity_cb,
-       .describe = describe_cb
-};
-
 int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle, struct afb_apiset *apiset, struct afb_binding_data_v2 *data)
 {
        int rc;
@@ -328,7 +294,8 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle
 
        /* records the binding */
        afb_api.closure = desc;
-       afb_api.itf = binding->noconcurrency ? &so_v2_sync_api_itf : &so_v2_api_itf;
+       afb_api.itf = &so_v2_api_itf;
+       afb_api.noconcurrency = binding->noconcurrency;
        if (afb_apiset_add(apiset, binding->api, afb_api) < 0) {
                ERROR("binding %s can't be registered to set %s...", binding->api, afb_apiset_name(apiset));
                goto error2;
index c8cb2d6..1a14988 100644 (file)
@@ -35,6 +35,7 @@ struct afb_api
 {
        void *closure;
        struct afb_api_itf *itf;
+       unsigned noconcurrency: 1;
 };
 
 extern int afb_api_is_valid_name(const char *name);
index ce68b44..cb52923 100644 (file)
@@ -1337,6 +1337,7 @@ struct afb_api afb_stub_ws_client_api(struct afb_stub_ws *stubws)
        assert(!stubws->listener); /* check client */
        api.closure = stubws;
        api.itf = &ws_api_itf;
+       api.noconcurrency = 0;
        return api;
 }
 
index 73841af..d021c52 100644 (file)
@@ -884,15 +884,15 @@ static void process_sync(struct afb_xreq *xreq)
                afb_hook_xreq_begin(xreq);
 
        /* search the api */
-       api = afb_apiset_lookup_started(xreq->apiset, xreq->api, 1);
-       if (!api) {
+       api = (const struct afb_api*)xreq->context.api_key;
+       if (api)
+               api->itf->call(api->closure, xreq);
+       else {
+               api = afb_apiset_lookup_started(xreq->apiset, xreq->api, 1);
                if (errno == ENOENT)
                        afb_xreq_fail_f(xreq, "unknown-api", "api %s not found", xreq->api);
                else
                        afb_xreq_fail_f(xreq, "bad-api-state", "api %s not started correctly: %m", xreq->api);
-       } else {
-               xreq->context.api_key = api->closure;
-               api->itf->call(api->closure, xreq);
        }
 }
 
@@ -910,10 +910,14 @@ static void process_async(int signum, void *arg)
 
 void afb_xreq_process(struct afb_xreq *xreq, struct afb_apiset *apiset)
 {
+       const struct afb_api *api;
+
        xreq->apiset = apiset;
+       api = afb_apiset_lookup_started(apiset, xreq->api, 1);
+       xreq->context.api_key = (void*)api;
 
        xreq_addref(xreq);
-       if (jobs_queue(NULL, afb_apiset_timeout_get(apiset), process_async, xreq) < 0) {
+       if (jobs_queue(api && api->noconcurrency ? (void*)api : NULL, afb_apiset_timeout_get(apiset), process_async, xreq) < 0) {
                /* TODO: allows or not to proccess it directly as when no threading? (see above) */
                ERROR("can't process job with threads: %m");
                afb_xreq_fail_f(xreq, "cancelled", "not able to create a job for the task");