godot icon indicating copy to clipboard operation
godot copied to clipboard

Implement `RecursiveRWLock` class and synchronization primitive.

Open radiantgurl opened this issue 9 months ago • 11 comments

closes https://github.com/godotengine/godot-proposals/issues/7423

radiantgurl avatar May 07 '24 21:05 radiantgurl

Actually, nvm, this looks ready! I'll be testing it out right now.

radiantgurl avatar May 07 '24 21:05 radiantgurl

Instead of rolling your own RW lock, it's probably better to use std::shared_mutex (like how Mutex is implemented via std::mutex in mutex.h).

timothyqiu avatar May 08 '24 00:05 timothyqiu

There is already the RWLock class in core/os/rw_lock.h for a shared read/write lock?

smix8 avatar May 08 '24 06:05 smix8

Instead of rolling your own RW lock, it's probably better to use std::shared_mutex (like how Mutex is implemented via std::mutex in mutex.h).

There is already the RWLock class in core/os/rw_lock.h for a shared read/write lock?

I agree with both, so I think this PR is not needed.

RandomShaper avatar May 08 '24 08:05 RandomShaper

Can this be added and fixed later...?

Instead of rolling your own RW lock, it's probably better to use std::shared_mutex (like how Mutex is implemented via std::mutex in mutex.h).

I have not used RWLock and std::shared_mutex due to the single fact they're not recursive.

radiantgurl avatar May 08 '24 12:05 radiantgurl

A few questions and thoughts:

  • The same way we have Mutex and BinaryMutex (recursive vs. non-recursive), the new class should have its name based on RWLock. Too late for BinaryRWLock, with RWLock being the new one, so I'd suggest RecursiveRWLock.
  • The new implementation is intended to avoid UB when trying to re-lock from the same thread. However, it still doesn't protect against re-locking in a different mode. To me, this implementation would only make sense if it avoids UB entirely.
  • Why a recursive RWLock is needed in the first place?
  • An alternative would be to write code so that RWLock can be used and add some checks to the debug version of it so it can detect misusages (similarly to what, e.g., Sempahore and Thread do).

RandomShaper avatar May 09 '24 12:05 RandomShaper

  • The same way we have Mutex and BinaryMutex (recursive vs. non-recursive), the new class should have its name based on RWLock. Too late for BinaryRWLock, with RWLock being the new one, so I'd suggest RecursiveRWLock.

Sure, why not.

  • The new implementation is intended to avoid UB when trying to re-lock from the same thread. However, it still doesn't protect against re-locking in a different mode. To me, this implementation would only make sense if it avoids UB entirely.

Sure, we'll fix that, however it will probably need using thread ids themselves.

  • Why a recursive RWLock is needed in the first place?

A recursive RWLock would provide better ways of being able to implement thread-safety. These don't have an use-case only in custom code, but may even open up a path to having SceneTree become thread-safe.

  • An alternative would be to write code so that RWLock can be used and add some checks to the debug version of it so it can detect misusages (similarly to what, e.g., Sempahore and Thread do).

I am unsure of what you mean.

radiantgurl avatar May 09 '24 16:05 radiantgurl

If two threads own read locks at the same time, then one gets a write lock (waiting for the other to release the read lock), and the other also wants the write lock, a deadlock will occur. (Any ways how to prevent/mitigate this? Maybe raise an error if this odd case happens? What should we do? How should we continue?)

EDIT: I found a way, i'll push after i'm done.

radiantgurl avatar May 10 '24 14:05 radiantgurl

Passed test

radiantgurl avatar May 10 '24 15:05 radiantgurl

Fixed a race condition.

radiantgurl avatar May 10 '24 16:05 radiantgurl

Status updates?

radiantgurl avatar Aug 17 '24 22:08 radiantgurl