From be022b610f23c252ca6601ab43c1624e742b5a5c Mon Sep 17 00:00:00 2001 From: Relintai Date: Thu, 6 Jul 2023 21:17:13 +0200 Subject: [PATCH] Bind RWLock, so it's accessible to scripts. --- core/bind/core_bind.cpp | 36 +++++++++++++++++++++++ core/bind/core_bind.h | 18 ++++++++++++ core/register_core_types.cpp | 1 + doc/classes/RWLock.xml | 57 ++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 doc/classes/RWLock.xml diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index ecc4da1ea..98d2952e7 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -2712,6 +2712,42 @@ void _Mutex::_bind_methods() { /////////////// +void _RWLock::read_lock() { + rw_lock.read_lock(); +} + +Error _RWLock::read_try_lock() { + return rw_lock.read_try_lock(); +} + +void _RWLock::read_unlock() { + rw_lock.read_unlock(); +} + +void _RWLock::write_lock() { + rw_lock.write_lock(); +} + +Error _RWLock::write_try_lock() { + return rw_lock.write_try_lock(); +} + +void _RWLock::write_unlock() { + rw_lock.write_unlock(); +} + +void _RWLock::_bind_methods() { + ClassDB::bind_method(D_METHOD("read_lock"), &_RWLock::read_lock); + ClassDB::bind_method(D_METHOD("read_unlock"), &_RWLock::read_unlock); + ClassDB::bind_method(D_METHOD("read_try_lock"), &_RWLock::read_try_lock); + + ClassDB::bind_method(D_METHOD("write_lock"), &_RWLock::write_lock); + ClassDB::bind_method(D_METHOD("write_unlock"), &_RWLock::write_unlock); + ClassDB::bind_method(D_METHOD("write_try_lock"), &_RWLock::write_try_lock); +} + +/////////////// + void _Thread::_start_func(void *ud) { Ref<_Thread> *tud = (Ref<_Thread> *)ud; Ref<_Thread> t = *tud; diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index edb312a58..4df0c88bc 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -38,6 +38,7 @@ #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" +#include "core/os/rw_lock.h" #include "core/os/safe_refcount.h" #include "core/os/semaphore.h" #include "core/os/thread.h" @@ -699,6 +700,23 @@ public: void unlock(); }; +class _RWLock : public Reference { + GDCLASS(_RWLock, Reference); + + RWLock rw_lock; + + static void _bind_methods(); + +public: + void read_lock(); + void read_unlock(); + Error read_try_lock(); + + void write_lock(); + void write_unlock(); + Error write_try_lock(); +}; + class _Semaphore : public Reference { GDCLASS(_Semaphore, Reference); Semaphore semaphore; diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index aa86d9e8a..8eb9e389c 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -206,6 +206,7 @@ void register_core_types() { ClassDB::register_class<_Directory>(); ClassDB::register_class<_Thread>(); ClassDB::register_class<_Mutex>(); + ClassDB::register_class<_RWLock>(); ClassDB::register_class<_Semaphore>(); ClassDB::register_class(); diff --git a/doc/classes/RWLock.xml b/doc/classes/RWLock.xml new file mode 100644 index 000000000..7a3d1463f --- /dev/null +++ b/doc/classes/RWLock.xml @@ -0,0 +1,57 @@ + + + + A Read Write Lock. + + + A Read Write Lock. This is used to synchronize multiple [Thread]s. This guarantees that only one thread can ever acquire the write lock at a time, and gives any number of threads read access in the meantime. An RWLock can be used to protect a critical section; however, be careful to avoid deadlocks. + + + + + + + + Locks this [RWLock] for read access, blocks until it is unlocked by the current owner. + [b]Note:[/b] This function returns without blocking if the thread already has ownership of the rwlock. + + + + + + Tries locking this [RWLock] for read access, but does not block. Returns [constant OK] on success, [constant ERR_BUSY] otherwise. + [b]Note:[/b] This function returns [constant OK] if the thread already has ownership of the rwlock. + + + + + + Unlocks this [RWLock] for read access, leaving it to other threads. + [b]Note:[/b] If a thread called [method lock] or [method try_lock] multiple times while already having ownership of the rwlock, it must also call [method unlock] the same number of times in order to unlock it correctly. + + + + + + Locks this [RWLock] for write access, blocks until it is unlocked by the current owner. + [b]Note:[/b] This function returns without blocking if the thread already has ownership of the rwlock. + + + + + + Tries locking this [RWLock] for write access, but does not block. Returns [constant OK] on success, [constant ERR_BUSY] otherwise. + [b]Note:[/b] This function returns [constant OK] if the thread already has ownership of the rwlock. + + + + + + Unlocks this [RWLock] for write access, leaving it to other threads. + [b]Note:[/b] If a thread called [method lock] or [method try_lock] multiple times while already having ownership of the rwlock, it must also call [method unlock] the same number of times in order to unlock it correctly. + + + + + +