aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/hs-clientmanager.cpp1
-rw-r--r--src/hs-proxy.cpp62
2 files changed, 60 insertions, 3 deletions
diff --git a/src/hs-clientmanager.cpp b/src/hs-clientmanager.cpp
index 7c2adc5..beac816 100644
--- a/src/hs-clientmanager.cpp
+++ b/src/hs-clientmanager.cpp
@@ -184,6 +184,7 @@ int HS_ClientManager::handleRequest(afb_req_t request, const char *verb, const c
std::string id(appid);
auto ip = client_list.find(id);
if(ip != client_list.end()) {
+ // FIXME: do another verification here in case the application died
ret = ip->second->handleRequest(request, verb);
}
else {
diff --git a/src/hs-proxy.cpp b/src/hs-proxy.cpp
index a7236b4..33e5d53 100644
--- a/src/hs-proxy.cpp
+++ b/src/hs-proxy.cpp
@@ -17,6 +17,12 @@
#include "homescreen.h"
#include "hs-proxy.h"
+struct closure_data {
+ std::string appid;
+ HS_ClientCtxt *clientCtx;
+ struct hs_instance *hs_instance;
+};
+
const char _afm_main[] = "afm-main";
@@ -37,6 +43,24 @@ const char _afm_main[] = "afm-main";
static void api_callback(void *closure, struct json_object *object, const char *error, const char *info, afb_api_t api)
{
AFB_INFO("asynchronous call, error=%s, info=%s, object=%s.", error, info, json_object_get_string(object));
+ struct closure_data *cdata = static_cast<struct closure_data *>(closure);
+
+ if (!cdata->hs_instance) {
+ return;
+ }
+
+ struct HS_ClientManager *clientManager = cdata->hs_instance->client_manager;
+ if (!clientManager) {
+ return;
+ }
+
+ /* if we have an error then we couldn't start the application so we remove it */
+ if (error) {
+ clientManager->removeClientCtxt(cdata->clientCtx);
+ clientManager->removeClient(cdata->appid);
+ }
+
+ free(cdata);
}
/**
@@ -52,10 +76,10 @@ static void api_callback(void *closure, struct json_object *object, const char *
* None
*
*/
-static void api_call(afb_api_t api, const char *service, const char *verb, struct json_object *args)
+static void api_call(afb_api_t api, const char *service, const char *verb, struct json_object *args, struct closure_data *cdata)
{
AFB_INFO("service=%s verb=%s, args=%s.", service, verb, json_object_get_string(args));
- afb_api_call(api, service, verb, args, api_callback, nullptr);
+ afb_api_call(api, service, verb, args, api_callback, cdata);
}
/**
@@ -131,5 +155,37 @@ int HS_AfmMainProxy::detail(afb_api_t api, const std::string &id, struct json_ob
void HS_AfmMainProxy::start(struct hs_instance *instance, afb_req_t request, const std::string &id)
{
struct json_object *args = json_object_new_string(id.c_str());
- api_call(request->api, _afm_main, __FUNCTION__, args);
+ struct closure_data *cdata;
+
+ /* tentatively store the client and client context, as the afb_req_t
+ * request will no longer be available in the async callback handler. This
+ * is similar to that is done showWindow(), handleRequest() in
+ * homescreen.cpp, but allows to fake the subscription here as well to
+ * avoid clients create/install dummy event handlers as to 'register' (or
+ * to keep track of applications started).
+ *
+ * In case api_callback() does return an error we'll remove then the client
+ * and client context there. We pass the closure_data with the client context
+ * and the application id to remove it.
+ */
+ if (!instance)
+ return;
+
+ cdata = static_cast<struct closure_data *>(calloc(1, sizeof(*cdata)));
+ cdata->hs_instance = instance;
+ cdata->appid = id;
+
+ struct HS_ClientManager *clientManager = instance->client_manager;
+ if (!clientManager) {
+ return;
+ }
+
+ cdata->clientCtx = clientManager->createClientCtxt(request, id);
+ HS_Client *client = clientManager->addClient(request, id);
+ if (client) {
+ if (client->handleRequest(request, "subscribe"))
+ AFB_WARNING("Failed to handle subcribe\n");
+ }
+
+ api_call(request->api, _afm_main, __FUNCTION__, args, cdata);
}