From 9d21e0db847cebff18406f16f5d3234ec0d9e0ec Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Wed, 17 Dec 2014 13:41:13 +0100 Subject: [PATCH] Fix synchronization issues [Bug/Feature] Missing mutex [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: Iec7e016b62a0f3a671fd4843957e1bc6a265f84e --- server/zones-manager.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++- server/zones-manager.hpp | 4 ++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index a1dcc71..a0cb274 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -195,6 +195,8 @@ void ZonesManager::createZone(const std::string& zoneConfig) zone->setDbusStateChangedCallback(bind(&ZonesManager::handleDbusStateChanged, this, id, _1)); + Lock lock(mMutex); + mZones.insert(ZoneMap::value_type(id, std::move(zone))); // after zone is created successfully, put a file informing that zones are enabled @@ -208,7 +210,8 @@ void ZonesManager::createZone(const std::string& zoneConfig) void ZonesManager::destroyZone(const std::string& zoneId) { - // TODO mutex for mZones access + Lock lock(mMutex); + auto it = mZones.find(zoneId); if (it == mZones.end()) { LOGE("Failed to destroy zone " << zoneId << ": no such zone"); @@ -228,6 +231,8 @@ void ZonesManager::destroyZone(const std::string& zoneId) void ZonesManager::focus(const std::string& zoneId) { + Lock lock(mMutex); + /* try to access the object first to throw immediately if it doesn't exist */ ZoneMap::mapped_type& foregroundZone = mZones.at(zoneId); @@ -249,6 +254,8 @@ void ZonesManager::startAll() { LOGI("Starting all zones"); + Lock lock(mMutex); + bool isForegroundFound = false; for (auto& zone : mZones) { @@ -279,6 +286,8 @@ void ZonesManager::stopAll() { LOGI("Stopping all zones"); + Lock lock(mMutex); + for (auto& zone : mZones) { zone.second->stop(); } @@ -286,6 +295,8 @@ void ZonesManager::stopAll() bool ZonesManager::isPaused(const std::string& zoneId) { + Lock lock(mMutex); + auto iter = mZones.find(zoneId); if (iter == mZones.end()) { LOGE("No such zone id: " << zoneId); @@ -297,6 +308,8 @@ bool ZonesManager::isPaused(const std::string& zoneId) bool ZonesManager::isRunning(const std::string& zoneId) { + Lock lock(mMutex); + auto iter = mZones.find(zoneId); if (iter == mZones.end()) { LOGE("No such zone id: " << zoneId); @@ -307,6 +320,8 @@ bool ZonesManager::isRunning(const std::string& zoneId) std::string ZonesManager::getRunningForegroundZoneId() const { + Lock lock(mMutex); + for (auto& zone : mZones) { if (zone.first == mConfig.foregroundId && zone.second->isRunning()) { @@ -318,6 +333,8 @@ std::string ZonesManager::getRunningForegroundZoneId() const std::string ZonesManager::getNextToForegroundZoneId() { + Lock lock(mMutex); + // handles case where there is no next zone if (mZones.size() < 2) { return std::string(); @@ -349,6 +366,8 @@ void ZonesManager::switchingSequenceMonitorNotify() void ZonesManager::setZonesDetachOnExit() { + Lock lock(mMutex); + mDetachOnExit = true; for (auto& zone : mZones) { @@ -362,6 +381,9 @@ void ZonesManager::notifyActiveZoneHandler(const std::string& caller, { LOGI("notifyActiveZoneHandler(" << caller << ", " << application << ", " << message << ") called"); + + Lock lock(mMutex); + try { const std::string activeZone = getRunningForegroundZoneId(); if (!activeZone.empty() && caller != activeZone) { @@ -375,6 +397,8 @@ void ZonesManager::notifyActiveZoneHandler(const std::string& caller, void ZonesManager::displayOffHandler(const std::string& /*caller*/) { // get config of currently set zone and switch if switchToDefaultAfterTimeout is true + Lock lock(mMutex); + const std::string activeZoneName = getRunningForegroundZoneId(); const auto& activeZone = mZones.find(activeZoneName); @@ -414,6 +438,8 @@ void ZonesManager::handleZoneMoveFileRequest(const std::string& srcZoneId, << "dst: " << dstZoneId << "\n" << "path: " << path); + Lock lock(mMutex); + ZoneMap::const_iterator srcIter = mZones.find(srcZoneId); if (srcIter == mZones.end()) { LOGE("Source zone '" << srcZoneId << "' not found"); @@ -507,6 +533,8 @@ void ZonesManager::handleProxyCall(const std::string& caller, return; } + Lock lock(mMutex); + ZoneMap::const_iterator targetIter = mZones.find(target); if (targetIter == mZones.end()) { LOGE("Target zone '" << target << "' not found"); @@ -525,6 +553,8 @@ void ZonesManager::handleProxyCall(const std::string& caller, void ZonesManager::handleGetZoneDbuses(dbus::MethodResultBuilder::Pointer result) const { + Lock lock(mMutex); + std::vector entries; for (auto& zone : mZones) { GVariant* zoneId = g_variant_new_string(zone.first.c_str()); @@ -544,6 +574,8 @@ void ZonesManager::handleDbusStateChanged(const std::string& zoneId, void ZonesManager::handleGetZoneIdsCall(dbus::MethodResultBuilder::Pointer result) const { + Lock lock(mMutex); + std::vector zoneIds; for(auto& zone: mZones){ zoneIds.push_back(g_variant_new_string(zone.first.c_str())); @@ -558,6 +590,9 @@ void ZonesManager::handleGetZoneIdsCall(dbus::MethodResultBuilder::Pointer resul void ZonesManager::handleGetActiveZoneIdCall(dbus::MethodResultBuilder::Pointer result) { LOGI("GetActiveZoneId call"); + + Lock lock(mMutex); + if (!mConfig.foregroundId.empty() && mZones[mConfig.foregroundId]->isRunning()){ result->set(g_variant_new("(s)", mConfig.foregroundId.c_str())); } else { @@ -569,6 +604,9 @@ void ZonesManager::handleGetZoneInfoCall(const std::string& id, dbus::MethodResultBuilder::Pointer result) { LOGI("GetZoneInfo call"); + + Lock lock(mMutex); + if (mZones.count(id) == 0) { LOGE("No zone with id=" << id); result->setError(api::ERROR_INVALID_ID, "No such zone id"); @@ -607,7 +645,10 @@ void ZonesManager::handleDeclareFileCall(const std::string& zone, dbus::MethodResultBuilder::Pointer result) { LOGI("DeclareFile call"); + try { + Lock lock(mMutex); + mZones.at(zone)->declareFile(type, path, flags, mode); result->setVoid(); } catch (const std::out_of_range&) { @@ -628,7 +669,10 @@ void ZonesManager::handleDeclareMountCall(const std::string& source, dbus::MethodResultBuilder::Pointer result) { LOGI("DeclareMount call"); + try { + Lock lock(mMutex); + mZones.at(zone)->declareMount(source, target, type, flags, data); result->setVoid(); } catch (const std::out_of_range&) { @@ -647,6 +691,8 @@ void ZonesManager::handleDeclareLinkCall(const std::string& source, { LOGI("DeclareLink call"); try { + Lock lock(mMutex); + mZones.at(zone)->declareLink(source, target); result->setVoid(); } catch (const std::out_of_range&) { @@ -662,6 +708,9 @@ void ZonesManager::handleSetActiveZoneCall(const std::string& id, dbus::MethodResultBuilder::Pointer result) { LOGI("SetActiveZone call; Id=" << id ); + + Lock lock(mMutex); + auto zone = mZones.find(id); if (zone == mZones.end()){ LOGE("No zone with id=" << id ); @@ -737,6 +786,8 @@ void ZonesManager::handleCreateZoneCall(const std::string& id, LOGI("Creating zone " << id); + Lock lock(mMutex); + // TODO: This solution is temporary. It utilizes direct access to config files when creating new // zones. Update this handler when config database will appear. namespace fs = boost::filesystem; @@ -819,6 +870,8 @@ void ZonesManager::handleCreateZoneCall(const std::string& id, void ZonesManager::handleDestroyZoneCall(const std::string& id, dbus::MethodResultBuilder::Pointer result) { + Lock lock(mMutex); + if (mZones.find(id) == mZones.end()) { LOGE("Failed to destroy zone - no such zone id: " << id); result->setError(api::ERROR_INVALID_ID, "No such zone id"); @@ -845,6 +898,9 @@ void ZonesManager::handleLockZoneCall(const std::string& id, dbus::MethodResultBuilder::Pointer result) { LOGI("LockZone call; Id=" << id ); + + Lock lock(mMutex); + auto iter = mZones.find(id); if (iter == mZones.end()) { LOGE("Failed to lock zone - no such zone id: " << id); @@ -875,6 +931,9 @@ void ZonesManager::handleUnlockZoneCall(const std::string& id, dbus::MethodResultBuilder::Pointer result) { LOGI("UnlockZone call; Id=" << id ); + + Lock lock(mMutex); + auto iter = mZones.find(id); if (iter == mZones.end()) { LOGE("Failed to unlock zone - no such zone id: " << id); diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp index 41a3e7c..2ed5312 100644 --- a/server/zones-manager.hpp +++ b/server/zones-manager.hpp @@ -106,7 +106,11 @@ public: void setZonesDetachOnExit(); private: + typedef std::recursive_mutex Mutex; + typedef std::unique_lock Lock; + utils::Worker::Pointer mWorker; + mutable Mutex mMutex; // used to protect mZones ZonesManagerConfig mConfig; std::string mConfigPath; HostConnection mHostConnection; -- 2.7.4