#include "afb-calls.h"
#include "jobs.h"
#include "verbose.h"
+#include "sig-monitor.h"
/*************************************************************************
* internal types
}
/* create the event */
- handler = malloc(strlen(pattern) + strlen(pattern));
+ handler = malloc(strlen(pattern) + sizeof * handler);
if (!handler) {
ERROR("[API %s] can't allocate event handler %s", export->api.apiname, pattern);
errno = ENOMEM;
handler->callback = callback;
handler->closure = closure;
strcpy(handler->pattern, pattern);
- export->event_handlers = handler;
+ *previous = handler;
return 0;
}
******************************************************************************
******************************************************************************/
-int afb_export_start(struct afb_export *export, int share_session, int onneed)
+struct init
{
+ int return_code;
+ struct afb_export *export;
+};
+
+static void do_init(int sig, void *closure)
+{
+ int rc = -1;
+ struct init *init = closure;
+ struct afb_export *export;
+
+ if (sig)
+ errno = EFAULT;
+ else {
+ export = init->export;
+ switch (export->version) {
+#if defined(WITH_LEGACY_BINDING_V1)
+ case Api_Version_1:
+ rc = export->init.v1 ? export->init.v1(
+ (struct afb_service_x1){
+ .itf = &hooked_service_itf,
+ .closure = to_api_x3(export) }) : 0;
+ break;
+#endif
+ case Api_Version_2:
+ rc = export->init.v2 ? export->init.v2() : 0;
+ break;
+ case Api_Version_3:
+ rc = export->init.v3 ? export->init.v3(to_api_x3(export)) : 0;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ }
+ init->return_code = rc;
+};
+
+
+int afb_export_start(struct afb_export *export)
+{
+ struct init init;
int rc;
/* check state */
- if (export->state != Api_State_Pre_Init) {
- /* not an error when onneed */
- if (onneed != 0)
- goto done;
+ switch (export->state) {
+ case Api_State_Run:
+ return 0;
- /* already started: it is an error */
- ERROR("Service of API %s already started", export->api.apiname);
+ case Api_State_Init:
+ /* starting in progress: it is an error */
+ ERROR("Service of API %s required started while starting", export->api.apiname);
return -1;
- }
- /* unshare the session if asked */
- if (!share_session) {
- rc = afb_export_unshare_session(export);
- if (rc < 0) {
- ERROR("Can't unshare the session for %s", export->api.apiname);
- return -1;
- }
+ default:
+ break;
}
/* set event handling */
case Api_Version_1:
#endif
case Api_Version_2:
- if (export->on_any_event_v12)
+ if (export->on_any_event_v12) {
rc = afb_export_handle_events_v12(export, export->on_any_event_v12);
- break;
+ break;
+ }
+ /*@fallthrough@*/
default:
rc = 0;
break;
afb_hook_api_start_before(export);
export->state = Api_State_Init;
- switch (export->version) {
-#if defined(WITH_LEGACY_BINDING_V1)
- case Api_Version_1:
- rc = export->init.v1 ? export->init.v1((struct afb_service_x1){ .itf = &hooked_service_itf, .closure = to_api_x3(export) }) : 0;
- break;
-#endif
- case Api_Version_2:
- rc = export->init.v2 ? export->init.v2() : 0;
- break;
- case Api_Version_3:
- rc = export->init.v3 ? export->init.v3(to_api_x3(export)) : 0;
- break;
- default:
- errno = EINVAL;
- rc = -1;
- break;
- }
+ init.export = export;
+ sig_monitor(0, do_init, &init);
+ rc = init.return_code;
export->state = Api_State_Run;
if (export->hooksvc & afb_hook_flag_api_start)
return rc;
}
-done:
return 0;
}
return result;
}
-static int api_service_start_cb(void *closure, int share_session, int onneed)
+static int api_service_start_cb(void *closure)
{
struct afb_export *export = closure;
- return afb_export_start(export, share_session, onneed);
+ return afb_export_start(export);
}
static void api_update_hooks_cb(void *closure)