From e292bab8cc00a0219999b57cf0ed6de1e3106e67 Mon Sep 17 00:00:00 2001 From: dubj Date: Mon, 11 Jul 2022 11:38:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0map=E7=9A=84=E5=8E=9F?= =?UTF-8?q?=E5=AD=90=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dubj Change-Id: I92ad25aa4672cd12eb2799b6aeb00ba6b78923e4 --- dmserver/include/display_manager_service.h | 3 +- dmserver/src/display_manager_service.cpp | 6 +- utils/include/atomic_map.h | 106 +++++++++++++++++++++ wmserver/include/window_manager_service.h | 3 +- wmserver/src/window_manager_service.cpp | 5 +- 5 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 utils/include/atomic_map.h diff --git a/dmserver/include/display_manager_service.h b/dmserver/include/display_manager_service.h index 1611bbc5..3694c00c 100644 --- a/dmserver/include/display_manager_service.h +++ b/dmserver/include/display_manager_service.h @@ -23,6 +23,7 @@ #include #include +#include "atomic_map.h" #include "dm_common.h" #include "display_dumper.h" #include "screen.h" @@ -117,7 +118,7 @@ private: sptr displayChangeListener_; sptr displayDumper_; static float customVirtualPixelRatio_; - std::map accessTokenIdMaps_; + AtomicMap accessTokenIdMaps_; bool isAutoRotationOpen_; }; } // namespace OHOS::Rosen diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index d3052bd0..aae0279b 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -178,16 +178,16 @@ ScreenId DisplayManagerService::CreateVirtualScreen(VirtualScreenOption option, HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:CreateVirtualScreen(%s)", option.name_.c_str()); ScreenId screenId = abstractScreenController_->CreateVirtualScreen(option, displayManagerAgent); CHECK_SCREEN_AND_RETURN(SCREEN_ID_INVALID); - accessTokenIdMaps_[screenId] = IPCSkeleton::GetCallingTokenID(); + accessTokenIdMaps_.insert(std::pair(screenId, IPCSkeleton::GetCallingTokenID())); return screenId; } DMError DisplayManagerService::DestroyVirtualScreen(ScreenId screenId) { - if (accessTokenIdMaps_[screenId] != IPCSkeleton::GetCallingTokenID()) { + if (!accessTokenIdMaps_.isExistAndRemove(screenId, IPCSkeleton::GetCallingTokenID())) { return DMError::DM_ERROR_INVALID_CALLING; } - accessTokenIdMaps_.erase(screenId); + WLOGFI("DestroyVirtualScreen::ScreenId: %{public}" PRIu64 "", screenId); CHECK_SCREEN_AND_RETURN(DMError::DM_ERROR_INVALID_PARAM); diff --git a/utils/include/atomic_map.h b/utils/include/atomic_map.h new file mode 100644 index 00000000..f2f56c0f --- /dev/null +++ b/utils/include/atomic_map.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ATOMIC_MAP_H +#define ATOMIC_MAP_H + +#include +#include +#include "nocopyable.h" + +namespace OHOS { +namespace Rosen { +template +class AtomicMap { +public: + void insert(const std::pair& kv) + { + locked(); + data_.insert(kv); + unlocked(); + } + + void erase(const Key& key) + { + locked(); + data_.erase(key); + unlocked(); + } + + auto find(Key k) + { + locked(); + auto key = data_.find(k); + unlocked(); + return key; + } + + int count(Key k) + { + locked(); + int size = data_.count(k); + unlocked(); + return size; + } + + bool isExistAndRemove(Key k, uint32_t value) + { + locked(); + if (data_.count(k) <= 0) { + unlocked(); + return false; + } + if (data_[k] == value) { + data_.erase(k); + unlocked(); + return true; + } + unlocked(); + return false; + } + + bool isExist(Key k, uint32_t value) + { + locked(); + if (data_.count(k) <= 0) { + unlocked(); + return false; + } + if (data_[k] == value) { + unlocked(); + return true; + } + unlocked(); + return false; + } +private: + void locked() + { + bool expect = false; + while (!isWritingOrReading_.compare_exchange_weak(expect, true, std::memory_order_relaxed)) { + expect = false; + } + } + + void unlocked() + { + isWritingOrReading_.store(false); + } + + std::map data_; + std::atomic isWritingOrReading_ { false }; +}; +} // Rosen +} // OHOS +#endif // ATOMIC_MAP_H \ No newline at end of file diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index eebc793e..cd1f3d9a 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -24,6 +24,7 @@ #include #include #include +#include "atomic_map.h" #include "display_change_listener.h" #include "drag_controller.h" #include "freeze_controller.h" @@ -124,7 +125,7 @@ private: void ConfigureWindowManagerService(); static inline SingletonDelegator delegator; - std::map accessTokenIdMaps_; + AtomicMap accessTokenIdMaps_; sptr windowRoot_; sptr windowController_; sptr inputWindowMonitor_; diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 4416df19..4902ab76 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -379,7 +379,7 @@ WMError WindowManagerService::CreateWindow(sptr& window, sptrCreateWindow(window, property, surfaceNode, windowId, token, pid, uid); }).get(); - accessTokenIdMaps_[windowId] = IPCSkeleton::GetCallingTokenID(); + accessTokenIdMaps_.insert(std::pair(windowId, IPCSkeleton::GetCallingTokenID())); return ret; } @@ -420,11 +420,10 @@ WMError WindowManagerService::RemoveWindow(uint32_t windowId) WMError WindowManagerService::DestroyWindow(uint32_t windowId, bool onlySelf) { - if (accessTokenIdMaps_[windowId] != IPCSkeleton::GetCallingTokenID()) { + if (!accessTokenIdMaps_.isExistAndRemove(windowId, IPCSkeleton::GetCallingTokenID())) { WLOGFI("Operation rejected"); return WMError::WM_ERROR_INVALID_OPERATION; } - accessTokenIdMaps_.erase(windowId); return wmsTaskLooper_->ScheduleTask([this, windowId, onlySelf]() { WLOGFI("[WMS] Destroy: %{public}u", windowId); HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "wms:DestroyWindow(%u)", windowId);