diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 3e27ef6acb..006c783aad 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -42563,8 +42563,6 @@ ORIGIN: ../../../flutter/fml/platform/posix/native_library_posix.cc + ../../../f ORIGIN: ../../../flutter/fml/platform/posix/paths_posix.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/posix/posix_wrappers_posix.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/posix/process_posix.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/fml/platform/posix/shared_mutex_posix.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/fml/platform/posix/shared_mutex_posix.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/win/command_line_win.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/win/errors_win.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/win/errors_win.h + ../../../flutter/LICENSE @@ -42593,9 +42591,6 @@ ORIGIN: ../../../flutter/fml/synchronization/count_down_latch.cc + ../../../flut ORIGIN: ../../../flutter/fml/synchronization/count_down_latch.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/synchronization/semaphore.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/synchronization/semaphore.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/fml/synchronization/shared_mutex.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/fml/synchronization/shared_mutex_std.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/fml/synchronization/shared_mutex_std.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/synchronization/sync_switch.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/synchronization/sync_switch.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/synchronization/waitable_event.cc + ../../../flutter/LICENSE @@ -45400,8 +45395,6 @@ FILE: ../../../flutter/fml/platform/posix/native_library_posix.cc FILE: ../../../flutter/fml/platform/posix/paths_posix.cc FILE: ../../../flutter/fml/platform/posix/posix_wrappers_posix.cc FILE: ../../../flutter/fml/platform/posix/process_posix.cc -FILE: ../../../flutter/fml/platform/posix/shared_mutex_posix.cc -FILE: ../../../flutter/fml/platform/posix/shared_mutex_posix.h FILE: ../../../flutter/fml/platform/win/command_line_win.cc FILE: ../../../flutter/fml/platform/win/errors_win.cc FILE: ../../../flutter/fml/platform/win/errors_win.h @@ -45430,9 +45423,6 @@ FILE: ../../../flutter/fml/synchronization/count_down_latch.cc FILE: ../../../flutter/fml/synchronization/count_down_latch.h FILE: ../../../flutter/fml/synchronization/semaphore.cc FILE: ../../../flutter/fml/synchronization/semaphore.h -FILE: ../../../flutter/fml/synchronization/shared_mutex.h -FILE: ../../../flutter/fml/synchronization/shared_mutex_std.cc -FILE: ../../../flutter/fml/synchronization/shared_mutex_std.h FILE: ../../../flutter/fml/synchronization/sync_switch.cc FILE: ../../../flutter/fml/synchronization/sync_switch.h FILE: ../../../flutter/fml/synchronization/waitable_event.cc diff --git a/engine/src/flutter/fml/BUILD.gn b/engine/src/flutter/fml/BUILD.gn index 21b0708745..2dc48033fb 100644 --- a/engine/src/flutter/fml/BUILD.gn +++ b/engine/src/flutter/fml/BUILD.gn @@ -78,7 +78,6 @@ source_set("fml") { "synchronization/count_down_latch.h", "synchronization/semaphore.cc", "synchronization/semaphore.h", - "synchronization/shared_mutex.h", "synchronization/sync_switch.cc", "synchronization/sync_switch.h", "synchronization/waitable_event.cc", @@ -136,15 +135,9 @@ source_set("fml") { libs = [] if (is_ios || is_mac) { - sources += [ - "platform/darwin/concurrent_message_loop_factory.mm", - "platform/posix/shared_mutex_posix.cc", - ] + sources += [ "platform/darwin/concurrent_message_loop_factory.mm" ] } else { - sources += [ - "concurrent_message_loop_factory.cc", - "synchronization/shared_mutex_std.cc", - ] + sources += [ "concurrent_message_loop_factory.cc" ] } if (is_ios || is_mac) { diff --git a/engine/src/flutter/fml/message_loop_task_queues.h b/engine/src/flutter/fml/message_loop_task_queues.h index b3c9a63314..d8ed37920d 100644 --- a/engine/src/flutter/fml/message_loop_task_queues.h +++ b/engine/src/flutter/fml/message_loop_task_queues.h @@ -15,7 +15,6 @@ #include "flutter/fml/delayed_task.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/ref_counted.h" -#include "flutter/fml/synchronization/shared_mutex.h" #include "flutter/fml/task_queue_id.h" #include "flutter/fml/task_source.h" #include "flutter/fml/wakeable.h" diff --git a/engine/src/flutter/fml/platform/posix/shared_mutex_posix.cc b/engine/src/flutter/fml/platform/posix/shared_mutex_posix.cc deleted file mode 100644 index 515b2adb36..0000000000 --- a/engine/src/flutter/fml/platform/posix/shared_mutex_posix.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/fml/platform/posix/shared_mutex_posix.h" - -#include "flutter/fml/logging.h" - -namespace fml { - -SharedMutex* SharedMutex::Create() { - return new SharedMutexPosix(); -} - -SharedMutexPosix::SharedMutexPosix() { - FML_CHECK(pthread_rwlock_init(&rwlock_, nullptr) == 0); -} - -void SharedMutexPosix::Lock() { - pthread_rwlock_wrlock(&rwlock_); -} - -void SharedMutexPosix::LockShared() { - pthread_rwlock_rdlock(&rwlock_); -} - -void SharedMutexPosix::Unlock() { - pthread_rwlock_unlock(&rwlock_); -} - -void SharedMutexPosix::UnlockShared() { - pthread_rwlock_unlock(&rwlock_); -} - -} // namespace fml diff --git a/engine/src/flutter/fml/platform/posix/shared_mutex_posix.h b/engine/src/flutter/fml/platform/posix/shared_mutex_posix.h deleted file mode 100644 index 6694a33598..0000000000 --- a/engine/src/flutter/fml/platform/posix/shared_mutex_posix.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_FML_PLATFORM_POSIX_SHARED_MUTEX_POSIX_H_ -#define FLUTTER_FML_PLATFORM_POSIX_SHARED_MUTEX_POSIX_H_ - -#include - -#include "flutter/fml/synchronization/shared_mutex.h" - -namespace fml { - -class SharedMutexPosix : public SharedMutex { - public: - virtual void Lock(); - virtual void LockShared(); - virtual void Unlock(); - virtual void UnlockShared(); - - private: - friend SharedMutex* SharedMutex::Create(); - SharedMutexPosix(); - - pthread_rwlock_t rwlock_; -}; - -} // namespace fml - -#endif // FLUTTER_FML_PLATFORM_POSIX_SHARED_MUTEX_POSIX_H_ diff --git a/engine/src/flutter/fml/synchronization/shared_mutex.h b/engine/src/flutter/fml/synchronization/shared_mutex.h deleted file mode 100644 index a5f343d2d5..0000000000 --- a/engine/src/flutter/fml/synchronization/shared_mutex.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_FML_SYNCHRONIZATION_SHARED_MUTEX_H_ -#define FLUTTER_FML_SYNCHRONIZATION_SHARED_MUTEX_H_ - -namespace fml { - -// Interface for a reader/writer lock. -class SharedMutex { - public: - static SharedMutex* Create(); - virtual ~SharedMutex() = default; - - virtual void Lock() = 0; - virtual void LockShared() = 0; - virtual void Unlock() = 0; - virtual void UnlockShared() = 0; -}; - -// RAII wrapper that does a shared acquire of a SharedMutex. -class SharedLock { - public: - explicit SharedLock(SharedMutex& shared_mutex) : shared_mutex_(shared_mutex) { - shared_mutex_.LockShared(); - } - - ~SharedLock() { shared_mutex_.UnlockShared(); } - - private: - SharedMutex& shared_mutex_; -}; - -// RAII wrapper that does an exclusive acquire of a SharedMutex. -class UniqueLock { - public: - explicit UniqueLock(SharedMutex& shared_mutex) : shared_mutex_(shared_mutex) { - shared_mutex_.Lock(); - } - - ~UniqueLock() { shared_mutex_.Unlock(); } - - private: - SharedMutex& shared_mutex_; -}; - -} // namespace fml - -#endif // FLUTTER_FML_SYNCHRONIZATION_SHARED_MUTEX_H_ diff --git a/engine/src/flutter/fml/synchronization/shared_mutex_std.cc b/engine/src/flutter/fml/synchronization/shared_mutex_std.cc deleted file mode 100644 index 41754446ab..0000000000 --- a/engine/src/flutter/fml/synchronization/shared_mutex_std.cc +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/fml/synchronization/shared_mutex_std.h" - -namespace fml { - -SharedMutex* SharedMutex::Create() { - return new SharedMutexStd(); -} - -void SharedMutexStd::Lock() { - mutex_.lock(); -} - -void SharedMutexStd::LockShared() { - mutex_.lock_shared(); -} - -void SharedMutexStd::Unlock() { - mutex_.unlock(); -} - -void SharedMutexStd::UnlockShared() { - mutex_.unlock_shared(); -} - -} // namespace fml diff --git a/engine/src/flutter/fml/synchronization/shared_mutex_std.h b/engine/src/flutter/fml/synchronization/shared_mutex_std.h deleted file mode 100644 index d8e2a1a3ec..0000000000 --- a/engine/src/flutter/fml/synchronization/shared_mutex_std.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_FML_SYNCHRONIZATION_SHARED_MUTEX_STD_H_ -#define FLUTTER_FML_SYNCHRONIZATION_SHARED_MUTEX_STD_H_ - -#include "flutter/fml/synchronization/shared_mutex.h" - -#include - -namespace fml { - -class SharedMutexStd : public SharedMutex { - public: - virtual void Lock(); - virtual void LockShared(); - virtual void Unlock(); - virtual void UnlockShared(); - - private: - friend SharedMutex* SharedMutex::Create(); - SharedMutexStd() = default; - - std::shared_timed_mutex mutex_; -}; - -} // namespace fml - -#endif // FLUTTER_FML_SYNCHRONIZATION_SHARED_MUTEX_STD_H_ diff --git a/engine/src/flutter/fml/synchronization/sync_switch.cc b/engine/src/flutter/fml/synchronization/sync_switch.cc index 2c04fae2f0..463b6a08d7 100644 --- a/engine/src/flutter/fml/synchronization/sync_switch.cc +++ b/engine/src/flutter/fml/synchronization/sync_switch.cc @@ -20,12 +20,10 @@ SyncSwitch::Handlers& SyncSwitch::Handlers::SetIfFalse( return *this; } -SyncSwitch::SyncSwitch(bool value) - : mutex_(std::unique_ptr(fml::SharedMutex::Create())), - value_(value) {} +SyncSwitch::SyncSwitch(bool value) : value_(value) {} void SyncSwitch::Execute(const SyncSwitch::Handlers& handlers) const { - fml::SharedLock lock(*mutex_); + std::shared_lock lock(mutex_); if (value_) { handlers.true_handler(); } else { @@ -35,7 +33,7 @@ void SyncSwitch::Execute(const SyncSwitch::Handlers& handlers) const { void SyncSwitch::SetSwitch(bool value) { { - fml::UniqueLock lock(*mutex_); + std::unique_lock lock(mutex_); value_ = value; } for (Observer* observer : observers_) { @@ -44,7 +42,7 @@ void SyncSwitch::SetSwitch(bool value) { } void SyncSwitch::AddObserver(Observer* observer) const { - fml::UniqueLock lock(*mutex_); + std::unique_lock lock(mutex_); if (std::find(observers_.begin(), observers_.end(), observer) == observers_.end()) { observers_.push_back(observer); @@ -52,7 +50,7 @@ void SyncSwitch::AddObserver(Observer* observer) const { } void SyncSwitch::RemoveObserver(Observer* observer) const { - fml::UniqueLock lock(*mutex_); + std::unique_lock lock(mutex_); observers_.erase(std::remove(observers_.begin(), observers_.end(), observer), observers_.end()); } diff --git a/engine/src/flutter/fml/synchronization/sync_switch.h b/engine/src/flutter/fml/synchronization/sync_switch.h index d9b0807afd..93aab7e576 100644 --- a/engine/src/flutter/fml/synchronization/sync_switch.h +++ b/engine/src/flutter/fml/synchronization/sync_switch.h @@ -7,10 +7,10 @@ #include #include +#include #include #include "flutter/fml/macros.h" -#include "flutter/fml/synchronization/shared_mutex.h" namespace fml { @@ -70,7 +70,7 @@ class SyncSwitch { void RemoveObserver(Observer* observer) const; private: - mutable std::unique_ptr mutex_; + mutable std::shared_mutex mutex_; mutable std::vector observers_; bool value_; diff --git a/engine/src/flutter/impeller/base/thread.h b/engine/src/flutter/impeller/base/thread.h index 3ec18ab9a9..ae9ae3badd 100644 --- a/engine/src/flutter/impeller/base/thread.h +++ b/engine/src/flutter/impeller/base/thread.h @@ -10,9 +10,9 @@ #include #include #include +#include #include -#include "flutter/fml/synchronization/shared_mutex.h" #include "impeller/base/thread_safety.h" namespace impeller { @@ -45,21 +45,20 @@ class IPLR_CAPABILITY("mutex") Mutex { class IPLR_CAPABILITY("mutex") RWMutex { public: - RWMutex() - : mutex_(std::unique_ptr(fml::SharedMutex::Create())) {} + RWMutex() = default; ~RWMutex() = default; - void LockWriter() IPLR_ACQUIRE() { mutex_->Lock(); } + void LockWriter() IPLR_ACQUIRE() { mutex_.lock(); } - void UnlockWriter() IPLR_RELEASE() { mutex_->Unlock(); } + void UnlockWriter() IPLR_RELEASE() { mutex_.unlock(); } - void LockReader() IPLR_ACQUIRE_SHARED() { mutex_->LockShared(); } + void LockReader() IPLR_ACQUIRE_SHARED() { mutex_.lock_shared(); } - void UnlockReader() IPLR_RELEASE_SHARED() { mutex_->UnlockShared(); } + void UnlockReader() IPLR_RELEASE_SHARED() { mutex_.unlock_shared(); } private: - std::unique_ptr mutex_; + std::shared_mutex mutex_; RWMutex(const RWMutex&) = delete; diff --git a/engine/src/flutter/runtime/dart_vm_initializer.cc b/engine/src/flutter/runtime/dart_vm_initializer.cc index fbd941d11f..f47198f5a7 100644 --- a/engine/src/flutter/runtime/dart_vm_initializer.cc +++ b/engine/src/flutter/runtime/dart_vm_initializer.cc @@ -7,7 +7,6 @@ #include #include "flutter/fml/logging.h" -#include "flutter/fml/synchronization/shared_mutex.h" #include "flutter/fml/trace_event.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_configuration.h" diff --git a/engine/src/flutter/runtime/service_protocol.cc b/engine/src/flutter/runtime/service_protocol.cc index 2a7f9d1cd0..ae90ec4573 100644 --- a/engine/src/flutter/runtime/service_protocol.cc +++ b/engine/src/flutter/runtime/service_protocol.cc @@ -59,8 +59,7 @@ ServiceProtocol::ServiceProtocol() kGetSkSLsExtensionName, kEstimateRasterCacheMemoryExtensionName, kReloadAssetFonts, - }), - handlers_mutex_(fml::SharedMutex::Create()) {} + }) {} ServiceProtocol::~ServiceProtocol() { ToggleHooks(false); @@ -68,19 +67,19 @@ ServiceProtocol::~ServiceProtocol() { void ServiceProtocol::AddHandler(Handler* handler, const Handler::Description& description) { - fml::UniqueLock lock(*handlers_mutex_); + std::unique_lock lock(handlers_mutex_); handlers_.emplace(handler, description); } void ServiceProtocol::RemoveHandler(Handler* handler) { - fml::UniqueLock lock(*handlers_mutex_); + std::unique_lock lock(handlers_mutex_); handlers_.erase(handler); } void ServiceProtocol::SetHandlerDescription( Handler* handler, const Handler::Description& description) { - fml::SharedLock lock(*handlers_mutex_); + std::shared_lock lock(handlers_mutex_); auto it = handlers_.find(handler); if (it != handlers_.end()) { it->second.Store(description); @@ -191,7 +190,7 @@ bool ServiceProtocol::HandleMessage(std::string_view method, return HandleListViewsMethod(response); } - fml::SharedLock lock(*handlers_mutex_); + std::shared_lock lock(handlers_mutex_); if (handlers_.empty()) { WriteServerErrorResponse(response, @@ -262,7 +261,7 @@ void ServiceProtocol::Handler::Description::Write( bool ServiceProtocol::HandleListViewsMethod( rapidjson::Document* response) const { - fml::SharedLock lock(*handlers_mutex_); + std::shared_lock lock(handlers_mutex_); std::vector> descriptions; descriptions.reserve(handlers_.size()); for (const auto& handler : handlers_) { diff --git a/engine/src/flutter/runtime/service_protocol.h b/engine/src/flutter/runtime/service_protocol.h index 4e8ddb467a..8d277a2715 100644 --- a/engine/src/flutter/runtime/service_protocol.h +++ b/engine/src/flutter/runtime/service_protocol.h @@ -7,12 +7,12 @@ #include #include +#include #include #include #include "flutter/fml/macros.h" #include "flutter/fml/synchronization/atomic_object.h" -#include "flutter/fml/synchronization/shared_mutex.h" #include "flutter/fml/task_runner.h" #include "rapidjson/document.h" @@ -75,7 +75,7 @@ class ServiceProtocol { private: const std::set endpoints_; - std::unique_ptr handlers_mutex_; + mutable std::shared_mutex handlers_mutex_; std::map> handlers_; [[nodiscard]] static bool HandleMessage(const char* method, diff --git a/engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc b/engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc index 6962136909..11885cb6cd 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc +++ b/engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc @@ -7,6 +7,7 @@ #include #include +#include #include #include "flutter/fml/logging.h" @@ -150,7 +151,6 @@ FlutterWindowsEngine::FlutterWindowsEngine( : project_(std::make_unique(project)), windows_proc_table_(std::move(windows_proc_table)), aot_data_(nullptr, nullptr), - views_mutex_(fml::SharedMutex::Create()), lifecycle_manager_(std::make_unique(this)) { if (windows_proc_table_ == nullptr) { windows_proc_table_ = std::make_shared(); @@ -505,7 +505,7 @@ std::unique_ptr FlutterWindowsEngine::CreateView( { // Add the view to the embedder. This must happen before the engine // is notified the view exists and starts presenting to it. - fml::UniqueLock write_lock{*views_mutex_}; + std::unique_lock write_lock(views_mutex_); FML_DCHECK(views_.find(view_id) == views_.end()); views_[view_id] = view.get(); } @@ -554,7 +554,7 @@ std::unique_ptr FlutterWindowsEngine::CreateView( // engine's state. This is unexpected and indicates a bug in the Windows // embedder. FML_LOG(ERROR) << "FlutterEngineAddView failed to add view"; - fml::UniqueLock write_lock{*views_mutex_}; + std::unique_lock write_lock(views_mutex_); views_.erase(view_id); return nullptr; } @@ -618,7 +618,7 @@ void FlutterWindowsEngine::RemoveView(FlutterViewId view_id) { { // The engine no longer presents to the view. Remove the view from the // embedder. - fml::UniqueLock write_lock{*views_mutex_}; + std::unique_lock write_lock(views_mutex_); FML_DCHECK(views_.find(view_id) != views_.end()); views_.erase(view_id); @@ -654,7 +654,7 @@ std::chrono::nanoseconds FlutterWindowsEngine::FrameInterval() { } FlutterWindowsView* FlutterWindowsEngine::view(FlutterViewId view_id) const { - fml::SharedLock read_lock{*views_mutex_}; + std::shared_lock read_lock(views_mutex_); auto iterator = views_.find(view_id); if (iterator == views_.end()) { @@ -884,7 +884,7 @@ bool FlutterWindowsEngine::DispatchSemanticsAction( void FlutterWindowsEngine::UpdateSemanticsEnabled(bool enabled) { if (engine_ && semantics_enabled_ != enabled) { - fml::SharedLock read_lock{*views_mutex_}; + std::shared_lock read_lock(views_mutex_); semantics_enabled_ = enabled; embedder_api_.UpdateSemanticsEnabled(engine_, enabled); @@ -951,7 +951,7 @@ void FlutterWindowsEngine::OnQuit(std::optional hwnd, } void FlutterWindowsEngine::OnDwmCompositionChanged() { - fml::SharedLock read_lock{*views_mutex_}; + std::shared_lock read_lock(views_mutex_); for (auto iterator = views_.begin(); iterator != views_.end(); iterator++) { iterator->second->OnDwmCompositionChanged(); @@ -987,7 +987,7 @@ bool FlutterWindowsEngine::Present(const FlutterPresentViewInfo* info) { // This runs on the raster thread. Lock the views map for the entirety of the // present operation to block the platform thread from destroying the // view during the present. - fml::SharedLock read_lock{*views_mutex_}; + std::shared_lock read_lock(views_mutex_); auto iterator = views_.find(info->view_id); if (iterator == views_.end()) { diff --git a/engine/src/flutter/shell/platform/windows/flutter_windows_engine.h b/engine/src/flutter/shell/platform/windows/flutter_windows_engine.h index c0f4185be0..2d7b730580 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_windows_engine.h +++ b/engine/src/flutter/shell/platform/windows/flutter_windows_engine.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -16,7 +17,6 @@ #include "flutter/fml/closure.h" #include "flutter/fml/macros.h" -#include "flutter/fml/synchronization/shared_mutex.h" #include "flutter/shell/platform/common/accessibility_bridge.h" #include "flutter/shell/platform/common/app_lifecycle_state.h" #include "flutter/shell/platform/common/client_wrapper/binary_messenger_impl.h" @@ -384,7 +384,7 @@ class FlutterWindowsEngine { // The platform thread acquires a shared lock to access the view. // The platform thread acquires an exclusive lock before adding // a view to the engine or after removing a view from the engine. - std::unique_ptr views_mutex_; + mutable std::shared_mutex views_mutex_; // Task runner for tasks posted from the engine. std::unique_ptr task_runner_;