Optimisation of xreq
authorJosé Bollo <jose.bollo@iot.bzh>
Wed, 12 Apr 2017 15:00:33 +0000 (17:00 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Wed, 12 Apr 2017 15:00:33 +0000 (17:00 +0200)
Reduce the count of memory read

Change-Id: Ie4dfa4bd30d6485be91961196294c43ffbd3b2a9
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/afb-api-dbus.c
src/afb-api-ws.c
src/afb-hreq.c
src/afb-subcall.c
src/afb-svc.c
src/afb-ws-json1.c
src/afb-xreq.c
src/afb-xreq.h
src/main.c

index 593232b..b8ec3d0 100644 (file)
@@ -808,9 +808,9 @@ struct dbus_req {
 };
 
 /* decrement the reference count of the request and free/release it on falling to null */
-static void dbus_req_destroy(void *closure)
+static void dbus_req_destroy(struct afb_xreq *xreq)
 {
-       struct dbus_req *dreq = closure;
+       struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq);
 
        afb_context_disconnect(&dreq->xreq.context);
        json_object_put(dreq->json);
@@ -819,9 +819,9 @@ static void dbus_req_destroy(void *closure)
 }
 
 /* get the object of the request */
-static struct json_object *dbus_req_json(void *closure)
+static struct json_object *dbus_req_json(struct afb_xreq *xreq)
 {
-       struct dbus_req *dreq = closure;
+       struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq);
 
        return dreq->json;
 }
@@ -836,25 +836,25 @@ static void dbus_req_reply(struct dbus_req *dreq, uint8_t type, const char *firs
                ERROR("sending the reply failed");
 }
 
-static void dbus_req_success(void *closure, struct json_object *obj, const char *info)
+static void dbus_req_success(struct afb_xreq *xreq, struct json_object *obj, const char *info)
 {
-       struct dbus_req *dreq = closure;
+       struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq);
 
        dbus_req_reply(dreq, RETOK, json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN), info);
 }
 
-static void dbus_req_fail(void *closure, const char *status, const char *info)
+static void dbus_req_fail(struct afb_xreq *xreq, const char *status, const char *info)
 {
-       struct dbus_req *dreq = closure;
+       struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq);
 
        dbus_req_reply(dreq, RETERR, status, info);
 }
 
 static void afb_api_dbus_server_event_send(struct origin *origin, char order, const char *event, int eventid, const char *data, uint64_t msgid);
 
-static int dbus_req_subscribe(void *closure, struct afb_event event)
+static int dbus_req_subscribe(struct afb_xreq *xreq, struct afb_event event)
 {
-       struct dbus_req *dreq = closure;
+       struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq);
        uint64_t msgid;
        int rc;
 
@@ -864,9 +864,9 @@ static int dbus_req_subscribe(void *closure, struct afb_event event)
        return rc;
 }
 
-static int dbus_req_unsubscribe(void *closure, struct afb_event event)
+static int dbus_req_unsubscribe(struct afb_xreq *xreq, struct afb_event event)
 {
-       struct dbus_req *dreq = closure;
+       struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq);
        uint64_t msgid;
        int rc;
 
@@ -976,6 +976,7 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd
        }
 
        /* connect to the context */
+       afb_xreq_init(&dreq->xreq, &afb_api_dbus_xreq_itf);
        if (afb_context_connect(&dreq->xreq.context, uuid, NULL) < 0)
                goto out_of_memory;
        session = dreq->xreq.context.session;
@@ -994,9 +995,6 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd
                dreq->json = json_object_new_string(dreq->request);
        }
        dreq->listener = listener;
-       dreq->xreq.refcount = 1;
-       dreq->xreq.query = dreq;
-       dreq->xreq.queryitf = &afb_api_dbus_xreq_itf;
        dreq->xreq.api = api->api;
        dreq->xreq.verb = method;
        afb_apis_call(&dreq->xreq);
index 8be74c0..472a44d 100644 (file)
@@ -159,11 +159,11 @@ struct api_ws_server_req {
        uint32_t msgid;                 /* the incoming request msgid */
 };
 
