From e3dc0bceb9ef653f87d766970f9f763e5416bdf1 Mon Sep 17 00:00:00 2001
From: Pawel Andruszkiewicz
Date: Thu, 27 Aug 2015 11:31:13 +0200
Subject: [PATCH] [Common] Keep track of created and destroyed instances. Safe
PostMessage() method.
Fixes: XWALK-730
The PostMessage() method is usually called after asynchronous job executed in background.
Since the job may finish after an instance has been destroyed, it's not very safe. Some of the modules
have experienced this problem before, and had similar workaround implemented (i.e. Download).
This commit adds a common mechanism which keeps track of existing instances and provides safe PostMessage() method.
As a follow-up, the method 'void Instance::PostMessage(const char* msg)' should be made private and all existing
calls to that method should be replaced with calls to 'void Instance::PostMessage(Instance* that, const char* msg)'.
Change-Id: Icb0bd38516f8a8203d7c9ca28837c036a258f9b6
Signed-off-by: Pawel Andruszkiewicz
---
src/application/application_manager.cc | 2 +-
src/common/extension.cc | 21 +++++++++++++++++++++
src/common/extension.h | 7 +++++++
3 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/src/application/application_manager.cc b/src/application/application_manager.cc
index c79db024..9da4a0fc 100755
--- a/src/application/application_manager.cc
+++ b/src/application/application_manager.cc
@@ -453,7 +453,7 @@ void ApplicationManager::Launch(const picojson::value& args) {
};
auto launch_response = [this](const std::shared_ptr& response) -> void {
- this->instance_.PostMessage(response->serialize().c_str());
+ Instance::PostMessage(&this->instance_, response->serialize().c_str());
};
TaskQueue::GetInstance().Queue(launch, launch_response, response);
diff --git a/src/common/extension.cc b/src/common/extension.cc
index 94ee3089..c11d5125 100755
--- a/src/common/extension.cc
+++ b/src/common/extension.cc
@@ -255,18 +255,39 @@ int32_t Extension::XW_Initialize(XW_Extension extension,
return XW_OK;
}
+std::mutex Instance::instance_mutex_;
+std::unordered_set Instance::all_instances_;
Instance::Instance() :
xw_instance_(0)
{
LoggerD("Enter");
+ {
+ std::lock_guard lock(instance_mutex_);
+ all_instances_.insert(this);
+ }
}
Instance::~Instance() {
LoggerD("Enter");
+ {
+ std::lock_guard lock(instance_mutex_);
+ all_instances_.erase(this);
+ }
Assert(xw_instance_ == 0);
}
+void Instance::PostMessage(Instance* that, const char* msg) {
+ LoggerD("Enter");
+ std::lock_guard lock(instance_mutex_);
+ if (that && all_instances_.end() != all_instances_.find(that)) {
+ that->PostMessage(msg);
+ } else {
+ LoggerE("Trying to post message to non-existing instance: [%p], ignoring",
+ that);
+ }
+}
+
void Instance::PostMessage(const char* msg) {
LoggerD("Enter");
if (!xw_instance_) {
diff --git a/src/common/extension.h b/src/common/extension.h
index 7e67d2b4..3e65e8df 100755
--- a/src/common/extension.h
+++ b/src/common/extension.h
@@ -21,7 +21,9 @@
#include
#include