aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/afb-hook.c23
-rw-r--r--src/afb-hook.h45
-rw-r--r--src/afb-subcall.c2
-rw-r--r--src/afb-xreq.c121
-rw-r--r--src/afb-xreq.h1
5 files changed, 131 insertions, 61 deletions
diff --git a/src/afb-hook.c b/src/afb-hook.c
index e16d6704..bafbbe90 100644
--- a/src/afb-hook.c
+++ b/src/afb-hook.c
@@ -174,6 +174,16 @@ static void hook_xreq_subcall_result_default_cb(void * closure, const struct afb
_hook_xreq_(xreq, " ...subcall... -> %d: %s", status, json_object_to_json_string(result));
}
+static void hook_xreq_subcallsync_default_cb(void * closure, const struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args)
+{
+ _hook_xreq_(xreq, "subcallsync(%s/%s, %s) ...", api, verb, json_object_to_json_string(args));
+}
+
+static void hook_xreq_subcallsync_result_default_cb(void * closure, const struct afb_xreq *xreq, int status, struct json_object *result)
+{
+ _hook_xreq_(xreq, " ...subcallsync... -> %d: %s", status, json_object_to_json_string(result));
+}
+
static struct afb_hook_xreq_itf hook_xreq_default_itf = {
.hook_xreq_begin = hook_xreq_begin_default_cb,
.hook_xreq_end = hook_xreq_end_default_cb,
@@ -193,6 +203,8 @@ static struct afb_hook_xreq_itf hook_xreq_default_itf = {
.hook_xreq_unsubscribe = hook_xreq_unsubscribe_default_cb,
.hook_xreq_subcall = hook_xreq_subcall_default_cb,
.hook_xreq_subcall_result = hook_xreq_subcall_result_default_cb,
+ .hook_xreq_subcallsync = hook_xreq_subcallsync_default_cb,
+ .hook_xreq_subcallsync_result = hook_xreq_subcallsync_result_default_cb,
};
/******************************************************************************
@@ -313,6 +325,17 @@ void afb_hook_xreq_subcall_result(const struct afb_xreq *xreq, int status, struc
_HOOK_XREQ_(subcall_result, xreq, status, result);
}
+void afb_hook_xreq_subcallsync(const struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args)
+{
+ _HOOK_XREQ_(subcallsync, xreq, api, verb, args);
+}
+
+int afb_hook_xreq_subcallsync_result(const struct afb_xreq *xreq, int status, struct json_object *result)
+{
+ _HOOK_XREQ_(subcallsync_result, xreq, status, result);
+ return status;
+}
+
/******************************************************************************
* section:
*****************************************************************************/
diff --git a/src/afb-hook.h b/src/afb-hook.h
index c9624bbf..53804d40 100644
--- a/src/afb-hook.h
+++ b/src/afb-hook.h
@@ -18,24 +18,26 @@
#pragma once
/* individual flags */
-#define afb_hook_flag_req_json 1
-#define afb_hook_flag_req_get 2
-#define afb_hook_flag_req_success 4
-#define afb_hook_flag_req_fail 8
-#define afb_hook_flag_req_raw 16
-#define afb_hook_flag_req_send 32
-#define afb_hook_flag_req_context_get 64
-#define afb_hook_flag_req_context_set 128
-#define afb_hook_flag_req_addref 256
-#define afb_hook_flag_req_unref 512
-#define afb_hook_flag_req_session_close 1024
-#define afb_hook_flag_req_session_set_LOA 2048
-#define afb_hook_flag_req_subscribe 4096
-#define afb_hook_flag_req_unsubscribe 8192
-#define afb_hook_flag_req_subcall 16384
-#define afb_hook_flag_req_subcall_result 32768
-#define afb_hook_flag_req_begin 65536
-#define afb_hook_flag_req_end 131072
+#define afb_hook_flag_req_begin 0x000001
+#define afb_hook_flag_req_end 0x000002
+#define afb_hook_flag_req_json 0x000004
+#define afb_hook_flag_req_get 0x000008
+#define afb_hook_flag_req_success 0x000010
+#define afb_hook_flag_req_fail 0x000020
+#define afb_hook_flag_req_raw 0x000040
+#define afb_hook_flag_req_send 0x000080
+#define afb_hook_flag_req_context_get 0x000100
+#define afb_hook_flag_req_context_set 0x000200
+#define afb_hook_flag_req_addref 0x000400
+#define afb_hook_flag_req_unref 0x000800
+#define afb_hook_flag_req_session_close 0x001000
+#define afb_hook_flag_req_session_set_LOA 0x002000
+#define afb_hook_flag_req_subscribe 0x004000
+#define afb_hook_flag_req_unsubscribe 0x010800
+#define afb_hook_flag_req_subcall 0x020000
+#define afb_hook_flag_req_subcall_result 0x040000
+#define afb_hook_flag_req_subcallsync 0x080000
+#define afb_hook_flag_req_subcallsync_result 0x100000
/* common flags */
#define afb_hook_flags_req_life (afb_hook_flag_req_begin|afb_hook_flag_req_end)
@@ -43,7 +45,8 @@
#define afb_hook_flags_req_result (afb_hook_flag_req_success|afb_hook_flag_req_fail)
#define afb_hook_flags_req_session (afb_hook_flag_req_session_close|afb_hook_flag_req_session_set_LOA)
#define afb_hook_flags_req_event (afb_hook_flag_req_subscribe|afb_hook_flag_req_unsubscribe)
-#define afb_hook_flags_req_subcall (afb_hook_flag_req_subcall|afb_hook_flag_req_subcall_result)
+#define afb_hook_flags_req_subcall (afb_hook_flag_req_subcall|afb_hook_flag_req_subcall_result\
+ |afb_hook_flag_req_subcallsync|afb_hook_flag_req_subcallsync_result)
/* extra flags */
#define afb_hook_flags_req_ref (afb_hook_flag_req_addref|afb_hook_flag_req_unref)
@@ -87,6 +90,8 @@ struct afb_hook_xreq_itf {
void (*hook_xreq_unsubscribe)(void * closure, const struct afb_xreq *xreq, struct afb_event event, int result);
void (*hook_xreq_subcall)(void * closure, const struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args);
void (*hook_xreq_subcall_result)(void * closure, const struct afb_xreq *xreq, int status, struct json_object *result);
+ void (*hook_xreq_subcallsync)(void * closure, const struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args);
+ void (*hook_xreq_subcallsync_result)(void * closure, const struct afb_xreq *xreq, int status, struct json_object *result);
};
extern void afb_hook_init_xreq(struct afb_xreq *xreq);
@@ -114,4 +119,6 @@ extern int afb_hook_xreq_subscribe(const struct afb_xreq *xreq, struct afb_event
extern int afb_hook_xreq_unsubscribe(const struct afb_xreq *xreq, struct afb_event event, int result);
extern void afb_hook_xreq_subcall(const struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args);
extern void afb_hook_xreq_subcall_result(const struct afb_xreq *xreq, int status, struct json_object *result);
+extern void afb_hook_xreq_subcallsync(const struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args);
+extern int afb_hook_xreq_subcallsync_result(const struct afb_xreq *xreq, int status, struct json_object *result);
diff --git a/src/afb-subcall.c b/src/afb-subcall.c
index b586e28a..7026f20e 100644
--- a/src/afb-subcall.c
+++ b/src/afb-subcall.c
@@ -164,7 +164,7 @@ static void subcall_sync_enter(int signum, void *closure, struct jobloop *jobloo
if (!signum) {
sync->jobloop = jobloop;
- afb_xreq_subcall(sync->caller, sync->api, sync->verb, sync->args, subcall_sync_reply, sync);
+ afb_xreq_unhooked_subcall(sync->caller, sync->api, sync->verb, sync->args, subcall_sync_reply, sync);
} else {
sync->result = json_object_get(afb_msg_json_internal_error());
sync->iserror = 1;
diff --git a/src/afb-xreq.c b/src/afb-xreq.c
index 95d089ab..cf982220 100644
--- a/src/afb-xreq.c
+++ b/src/afb-xreq.c
@@ -52,11 +52,7 @@ static struct afb_arg xreq_get_cb(void *closure, const char *name)
static void xreq_success_cb(void *closure, struct json_object *obj, const char *info)
{
struct afb_xreq *xreq = closure;
- afb_xreq_success(xreq, obj, info);
-}
-void afb_xreq_success(struct afb_xreq *xreq, struct json_object *obj, const char *info)
-{
if (xreq->replied) {
ERROR("reply called more than one time!!");
json_object_put(obj);
@@ -72,11 +68,7 @@ void afb_xreq_success(struct afb_xreq *xreq, struct json_object *obj, const char
static void xreq_fail_cb(void *closure, const char *status, const char *info)
{
struct afb_xreq *xreq = closure;
- afb_xreq_fail(xreq, status, info);
-}
-void afb_xreq_fail(struct afb_xreq *xreq, const char *status, const char *info)
-{
if (xreq->replied) {
ERROR("reply called more than one time!!");
} else {
@@ -91,11 +83,6 @@ void afb_xreq_fail(struct afb_xreq *xreq, const char *status, const char *info)
static const char *xreq_raw_cb(void *closure, size_t *size)
{
struct afb_xreq *xreq = closure;
- return afb_xreq_raw(xreq, size);
-}
-
-const char *afb_xreq_raw(struct afb_xreq *xreq, size_t *size)
-{
const char *result = json_object_to_json_string(xreq_json_cb(xreq));
if (size != NULL)
*size = strlen(result);
@@ -126,23 +113,13 @@ static void xreq_context_set_cb(void *closure, void *value, void (*free_value)(v
static void xreq_addref_cb(void *closure)
{
struct afb_xreq *xreq = closure;
- afb_xreq_addref(xreq);
-}
-
-void afb_xreq_addref(struct afb_xreq *xreq)
-{
- xreq->refcount++;
+ __atomic_add_fetch(&xreq->refcount, 1, __ATOMIC_RELAXED);
}
static void xreq_unref_cb(void *closure)
{
struct afb_xreq *xreq = closure;
- afb_xreq_unref(xreq);
-}
-
-void afb_xreq_unref(struct afb_xreq *xreq)
-{
- if (!--xreq->refcount) {
+ if (!__atomic_sub_fetch(&xreq->refcount, 1, __ATOMIC_RELAXED)) {
xreq->queryitf->unref(xreq->query);
}
}
@@ -197,11 +174,6 @@ static void xreq_subcall_cb(void *closure, const char *api, const char *verb, st
{
struct afb_xreq *xreq = closure;
- afb_xreq_subcall(xreq, api, verb, args, callback, cb_closure);
-}
-
-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)
-{
if (xreq->queryitf->subcall)
xreq->queryitf->subcall(xreq->query, api, verb, args, callback, cb_closure);
else
@@ -277,12 +249,17 @@ static void xreq_hooked_addref_cb(void *closure)
afb_hook_xreq_addref(xreq);
xreq_addref_cb(closure);
}
-/*
+
static void xreq_hooked_unref_cb(void *closure)
{
- TODO
+ struct afb_xreq *xreq = 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);
+ }
}
-*/
+
static void xreq_hooked_session_close_cb(void *closure)
{
struct afb_xreq *xreq = closure;
@@ -311,20 +288,47 @@ static int xreq_hooked_unsubscribe_cb(void *closure, struct afb_event event)
return afb_hook_xreq_unsubscribe(xreq, event, r);
}
-/*
+struct reply
+{
+ struct afb_xreq *xreq;
+ void (*callback)(void*, int, struct json_object*);
+ void *closure;
+};
+
+static void xreq_hooked_subcall_reply_cb(void *closure, int iserror, struct json_object *result)
+{
+ struct reply *reply = closure;
+
+ afb_hook_xreq_subcall_result(reply->xreq, iserror, result);
+ reply->callback(reply->closure, iserror, result);
+ free(reply);
+}
+
static void xreq_hooked_subcall_cb(void *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cb_closure)
{
+ struct reply *reply = malloc(sizeof *reply);
struct afb_xreq *xreq = closure;
-
- afb_xreq_subcall(xreq, api, verb, args, callback, cb_closure);
+ afb_hook_xreq_subcall(xreq, api, verb, args);
+ if (reply) {
+ reply->xreq = xreq;
+ reply->callback = callback;
+ reply->closure = cb_closure;
+ xreq_subcall_cb(closure, api, verb, args, xreq_hooked_subcall_reply_cb, reply);
+ } else {
+ ERROR("out of memory");
+ xreq_subcall_cb(closure, api, verb, args, callback, cb_closure);
+ }
}
static int xreq_hooked_subcallsync_cb(void *closure, const char *api, const char *verb, struct json_object *args, struct json_object **result)
{
+ int r;
struct afb_xreq *xreq = closure;
- return afb_subcall_sync(xreq, api, verb, args, result);
+ afb_hook_xreq_subcallsync(xreq, api, verb, args);
+ r = xreq_subcallsync_cb(closure, api, verb, args, result);
+ return afb_hook_xreq_subcallsync_result(xreq, r, *result);
}
-*/
+
const struct afb_req_itf xreq_itf = {
.json = xreq_json_cb,
.get = xreq_get_cb,
@@ -354,13 +358,13 @@ const struct afb_req_itf xreq_hooked_itf = {
.context_get = xreq_hooked_context_get_cb,
.context_set = xreq_hooked_context_set_cb,
.addref = xreq_hooked_addref_cb,
-.unref = xreq_unref_cb,
+ .unref = xreq_hooked_unref_cb,
.session_close = xreq_hooked_session_close_cb,
.session_set_LOA = xreq_hooked_session_set_LOA_cb,
.subscribe = xreq_hooked_subscribe_cb,
.unsubscribe = xreq_hooked_unsubscribe_cb,
-.subcall = xreq_subcall_cb,
-.subcallsync = xreq_subcallsync_cb
+ .subcall = xreq_hooked_subcall_cb,
+ .subcallsync = xreq_hooked_subcallsync_cb
};
static inline struct afb_req to_req(struct afb_xreq *xreq)
@@ -368,6 +372,11 @@ static inline struct afb_req to_req(struct afb_xreq *xreq)
return (struct afb_req){ .itf = xreq->hookflags ? &xreq_hooked_itf : &xreq_itf, .closure = xreq };
}
+void afb_xreq_success(struct afb_xreq *xreq, struct json_object *obj, const char *info)
+{
+ afb_req_success(to_req(xreq), obj, info);
+}
+
void afb_xreq_success_f(struct afb_xreq *xreq, struct json_object *obj, const char *info, ...)
{
char *message;
@@ -380,6 +389,11 @@ void afb_xreq_success_f(struct afb_xreq *xreq, struct json_object *obj, const ch
free(message);
}
+void afb_xreq_fail(struct afb_xreq *xreq, const char *status, const char *info)
+{
+ afb_req_fail(to_req(xreq), status, info);
+}
+
void afb_xreq_fail_f(struct afb_xreq *xreq, const char *status, const char *info, ...)
{
char *message;
@@ -392,6 +406,31 @@ void afb_xreq_fail_f(struct afb_xreq *xreq, const char *status, const char *info
free(message);
}
+const char *afb_xreq_raw(struct afb_xreq *xreq, size_t *size)
+{
+ return afb_req_raw(to_req(xreq), size);
+}
+
+void afb_xreq_addref(struct afb_xreq *xreq)
+{
+ afb_req_addref(to_req(xreq));
+}
+
+void afb_xreq_unref(struct afb_xreq *xreq)
+{
+ afb_req_unref(to_req(xreq));
+}
+
+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)
+{
+ xreq_subcall_cb(xreq, api, verb, args, callback, cb_closure);
+}
+
+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)
+{
+ afb_req_subcall(to_req(xreq), api, verb, args, callback, cb_closure);
+}
+
static int xcheck(struct afb_xreq *xreq, int sessionflags)
{
if ((sessionflags & (AFB_SESSION_CREATE|AFB_SESSION_CLOSE|AFB_SESSION_RENEW|AFB_SESSION_CHECK|AFB_SESSION_LOA_EQ)) != 0) {
diff --git a/src/afb-xreq.h b/src/afb-xreq.h
index 3376bb22..ba99d4af 100644
--- a/src/afb-xreq.h
+++ b/src/afb-xreq.h
@@ -67,6 +67,7 @@ extern const char *afb_xreq_raw(struct afb_xreq *xreq, size_t *size);
extern int afb_xreq_subscribe(struct afb_xreq *xreq, struct afb_event event);
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_begin(struct afb_xreq *xreq);
extern void afb_xreq_call(struct afb_xreq *xreq, int sessionflags, void (*callback)(struct afb_req req));