+static void subcall_sync_leave(struct subcall *subcall)
+{
+ struct jobloop *jobloop = subcall->jobloop;
+ subcall->jobloop = NULL;
+ if (jobloop)
+ jobs_leave(jobloop);
+}
+
+static void subcall_sync_cb(int signum, void *closure, struct jobloop *jobloop)
+{
+ struct subcall *subcall = closure;
+
+ if (!signum) {
+ subcall->jobloop = jobloop;
+ afb_apis_call_direct(&subcall->xreq);
+ } else {
+ afb_xreq_fail_f(&subcall->xreq, "aborted", "signal %s(%d) caught", strsignal(signum), signum);
+ }
+ subcall_sync_leave(subcall);
+}
+
+int afb_subcall_sync(
+ struct afb_xreq *caller,
+ const char *api,
+ const char *verb,
+ struct json_object *args,
+ struct json_object **result
+)
+{
+ int rc;
+ struct subcall *subcall;
+
+ subcall = create_subcall(caller, api, verb, args, NULL, NULL);
+ if (subcall == NULL) {
+ *result = json_object_get(afb_msg_json_internal_error());
+ return 0;
+ }
+
+ rc = jobs_enter(NULL, 0, subcall_sync_cb, subcall);
+ if (rc < 0) {
+ subcall->result = json_object_get(afb_msg_json_internal_error());
+ subcall->iserror = 1;
+ }
+ rc = !subcall->iserror;
+ *result = subcall->result;
+ afb_xreq_unref(&subcall->xreq);
+ return rc;
+}
+