summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-04-12 17:00:33 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2017-04-12 17:00:33 +0200
commit03f863dd080d32f71c4a0755c02e23c72e4cb342 (patch)
tree27dd6f931b42311964d9179b10a2781a6a7edcce
parenta05138e6bf1257b0e7b1ad90c974fb9e12f1d040 (diff)
Optimisation of xreq
Reduce the count of memory read Change-Id: Ie4dfa4bd30d6485be91961196294c43ffbd3b2a9 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--src/afb-api-dbus.c28
-rw-r--r--src/afb-api-ws.c34
-rw-r--r--src/afb-hreq.c40
-rw-r--r--src/afb-subcall.c28
-rw-r--r--src/afb-svc.c33
-rw-r--r--src/afb-ws-json1.c27
-rw-r--r--src/afb-xreq.c27
-rw-r--r--src/afb-xreq.h24
-rw-r--r--src/main.c14
9 files changed, 118 insertions, 137 deletions
diff --git a/src/afb-api-dbus.c b/src/afb-api-dbus.c
index 593232b9..b8ec3d02 100644
--- a/src/afb-api-dbus.c
+++ b/src/afb-api-dbus.c
@@ -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);
diff --git a/src/afb-api-ws.c b/src/afb-api-ws.c
index 8be74c03..472a44d4 100644
--- a/src/afb-api-ws.c
+++ b/src/afb-api-ws.c
@@ -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)
diff --git a/src/afb-hreq.c b/src/afb-hreq.c
index 69403f65..6589f0f4 100644
--- a/src/afb-hreq.c
+++ b/src/afb-hreq.c
@@ -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;
diff --git a/src/afb-subcall.c b/src/afb-subcall.c
index 7026f20e..498f73b5 100644
--- a/src/afb-subcall.c
+++ b/src/afb-subcall.c
@@ -33,10 +33,10 @@
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;
diff --git a/src/afb-svc.c b/src/afb-svc.c
index 59e775cd..d4932802 100644
--- a/src/afb-svc.c
+++ b/src/afb-svc.c
@@ -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);
}
diff --git a/src/afb-ws-json1.c b/src/afb-ws-json1.c
index fec41173..60a0a801 100644
--- a/src/afb-ws-json1.c
+++ b/src/afb-ws-json1.c
@@ -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)(
diff --git a/src/afb-xreq.c b/src/afb-xreq.c
index cf982220..4282f624 100644
--- a/src/afb-xreq.c
+++ b/src/afb-xreq.c
@@ -37,14 +37,14 @@
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;
+}
diff --git a/src/afb-xreq.h b/src/afb-xreq.h
index ba99d4af..4cd58209 100644
--- a/src/afb-xreq.h
+++ b/src/afb-xreq.h
@@ -25,20 +25,20 @@
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));
diff --git a/src/main.c b/src/main.c
index 32b12dd3..4dc6cb81 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);