-static void api_ws_server_req_success_cb(void *closure, struct json_object *obj, const char *info);
-static void api_ws_server_req_fail_cb(void *closure, const char *status, const char *info);
-static void api_ws_server_req_destroy_cb(void *closure);
-static int api_ws_server_req_subscribe_cb(void *closure, struct afb_event event);
-static int api_ws_server_req_unsubscribe_cb(void *closure, struct afb_event event);
+static void api_ws_server_req_success_cb(struct afb_xreq *xreq, struct json_object *obj, const char *info);
+static void api_ws_server_req_fail_cb(struct afb_xreq *xreq, const char *status, const char *info);
+static void api_ws_server_req_destroy_cb(struct afb_xreq *xreq);
+static int api_ws_server_req_subscribe_cb(struct afb_xreq *xreq, struct afb_event event);
+static int api_ws_server_req_unsubscribe_cb(struct afb_xreq *xreq, struct afb_event event);
 
 const struct afb_xreq_query_itf afb_api_ws_xreq_itf = {
        .success = api_ws_server_req_success_cb,
@@ -937,6 +937,7 @@ static void api_ws_server_called(struct api_ws_client *client, struct readbuf *r
         || !api_ws_read_string(rb, &wreq->request, &wreq->lenreq))
                goto overflow;
 
+       afb_xreq_init(&wreq->xreq, &afb_api_ws_xreq_itf);
        wreq->xreq.json = json_tokener_parse(wreq->request);
        if (wreq->xreq.json == NULL && strcmp(wreq->request, "null")) {
                wreq->xreq.json = json_object_new_string(wreq->request);
@@ -948,11 +949,8 @@ static void api_ws_server_called(struct api_ws_client *client, struct readbuf *r
        wreq->xreq.context.flags = flags;
 
        /* makes the call */
-       wreq->xreq.refcount = 1;
        wreq->xreq.api = client->api;
        wreq->xreq.verb = verb;
-       wreq->xreq.query = wreq;
-       wreq->xreq.queryitf = &afb_api_ws_xreq_itf;
        afb_apis_call(&wreq->xreq);
        afb_xreq_unref(&wreq->xreq);
        return;
@@ -1071,9 +1069,9 @@ static void api_ws_server_event_broadcast(void *closure, const char *event, int
 /******************* ws request part for server *****************/
 
 /* decrement the reference count of the request and free/release it on falling to null */
-static void api_ws_server_req_destroy_cb(void *closure)
+static void api_ws_server_req_destroy_cb(struct afb_xreq *xreq)
 {
-       struct api_ws_server_req *wreq = closure;
+       struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq);
 
        afb_context_disconnect(&wreq->xreq.context);
        json_object_put(wreq->xreq.json);
@@ -1082,11 +1080,11 @@ static void api_ws_server_req_destroy_cb(void *closure)
        free(wreq);
 }
 
-static void api_ws_server_req_success_cb(void *closure, struct json_object *obj, const char *info)
+static void api_ws_server_req_success_cb(struct afb_xreq *xreq, struct json_object *obj, const char *info)
 {
        int rc;
        struct writebuf wb = { .count = 0 };
-       struct api_ws_server_req *wreq = closure;
+       struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq);
 
        if (api_ws_write_char(&wb, 'T')
         && api_ws_write_uint32(&wb, wreq->msgid)
@@ -1102,11 +1100,11 @@ success:
        json_object_put(obj);
 }
 
-static void api_ws_server_req_fail_cb(void *closure, const char *status, const char *info)
+static void api_ws_server_req_fail_cb(struct afb_xreq *xreq, const char *status, const char *info)
 {
        int rc;
        struct writebuf wb = { .count = 0 };
-       struct api_ws_server_req *wreq = closure;
+       struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq);
 
        if (api_ws_write_char(&wb, 'F')
         && api_ws_write_uint32(&wb, wreq->msgid)
@@ -1120,11 +1118,11 @@ static void api_ws_server_req_fail_cb(void *closure, const char *status, const c
        ERROR("error while sending fail");
 }
 
-static int api_ws_server_req_subscribe_cb(void *closure, struct afb_event event)
+static int api_ws_server_req_subscribe_cb(struct afb_xreq *xreq, struct afb_event event)
 {
        int rc, rc2;
        struct writebuf wb = { .count = 0 };
-       struct api_ws_server_req *wreq = closure;
+       struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq);
 
        rc = afb_evt_add_watch(wreq->client->listener, event);
        if (rc < 0)
@@ -1143,11 +1141,11 @@ success:
        return rc;
 }
 
-static int api_ws_server_req_unsubscribe_cb(void *closure, struct afb_event event)
+static int api_ws_server_req_unsubscribe_cb(struct afb_xreq *xreq, struct afb_event event)
 {
        int rc, rc2;
        struct writebuf wb = { .count = 0 };
-       struct api_ws_server_req *wreq = closure;
+       struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq);
 
        if (api_ws_write_char(&wb, 'U')
         && api_ws_write_uint32(&wb, wreq->msgid)
index 69403f6..6589f0f 100644 (file)
@@ -72,19 +72,18 @@ struct hreq_data {
        char *path;             /* path of the file saved */
 };
 
-static struct json_object *req_json(struct afb_hreq *hreq);
-static struct afb_arg req_get(struct afb_hreq *hreq, const char *name);
-static void req_fail(struct afb_hreq *hreq, const char *status, const char *info);
-static void req_success(struct afb_hreq *hreq, json_object *obj, const char *info);
-
-static void afb_hreq_destroy(struct afb_hreq *hreq);
+static struct json_object *req_json(struct afb_xreq *xreq);
+static struct afb_arg req_get(struct afb_xreq *xreq, const char *name);
+static void req_fail(struct afb_xreq *xreq, const char *status, const char *info);
+static void req_success(struct afb_xreq *xreq, json_object *obj, const char *info);
+static void req_destroy(struct afb_xreq *xreq);
 
 const struct afb_xreq_query_itf afb_hreq_xreq_query_itf = {
-       .json = (void*)req_json,
-       .get = (void*)req_get,
-       .success = (void*)req_success,
-       .fail = (void*)req_fail,
-       .unref = (void*)afb_hreq_destroy
+       .json = req_json,
+       .get = req_get,
+       .success = req_success,
+       .fail = req_fail,
+       .unref = req_destroy
 };
 
 static struct hreq_data *get_data(struct afb_hreq *hreq, const char *key, int create)
@@ -299,8 +298,9 @@ static const char *mimetype_fd_name(int fd, const char *filename)
        return result;
 }
 
-static void afb_hreq_destroy(struct afb_hreq *hreq)
+static void req_destroy(struct afb_xreq *xreq)
 {
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
        struct hreq_data *data;
 
        if (hreq->postform != NULL)
@@ -820,9 +820,10 @@ int afb_hreq_post_add_file(struct afb_hreq *hreq, const char *key, const char *f
        return !size;
 }
 
-static struct afb_arg req_get(struct afb_hreq *hreq, const char *name)
+static struct afb_arg req_get(struct afb_xreq *xreq, const char *name)
 {
        const char *value;
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
        struct hreq_data *hdat = get_data(hreq, name, 0);
        if (hdat)
                return (struct afb_arg){
@@ -845,10 +846,11 @@ static int _iterargs_(struct json_object *obj, enum MHD_ValueKind kind, const ch
        return 1;
 }
 
-static struct json_object *req_json(struct afb_hreq *hreq)
+static struct json_object *req_json(struct afb_xreq *xreq)
 {
        struct hreq_data *hdat;
        struct json_object *obj, *val;
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
 
        obj = hreq->json;
        if (obj == NULL) {
@@ -896,13 +898,15 @@ static void req_reply(struct afb_hreq *hreq, unsigned retcode, const char *statu
        afb_hreq_reply(hreq, retcode, response, NULL);
 }
 
-static void req_fail(struct afb_hreq *hreq, const char *status, const char *info)
+static void req_fail(struct afb_xreq *xreq, const char *status, const char *info)
 {
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
        req_reply(hreq, MHD_HTTP_OK, status, info, NULL);
 }
 
-static void req_success(struct afb_hreq *hreq, json_object *obj, const char *info)
+static void req_success(struct afb_xreq *xreq, json_object *obj, const char *info)
 {
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
        req_reply(hreq, MHD_HTTP_OK, "success", info, obj);
 }
 
@@ -973,9 +977,7 @@ struct afb_hreq *afb_hreq_create()
        struct afb_hreq *hreq = calloc(1, sizeof *hreq);
        if (hreq) {
                /* init the request */
-               hreq->xreq.refcount = 1;
-               hreq->xreq.query = hreq;
-               hreq->xreq.queryitf = &afb_hreq_xreq_query_itf;
+               afb_xreq_init(&hreq->xreq, &afb_hreq_xreq_query_itf);
                hreq->reqid = ++global_reqids;
        }
        return hreq;
index 7026f20..498f73b 100644 (file)
 
 struct subcall;
 
-static void subcall_destroy(void *closure);
-static void subcall_reply(void *closure, int iserror, struct json_object *obj);
-static int subcall_subscribe(void *closure, struct afb_event event);
-static int subcall_unsubscribe(void *closure, struct afb_event event);
+static void subcall_destroy(struct afb_xreq *xreq);
+static void subcall_reply(struct afb_xreq *xreq, int iserror, struct json_object *obj);
+static int subcall_subscribe(struct afb_xreq *xreq, struct afb_event event);
+static int subcall_unsubscribe(struct afb_xreq *xreq, struct afb_event event);
 
 const struct afb_xreq_query_itf afb_subcall_xreq_itf = {
        .reply = subcall_reply,
@@ -53,33 +53,33 @@ struct subcall
        void *closure;
 };
 
-static void subcall_destroy(void *closure)
+static void subcall_destroy(struct afb_xreq *xreq)
 {
-       struct subcall *subcall = closure;
+       struct subcall *subcall = CONTAINER_OF_XREQ(struct subcall, xreq);
 
        json_object_put(subcall->xreq.json);
        afb_xreq_unref(subcall->caller);
        free(subcall);
 }
 
-static void subcall_reply(void *closure, int iserror, struct json_object *obj)
+static void subcall_reply(struct afb_xreq *xreq, int iserror, struct json_object *obj)
 {
-       struct subcall *subcall = closure;
+       struct subcall *subcall = CONTAINER_OF_XREQ(struct subcall, xreq);
 
        subcall->callback(subcall->closure, iserror, obj);
        json_object_put(obj);
 }
 
-static int subcall_subscribe(void *closure, struct afb_event event)
+static int subcall_subscribe(struct afb_xreq *xreq, struct afb_event event)
 {
-       struct subcall *subcall = closure;
+       struct subcall *subcall = CONTAINER_OF_XREQ(struct subcall, xreq);
 
        return afb_xreq_subscribe(subcall->caller, event);
 }
 
-static int subcall_unsubscribe(void *closure, struct afb_event event)
+static int subcall_unsubscribe(struct afb_xreq *xreq, struct afb_event event)
 {
-       struct subcall *subcall = closure;
+       struct subcall *subcall = CONTAINER_OF_XREQ(struct subcall, xreq);
 
        return afb_xreq_unsubscribe(subcall->caller, event);
 }
@@ -93,13 +93,11 @@ static struct subcall *create_subcall(struct afb_xreq *caller, const char *api,
                return NULL;
        }
 
+       afb_xreq_init(&subcall->xreq, &afb_subcall_xreq_itf);
        afb_context_subinit(&subcall->xreq.context, &caller->context);
-       subcall->xreq.refcount = 1;
        subcall->xreq.json = args;
        subcall->xreq.api = api; /* TODO: alloc ? */
        subcall->xreq.verb = verb; /* TODO: alloc ? */
-       subcall->xreq.query = subcall;
-       subcall->xreq.queryitf = &afb_subcall_xreq_itf;
        subcall->caller = caller;
        subcall->callback = callback;
        subcall->closure = closure;
index 59e775c..d493280 100644 (file)
@@ -56,12 +56,8 @@ struct svc_req
        struct afb_xreq xreq;
 
        /* the args */
-       struct json_object *args;
        void (*callback)(void*, int, struct json_object*);
        void *closure;
-
-       /* the service */
-       struct afb_svc *svc;
 };
 
 /* functions for services */
@@ -81,14 +77,12 @@ static const struct afb_evt_itf evt_itf = {
 };
 
 /* functions for requests of services */
-static struct json_object *svcreq_json(void *closure);
-static void svcreq_destroy(void *closure);
-static void svcreq_reply(void *closure, int iserror, json_object *obj);
+static void svcreq_destroy(struct afb_xreq *xreq);
+static void svcreq_reply(struct afb_xreq *xreq, int iserror, json_object *obj);
 
 /* interface for requests of services */
 const struct afb_xreq_query_itf afb_svc_xreq_itf = {
        .unref = svcreq_destroy,
-       .json = svcreq_json,
        .reply = svcreq_reply
 };
 
@@ -233,41 +227,32 @@ static void svc_call(void *closure, const char *api, const char *verb, struct js
        }
 
        /* initialises the request */
+       afb_xreq_init(&svcreq->xreq, &afb_svc_xreq_itf);
        afb_context_init(&svcreq->xreq.context, svc->session, NULL);
        svcreq->xreq.context.validated = 1;
-       svcreq->xreq.refcount = 1;
-       svcreq->xreq.query = svcreq;
-       svcreq->xreq.queryitf = &afb_svc_xreq_itf;
        svcreq->xreq.api = api;
        svcreq->xreq.verb = verb;
        svcreq->xreq.listener = svc->listener;
-       svcreq->args = args;
+       svcreq->xreq.json = args;
        svcreq->callback = callback;
        svcreq->closure = cbclosure;
-       svcreq->svc = svc;
 
        /* terminates and frees ressources if needed */
        afb_apis_call(&svcreq->xreq);
        afb_xreq_unref(&svcreq->xreq);
 }
 
-static void svcreq_destroy(void *closure)
+static void svcreq_destroy(struct afb_xreq *xreq)
 {
-       struct svc_req *svcreq = closure;
+       struct svc_req *svcreq = CONTAINER_OF_XREQ(struct svc_req, xreq);
        afb_context_disconnect(&svcreq->xreq.context);
-       json_object_put(svcreq->args);
+       json_object_put(svcreq->xreq.json);
        free(svcreq);
 }
 
-static struct json_object *svcreq_json(void *closure)
-{
-       struct svc_req *svcreq = closure;
-       return svcreq->args;
-}
-
-static void svcreq_reply(void *closure, int iserror, json_object *obj)
+static void svcreq_reply(struct afb_xreq *xreq, int iserror, json_object *obj)
 {
-       struct svc_req *svcreq = closure;
+       struct svc_req *svcreq = CONTAINER_OF_XREQ(struct svc_req, xreq);
        svcreq->callback(svcreq->closure, iserror, obj);
        json_object_put(obj);
 }
index fec4117..60a0a80 100644 (file)
@@ -50,9 +50,8 @@ static void aws_on_call(struct afb_ws_json1 *ws, const char *api, const char *ve
 static void aws_on_event(struct afb_ws_json1 *ws, const char *event, int eventid, struct json_object *object);
 
 /* predeclaration of wsreq callbacks */
-static void wsreq_destroy(struct afb_wsreq *wsreq);
-static struct json_object *wsreq_json(struct afb_wsreq *wsreq);
-static void wsreq_reply(struct afb_wsreq *wsreq, int iserror, json_object *obj);
+static void wsreq_destroy(struct afb_xreq *xreq);
+static void wsreq_reply(struct afb_xreq *xreq, int iserror, json_object *obj);
 
 /* declaration of websocket structure */
 struct afb_ws_json1
@@ -84,9 +83,8 @@ static struct afb_wsj1_itf wsj1_itf = {
 
 /* interface for xreq */
 const struct afb_xreq_query_itf afb_ws_json1_xreq_itf = {
-       .json = (void*)wsreq_json,
-       .reply = (void*)wsreq_reply,
-       .unref = (void*)wsreq_destroy
+       .reply = wsreq_reply,
+       .unref = wsreq_destroy
 };
 
 /* the interface for events */
@@ -182,6 +180,7 @@ static void aws_on_call(struct afb_ws_json1 *ws, const char *api, const char *ve
        }
 
        /* init the context */
+       afb_xreq_init(&wsreq->xreq, &afb_ws_json1_xreq_itf);
        afb_context_init(&wsreq->xreq.context, ws->session, afb_wsj1_msg_token(msg));
        if (!wsreq->xreq.context.invalidated)
                wsreq->xreq.context.validated = 1;
@@ -193,11 +192,9 @@ static void aws_on_call(struct afb_ws_json1 *ws, const char *api, const char *ve
        /* fill and record the request */
        afb_wsj1_msg_addref(msg);
        wsreq->msgj1 = msg;
-       wsreq->xreq.refcount = 1;
-       wsreq->xreq.query = wsreq;
-       wsreq->xreq.queryitf = &afb_ws_json1_xreq_itf;
        wsreq->xreq.api = api;
        wsreq->xreq.verb = verb;
+       wsreq->xreq.json = afb_wsj1_msg_object_j(wsreq->msgj1);
        wsreq->aws = aws_addref(ws);
        wsreq->xreq.listener = wsreq->aws->listener;
 
@@ -219,21 +216,19 @@ static void aws_on_event(struct afb_ws_json1 *aws, const char *event, int eventi
 ****************************************************************
 ***************************************************************/
 
-static void wsreq_destroy(struct afb_wsreq *wsreq)
+static void wsreq_destroy(struct afb_xreq *xreq)
 {
+       struct afb_wsreq *wsreq = CONTAINER_OF_XREQ(struct afb_wsreq, xreq);
+
        afb_context_disconnect(&wsreq->xreq.context);
        afb_wsj1_msg_unref(wsreq->msgj1);
        aws_unref(wsreq->aws);
        free(wsreq);
 }
 
-static struct json_object *wsreq_json(struct afb_wsreq *wsreq)
-{
-       return afb_wsj1_msg_object_j(wsreq->msgj1);
-}
-
-static void wsreq_reply(struct afb_wsreq *wsreq, int iserror, json_object *obj)
+static void wsreq_reply(struct afb_xreq *xreq, int iserror, json_object *obj)
 {
+       struct afb_wsreq *wsreq = CONTAINER_OF_XREQ(struct afb_wsreq, xreq);
        int rc;
 
        rc = (iserror ? afb_wsj1_reply_error_j : afb_wsj1_reply_ok_j)(
index cf98222..4282f62 100644 (file)
 static struct json_object *xreq_json_cb(void *closure)
 {
        struct afb_xreq *xreq = closure;
-       return xreq->json ? : (xreq->json = xreq->queryitf->json(xreq->query));
+       return xreq->json ? : (xreq->json = xreq->queryitf->json(xreq));
 }
 
 static struct afb_arg xreq_get_cb(void *closure, const char *name)
 {
        struct afb_xreq *xreq = closure;
        if (xreq->queryitf->get)
-               return xreq->queryitf->get(xreq->query, name);
+               return xreq->queryitf->get(xreq, name);
        else
                return afb_msg_json_get_arg(xreq_json_cb(closure), name);
 }
@@ -59,9 +59,9 @@ static void xreq_success_cb(void *closure, struct json_object *obj, const char *
        } else {
                xreq->replied = 1;
                if (xreq->queryitf->success)
-                       xreq->queryitf->success(xreq->query, obj, info);
+                       xreq->queryitf->success(xreq, obj, info);
                else
-                       xreq->queryitf->reply(xreq->query, 0, afb_msg_json_reply_ok(info, obj, &xreq->context, NULL));
+                       xreq->queryitf->reply(xreq, 0, afb_msg_json_reply_ok(info, obj, &xreq->context, NULL));
        }
 }
 
@@ -74,9 +74,9 @@ static void xreq_fail_cb(void *closure, const char *status, const char *info)
        } else {
                xreq->replied = 1;
                if (xreq->queryitf->fail)
-                       xreq->queryitf->fail(xreq->query, status, info);
+                       xreq->queryitf->fail(xreq, status, info);
                else
-                       xreq->queryitf->reply(xreq->query, 1, afb_msg_json_reply_error(status, info, &xreq->context, NULL));
+                       xreq->queryitf->reply(xreq, 1, afb_msg_json_reply_error(status, info, &xreq->context, NULL));
        }
 }
 
@@ -120,7 +120,7 @@ static void xreq_unref_cb(void *closure)
 {
        struct afb_xreq *xreq = closure;
        if (!__atomic_sub_fetch(&xreq->refcount, 1, __ATOMIC_RELAXED)) {
-               xreq->queryitf->unref(xreq->query);
+               xreq->queryitf->unref(xreq);
        }
 }
 
@@ -147,7 +147,7 @@ int afb_xreq_subscribe(struct afb_xreq *xreq, struct afb_event event)
        if (xreq->listener)
                return afb_evt_add_watch(xreq->listener, event);
        if (xreq->queryitf->subscribe)
-               return xreq->queryitf->subscribe(xreq->query, event);
+               return xreq->queryitf->subscribe(xreq, event);
        ERROR("no event listener, subscription impossible");
        errno = EINVAL;
        return -1;
@@ -164,7 +164,7 @@ int afb_xreq_unsubscribe(struct afb_xreq *xreq, struct afb_event event)
        if (xreq->listener)
                return afb_evt_remove_watch(xreq->listener, event);
        if (xreq->queryitf->unsubscribe)
-               return xreq->queryitf->unsubscribe(xreq->query, event);
+               return xreq->queryitf->unsubscribe(xreq, event);
        ERROR("no event listener, unsubscription impossible");
        errno = EINVAL;
        return -1;
@@ -175,7 +175,7 @@ static void xreq_subcall_cb(void *closure, const char *api, const char *verb, st
        struct afb_xreq *xreq = closure;
 
        if (xreq->queryitf->subcall)
-               xreq->queryitf->subcall(xreq->query, api, verb, args, callback, cb_closure);
+               xreq->queryitf->subcall(xreq, api, verb, args, callback, cb_closure);
        else
                afb_subcall(xreq, api, verb, args, callback, cb_closure);
 }
@@ -256,7 +256,7 @@ static void xreq_hooked_unref_cb(void *closure)
        afb_hook_xreq_unref(xreq);
        if (!__atomic_sub_fetch(&xreq->refcount, 1, __ATOMIC_RELAXED)) {
                afb_hook_xreq_end(xreq);
-               xreq->queryitf->unref(xreq->query);
+               xreq->queryitf->unref(xreq);
        }
 }
 
@@ -489,4 +489,9 @@ void afb_xreq_begin(struct afb_xreq *xreq)
                afb_hook_xreq_begin(xreq);
 }
 
+void afb_xreq_init(struct afb_xreq *xreq, const struct afb_xreq_query_itf *queryitf)
+{
+       xreq->refcount = 1;
+       xreq->queryitf = queryitf;
+}
 
index ba99d4a..4cd5820 100644 (file)
 
 struct json_object;
 struct afb_evt_listener;
+struct afb_xreq;
 
 struct afb_xreq_query_itf {
-       struct json_object *(*json)(void *closure);
-       struct afb_arg (*get)(void *closure, const char *name);
-       void (*success)(void *closure, struct json_object *obj, const char *info);
-       void (*fail)(void *closure, const char *status, const char *info);
-       void (*reply)(void *closure, int iserror, struct json_object *obj);
-       void (*unref)(void *closure);
-       int (*subscribe)(void *closure, struct afb_event event);
-       int (*unsubscribe)(void *closure, struct afb_event event);
-       void (*subcall)(void *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cb_closure);
+       struct json_object *(*json)(struct afb_xreq *xreq);
+       struct afb_arg (*get)(struct afb_xreq *xreq, const char *name);
+       void (*success)(struct afb_xreq *xreq, struct json_object *obj, const char *info);
+       void (*fail)(struct afb_xreq *xreq, const char *status, const char *info);
+       void (*reply)(struct afb_xreq *xreq, int iserror, struct json_object *obj);
+       void (*unref)(struct afb_xreq *xreq);
+       int (*subscribe)(struct afb_xreq *xreq, struct afb_event event);
+       int (*unsubscribe)(struct afb_xreq *xreq, struct afb_event event);
+       void (*subcall)(struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cb_closure);
 };
 
-
 /**
  * Internal data for requests
  */
@@ -48,7 +48,6 @@ struct afb_xreq
        const char *api;        /**< the requested API */
        const char *verb;       /**< the requested VERB */
        struct json_object *json; /**< the json object (or NULL) */
-       void *query;    /**< closure for the query */
        const struct afb_xreq_query_itf *queryitf;
        int refcount;   /**< current ref count */
        int replied;    /**< is replied? */
@@ -57,6 +56,8 @@ struct afb_xreq
        struct afb_evt_listener *listener;
 };
 
+#define CONTAINER_OF_XREQ(type,x) ((type*)(((intptr_t)(x))-((intptr_t)&(((type*)NULL)->xreq))))
+
 extern void afb_xreq_addref(struct afb_xreq *xreq);
 extern void afb_xreq_unref(struct afb_xreq *xreq);
 extern void afb_xreq_success(struct afb_xreq *xreq, struct json_object *obj, const char *info);
@@ -69,6 +70,7 @@ extern int afb_xreq_unsubscribe(struct afb_xreq *xreq, struct afb_event event);
 extern void afb_xreq_subcall(struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cb_closure);
 extern void afb_xreq_unhooked_subcall(struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cb_closure);
 
+extern void afb_xreq_init(struct afb_xreq *xreq, const struct afb_xreq_query_itf *queryitf);
 extern void afb_xreq_begin(struct afb_xreq *xreq);
 extern void afb_xreq_call(struct afb_xreq *xreq, int sessionflags, void (*callback)(struct afb_req req));
 
index 32b12dd..4dc6cb8 100644 (file)
@@ -446,9 +446,9 @@ struct startup_req
        struct afb_session *session;
 };
 
-static void startup_call_reply(void *closure, int iserror, struct json_object *obj)
+static void startup_call_reply(struct afb_xreq *xreq, int iserror, struct json_object *obj)
 {
-       struct startup_req *sreq = closure;
+       struct startup_req *sreq = CONTAINER_OF_XREQ(struct startup_req, xreq);
 
        if (!iserror)
                NOTICE("startup call %s returned %s", sreq->current->value, json_object_get_string(obj));
@@ -460,9 +460,9 @@ static void startup_call_reply(void *closure, int iserror, struct json_object *o
 
 static void startup_call_current(struct startup_req *sreq);
 
-static void startup_call_unref(void *closure)
+static void startup_call_unref(struct afb_xreq *xreq)
 {
-       struct startup_req *sreq = closure;
+       struct startup_req *sreq = CONTAINER_OF_XREQ(struct startup_req, xreq);
 
        free(sreq->api);
        free(sreq->verb);
@@ -493,16 +493,14 @@ static void startup_call_current(struct startup_req *sreq)
                json = strchr(verb, ':');
                if (json) {
                        memset(&sreq->xreq, 0, sizeof sreq->xreq);
+                       afb_xreq_init(&sreq->xreq, &startup_xreq_itf);
                        afb_context_init(&sreq->xreq.context, sreq->session, NULL);
                        sreq->xreq.context.validated = 1;
                        sreq->api = strndup(api, verb - api);
-                       sreq->xreq.api = sreq->api;
                        sreq->verb = strndup(verb + 1, json - verb - 1);
+                       sreq->xreq.api = sreq->api;
                        sreq->xreq.verb = sreq->verb;
                        sreq->xreq.json = json_tokener_parse(json + 1);
-                       sreq->xreq.refcount = 1;
-                       sreq->xreq.query = sreq;
-                       sreq->xreq.queryitf = &startup_xreq_itf;
                        if (sreq->api && sreq->verb && sreq->xreq.json) {
                                afb_apis_call(&sreq->xreq);
                                afb_xreq_unref(&sreq->xreq);