#endif
}
+std::set<LaunchAppControlCallbackData*> ApplicationManager::launch_app_control_set_global_{};
+std::mutex ApplicationManager::launch_app_control_set_mutex_{};
+
ApplicationManager::ApplicationManager(ApplicationInstance& instance)
: pkgmgr_client_handle_(nullptr),
pkgmgr_client_uninstall_handle_(nullptr),
// cannot be determined, reply_callback depends on application scenario, which
// cannot be predicted. Moreover reply_callback is optional and can be called or not,
// thus callback_data is relesed here at the end of application lifetime.
- std::for_each(launch_app_control_set.begin(), launch_app_control_set.end(),
+ std::lock_guard<std::mutex> lock(launch_app_control_set_mutex_);
+ std::for_each(launch_app_control_set_.begin(), launch_app_control_set_.end(),
[](LaunchAppControlCallbackData* const& data) {
LoggerD("Releasing callback data: %p", data);
delete data;
+ launch_app_control_set_global_.erase(data);
});
}
LaunchAppControlCallbackData* callback_data =
static_cast<LaunchAppControlCallbackData*>(user_data);
- if (!callback_data) {
- LoggerD("reply_callback failed: user_data is nullptr");
+
+ std::lock_guard<std::mutex> lock(launch_app_control_set_mutex_);
+ if (!launch_app_control_set_global_.count(callback_data)) {
+ LoggerE("Invalid callback_data: %p", callback_data);
return;
}
LaunchAppControlCallbackData* callback_data =
static_cast<LaunchAppControlCallbackData*>(user_data);
+ std::lock_guard<std::mutex> lock(launch_app_control_set_mutex_);
+ if (!launch_app_control_set_global_.count(callback_data)) {
+ LoggerE("Invalid callback_data: %p", callback_data);
+ return;
+ }
+
auto result = utils::TranslateAppControlError(launch_result);
if (result.IsError()) {
// Moreover reply_callback is optional and can be called or not,
// thus callback_data is stored for releasing in destructor of ApplicationManager
// at the end of application lifetime.
- launch_app_control_set.insert(launch_app_user_data);
+ // We can not be sure whether callbach will not fire after instance destruction,
+ // we store all user_data pointers in static launch_app_control_set_global_ to check
+ // if they are still valid.
+ std::lock_guard<std::mutex> lock(launch_app_control_set_mutex_);
+ launch_app_control_set_.insert(launch_app_user_data);
+ launch_app_control_set_global_.insert(launch_app_user_data);
LoggerD("App launched, data %p stored for later release", launch_app_user_data);
}
}
#include <pkgmgr-info.h>
#include <functional>
#include <memory>
+#include <mutex>
#include <set>
#include <string>
#if defined(TIZEN_MOBILE)
JsonCallback event_callback_;
JsonCallback status_callback_;
std::map<std::string, event_handler_h> event_handler_map_;
- std::set<LaunchAppControlCallbackData*> launch_app_control_set;
+ std::set<LaunchAppControlCallbackData*> launch_app_control_set_;
+ // We use static set of callback_data's pointers to be able to check whether
+ // callback is fired after ApplicationInstance destruction
+ static std::set<LaunchAppControlCallbackData*> launch_app_control_set_global_;
+ static std::mutex launch_app_control_set_mutex_;
static void OnEvent(const char* event_name, bundle* event_data, void* user_data);
static void OnStatusEvent(const char* type, const char* app_id,
app_manager_event_type_e event_type,