mirror of
				https://github.com/LadybirdBrowser/ladybird.git
				synced 2025-10-27 10:29:23 +00:00 
			
		
		
		
	MutexProtected mirrors the identically-named Kernel primitive and can be used to synchronize access to any object that might not be thread safe on its own. Synchronization is done with a simple mutex, so access to a MutexProtected object is potentially blocking. Mutex now has an internal nesting variable which is there to harden it against lock-unlock ordering issues (e.g. double unlocking).
		
			
				
	
	
		
			56 lines
		
	
	
	
		
			1.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			56 lines
		
	
	
	
		
			1.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2022, kleines Filmröllchen <malu.bertsch@gmail.com>.
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <AK/Concepts.h>
 | |
| #include <AK/Noncopyable.h>
 | |
| #include <LibThreading/Mutex.h>
 | |
| 
 | |
| namespace Threading {
 | |
| 
 | |
| template<typename T>
 | |
| class MutexProtected {
 | |
|     AK_MAKE_NONCOPYABLE(MutexProtected);
 | |
|     AK_MAKE_NONMOVABLE(MutexProtected);
 | |
|     using ProtectedType = T;
 | |
| 
 | |
| public:
 | |
|     ALWAYS_INLINE MutexProtected() = default;
 | |
|     ALWAYS_INLINE MutexProtected(T&& value)
 | |
|         : m_value(move(value))
 | |
|     {
 | |
|     }
 | |
|     ALWAYS_INLINE explicit MutexProtected(T& value)
 | |
|         : m_value(value)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     template<typename Callback>
 | |
|     decltype(auto) with_locked(Callback callback)
 | |
|     {
 | |
|         auto lock = this->lock();
 | |
|         // This allows users to get a copy, but if we don't allow references through &m_value, it's even more complex.
 | |
|         return callback(m_value);
 | |
|     }
 | |
| 
 | |
|     template<VoidFunction<T> Callback>
 | |
|     void for_each_locked(Callback callback)
 | |
|     {
 | |
|         with_locked([&](auto& value) {
 | |
|             for (auto& item : value)
 | |
|                 callback(item);
 | |
|         });
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     [[nodiscard]] ALWAYS_INLINE MutexLocker lock() { return MutexLocker(m_lock); }
 | |
| 
 | |
|     T m_value;
 | |
|     Mutex m_lock {};
 | |
| };
 | |
| 
 | |
| }
 |