-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: add serial dispatch queue for storedCalls
to avoid data-race
#7480
Conversation
Accessing `storedCalls` from two different threads causes crash since `Dictionary` is not thread safe that introduces data-race. The serial queue prevents the access to the shared resource by two different threads by queuing the operation and invoking the functions one-by-one. There is other option to avoid data-race using lock, and there are two types of locks that can be used here `NSLock` and other one `OSAllocatedUnfairLock` that is faster than the first one.
We have a ConcurrentDictionary type that could be made |
I've got an implementation of the unfair lock using Here is the gist containing an implementation of the unfair lock. This gist also contains an implementation of |
I get that os_unfair_lock is more performant than NSLock, and I've seen and used the < iOS 16 implementations myself, but I made the conscious decision to not implement it that way in Capacitor because it's a bit of boiler plate that has to be maintained. Every maintainer on this project has varying levels of familiarity with Swift, so removing the need to juggle pointers and manual memory management, even if it is abstracted in such a way, is better to be avoided in my opinion. I find it doubtful that the impact on performance would be noticeable in a capacitor application. |
Originally, I fixed the problem using |
If ConcurrentDictionary solves the problem, lets use that. Otherwise |
We've to extend it to have some function for it to be fully compatible with the use case. Otherwise, we could add a single function that accepts a block, and you get full access to the object with a lock. |
Let's just add the single function that accepts the block, its simpler. |
What you plan to call that function? I've a few names from kotlin and other places like |
I personally like |
I've replaced the uses of the dispatch queue with the concurrent dictionary. |
Accessing
storedCalls
from two different threads causes crash sinceDictionary
is not thread safe that introduces data-race. The serial queue prevents the access to the shared resource by two different threads by queuing the operation and invoking the functions one-by-one.There is other option to avoid data-race using locks, and top of that, there are two types of locks that can be used here:
NSLock
and the other one isOSAllocatedUnfairLock
, which is faster than the first one.