Change-Id: Ie175ec1e508c7bd3bcdc25d7e0b26e7a9da3fafb
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
memo = malloc(sizeof *memo);
if (memo != NULL) {
memo = malloc(sizeof *memo);
if (memo != NULL) {
+ afb_xreq_unhooked_addref(xreq);
memo->xreq = xreq;
memo->msgid = 0;
memo->api = api;
memo->xreq = xreq;
memo->msgid = 0;
memo->api = api;
- afb_xreq_unref(memo->xreq);
+ afb_xreq_unhooked_unref(memo->xreq);
callreq->result = NULL;
callreq->status = 0;
callreq->async = 0;
callreq->result = NULL;
callreq->status = 0;
callreq->async = 0;
- afb_xreq_addref(&callreq->xreq);
+ afb_xreq_unhooked_addref(&callreq->xreq); /* avoid early callreq destruction */
rc = jobs_enter(NULL, 0, callreq_sync_enter, callreq);
if (rc >= 0)
rc = callreq->status;
resu = (rc >= 0 || callreq->result) ? callreq->result : afb_msg_json_internal_error();
rc = jobs_enter(NULL, 0, callreq_sync_enter, callreq);
if (rc >= 0)
rc = callreq->status;
resu = (rc >= 0 || callreq->result) ? callreq->result : afb_msg_json_internal_error();
- afb_xreq_unref(&callreq->xreq);
+ afb_xreq_unhooked_unref(&callreq->xreq);
}
if (result)
*result = resu;
}
if (result)
*result = resu;
void afb_hreq_addref(struct afb_hreq *hreq)
{
void afb_hreq_addref(struct afb_hreq *hreq)
{
- afb_xreq_addref(&hreq->xreq);
+ afb_xreq_unhooked_addref(&hreq->xreq);
}
void afb_hreq_unref(struct afb_hreq *hreq)
{
if (hreq->replied)
hreq->xreq.replied = 1;
}
void afb_hreq_unref(struct afb_hreq *hreq)
{
if (hreq->replied)
hreq->xreq.replied = 1;
- afb_xreq_unref(&hreq->xreq);
+ afb_xreq_unhooked_unref(&hreq->xreq);
} else if (afb_hreq_init_context(hreq) < 0) {
afb_hreq_reply_error(hreq, MHD_HTTP_INTERNAL_SERVER_ERROR);
} else {
} else if (afb_hreq_init_context(hreq) < 0) {
afb_hreq_reply_error(hreq, MHD_HTTP_INTERNAL_SERVER_ERROR);
} else {
- afb_xreq_addref(&hreq->xreq); /* TODO check if needed */
+ afb_xreq_unhooked_addref(&hreq->xreq);
afb_xreq_process(&hreq->xreq, apiset);
}
}
afb_xreq_process(&hreq->xreq, apiset);
}
}
struct afb_stub_ws *stubws = closure;
afb_proto_ws_client_call(stubws->proto, xreq->verb, afb_xreq_json(xreq), afb_session_uuid(xreq->context.session), xreq);
struct afb_stub_ws *stubws = closure;
afb_proto_ws_client_call(stubws->proto, xreq->verb, afb_xreq_json(xreq), afb_session_uuid(xreq->context.session), xreq);
+ afb_xreq_unhooked_addref(xreq);
}
static void client_on_description_cb(void *closure, struct json_object *data)
}
static void client_on_description_cb(void *closure, struct json_object *data)
struct afb_xreq *xreq = request;
afb_xreq_success(xreq, result, *info ? info : NULL);
struct afb_xreq *xreq = request;
afb_xreq_success(xreq, result, *info ? info : NULL);
+ afb_xreq_unhooked_unref(xreq);
}
static void on_reply_fail(void *closure, void *request, const char *status, const char *info)
}
static void on_reply_fail(void *closure, void *request, const char *status, const char *info)
struct afb_xreq *xreq = request;
afb_xreq_fail(xreq, status, *info ? info : NULL);
struct afb_xreq *xreq = request;
afb_xreq_fail(xreq, status, *info ? info : NULL);
+ afb_xreq_unhooked_unref(xreq);
}
static void on_event_create(void *closure, const char *event_name, int event_id)
}
static void on_event_create(void *closure, const char *event_name, int event_id)
/******************************************************************************/
/******************************************************************************/
-static inline void xreq_addref(struct afb_xreq *xreq)
+static void xreq_finalize(struct afb_xreq *xreq)
+{
+ if (!xreq->replied)
+ afb_xreq_fail(xreq, "error", "no reply");
+ if (xreq->hookflags)
+ afb_hook_xreq_end(xreq);
+ if (xreq->caller)
+ afb_xreq_unhooked_unref(xreq->caller);
+ xreq->queryitf->unref(xreq);
+}
+
+inline void afb_xreq_unhooked_addref(struct afb_xreq *xreq)
{
__atomic_add_fetch(&xreq->refcount, 1, __ATOMIC_RELAXED);
}
{
__atomic_add_fetch(&xreq->refcount, 1, __ATOMIC_RELAXED);
}
-static inline void xreq_unref(struct afb_xreq *xreq)
+inline void afb_xreq_unhooked_unref(struct afb_xreq *xreq)
- if (!__atomic_sub_fetch(&xreq->refcount, 1, __ATOMIC_RELAXED)) {
- if (!xreq->replied)
- afb_xreq_fail(xreq, "error", "no reply");
- if (xreq->hookflags)
- afb_hook_xreq_end(xreq);
- if (xreq->caller)
- xreq_unref(xreq->caller);
- xreq->queryitf->unref(xreq);
- }
+ if (!__atomic_sub_fetch(&xreq->refcount, 1, __ATOMIC_RELAXED))
+ xreq_finalize(xreq);
}
/******************************************************************************/
}
/******************************************************************************/
subcall->completion(subcall, status, result);
json_object_put(result);
subcall->completion(subcall, status, result);
json_object_put(result);
- afb_xreq_unref(&subcall->xreq);
+ afb_xreq_unhooked_unref(&subcall->xreq);
}
static void subcall_destroy_cb(struct afb_xreq *xreq)
}
static void subcall_destroy_cb(struct afb_xreq *xreq)
subcall->xreq.api = api;
subcall->xreq.verb = verb;
subcall->xreq.caller = caller;
subcall->xreq.api = api;
subcall->xreq.verb = verb;
subcall->xreq.caller = caller;
+ afb_xreq_unhooked_addref(caller);
subcall->xreq.caller, subcall->xreq.api, subcall->xreq.verb,
subcall->xreq.json, subcall_reply_direct_cb, &subcall->xreq);
} else {
subcall->xreq.caller, subcall->xreq.api, subcall->xreq.verb,
subcall->xreq.json, subcall_reply_direct_cb, &subcall->xreq);
} else {
- afb_xreq_addref(&subcall->xreq);
+ afb_xreq_unhooked_addref(&subcall->xreq);
afb_xreq_process(&subcall->xreq, subcall->xreq.caller->apiset);
}
}
afb_xreq_process(&subcall->xreq, subcall->xreq.caller->apiset);
}
}
- afb_xreq_addref(&subcall->xreq);
+ afb_xreq_unhooked_addref(&subcall->xreq);
rc = jobs_enter(NULL, 0, subcall_sync_enter, subcall);
*result = subcall->result;
if (rc < 0 || subcall->status < 0) {
*result = *result ?: afb_msg_json_internal_error();
rc = -1;
}
rc = jobs_enter(NULL, 0, subcall_sync_enter, subcall);
*result = subcall->result;
if (rc < 0 || subcall->status < 0) {
*result = *result ?: afb_msg_json_internal_error();
rc = -1;
}
- afb_xreq_unref(&subcall->xreq);
+ afb_xreq_unhooked_unref(&subcall->xreq);
static void xreq_addref_cb(void *closure)
{
struct afb_xreq *xreq = closure;
static void xreq_addref_cb(void *closure)
{
struct afb_xreq *xreq = closure;
+ afb_xreq_unhooked_addref(xreq);
}
static void xreq_unref_cb(void *closure)
{
struct afb_xreq *xreq = closure;
}
static void xreq_unref_cb(void *closure)
{
struct afb_xreq *xreq = closure;
+ afb_xreq_unhooked_unref(xreq);
}
static void xreq_session_close_cb(void *closure)
}
static void xreq_session_close_cb(void *closure)
api->itf->call(api->closure, xreq);
}
/* release the request */
api->itf->call(api->closure, xreq);
}
/* release the request */
+ afb_xreq_unhooked_unref(xreq);
}
/* queue the request job */
}
/* queue the request job */
+ afb_xreq_unhooked_addref(xreq);
if (jobs_queue(api, 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");
early_failure(xreq, "cancelled", "not able to create a job for the task");
if (jobs_queue(api, 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");
early_failure(xreq, "cancelled", "not able to create a job for the task");
+ afb_xreq_unhooked_unref(xreq);
+ afb_xreq_unhooked_unref(xreq);
extern struct afb_req afb_xreq_unstore(struct afb_stored_req *sreq);
extern void afb_xreq_addref(struct afb_xreq *xreq);
extern void afb_xreq_unref(struct afb_xreq *xreq);
extern struct afb_req afb_xreq_unstore(struct afb_stored_req *sreq);
extern void afb_xreq_addref(struct afb_xreq *xreq);
extern void afb_xreq_unref(struct afb_xreq *xreq);
+extern void afb_xreq_unhooked_addref(struct afb_xreq *xreq);
+extern void afb_xreq_unhooked_unref(struct afb_xreq *xreq);
extern struct json_object *afb_xreq_json(struct afb_xreq *xreq);
extern struct json_object *afb_xreq_json(struct afb_xreq *xreq);