-
Notifications
You must be signed in to change notification settings - Fork 268
ref_ptr causes crash in multi-thread environment #1687
Description
Describe the bug
I've encountered a crash issue, and after investigation, I found it's related to incorrect reference counting of ref_ptr in a multi-threaded environment.
To Reproduce
Steps to reproduce the behavior:
Threads A and B will both reference and create ref_ptr for the target object named myObj, and then destroy the ref_ptrs they created after several steps.
The crash scenario can be chronologically simplified as follows:
- thread A, myObj->ref(), _referenceCount.fetch_add, then _referenceCount is 1.
- thread A, myObj->unref(), _referenceCount.fetch_sub, then _referenceCount is 0.
- thread B, myObj->ref(), _referenceCount.fetch_add, then _referenceCount is 1.
- thread A, myObj->unref(), attemptDelete, _ptr becomes a hang-pointer.
- thread B, using myObj, although its _referenceCount is not 0, its _ptr is a hang-pointer, CRASH!
Other scenerio
I've also encountered cases of incorrect object destruction. When I capture a ref_ptr by value in a lambda expression and add it to Viewer's update operation queue, there is a chance that the object managed by the ref_ptr is destructed before the lambda is executed. I think it is a same bug.
Expected behavior
If ref_ptr is enabled for multi-threaded environments, I think its reference counting operations should be thread-safe. We can use mutex or atomic operations (like Compare-And-Swap) to ensure that. And it would be more safe when Lambda functions capturing ref_ptr by value.