mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:07:47 +00:00
LibThreading: Introduce MutexProtected generic synchronization primitive
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).
This commit is contained in:
parent
a7ce0c2297
commit
3d6e08156d
2 changed files with 75 additions and 2 deletions
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021, kleines Filmröllchen <malu.bertsch@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -7,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Format.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/Types.h>
|
||||
#include <pthread.h>
|
||||
|
@ -20,6 +22,7 @@ class Mutex {
|
|||
|
||||
public:
|
||||
Mutex()
|
||||
: m_lock_count(0)
|
||||
{
|
||||
#ifndef __serenity__
|
||||
pthread_mutexattr_t attr;
|
||||
|
@ -28,7 +31,11 @@ public:
|
|||
pthread_mutex_init(&m_mutex, &attr);
|
||||
#endif
|
||||
}
|
||||
~Mutex() = default;
|
||||
~Mutex()
|
||||
{
|
||||
VERIFY(m_lock_count == 0);
|
||||
// FIXME: pthread_mutex_destroy() is not implemented.
|
||||
}
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
@ -39,6 +46,7 @@ private:
|
|||
#else
|
||||
pthread_mutex_t m_mutex;
|
||||
#endif
|
||||
unsigned m_lock_count { 0 };
|
||||
};
|
||||
|
||||
class MutexLocker {
|
||||
|
@ -51,7 +59,10 @@ public:
|
|||
{
|
||||
lock();
|
||||
}
|
||||
ALWAYS_INLINE ~MutexLocker() { unlock(); }
|
||||
ALWAYS_INLINE ~MutexLocker()
|
||||
{
|
||||
unlock();
|
||||
}
|
||||
ALWAYS_INLINE void unlock() { m_mutex.unlock(); }
|
||||
ALWAYS_INLINE void lock() { m_mutex.lock(); }
|
||||
|
||||
|
@ -62,10 +73,16 @@ private:
|
|||
ALWAYS_INLINE void Mutex::lock()
|
||||
{
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
m_lock_count++;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void Mutex::unlock()
|
||||
{
|
||||
VERIFY(m_lock_count > 0);
|
||||
// FIXME: We need to protect the lock count with the mutex itself.
|
||||
// This may be bad because we're not *technically* unlocked yet,
|
||||
// but we're not handling any errors from pthread_mutex_unlock anyways.
|
||||
m_lock_count--;
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue