context: ENG-2139
The flag will allow indicating (while executing task) that the task should be canceled (because e.g. clearing the database was scheduled).
Differential D5576
[native] introduce atomic flag that indicates clearing database process will execute kamil on Nov 9 2022, 2:50 AM. Authored by Tags None Referenced Files
Details context: ENG-2139 The flag will allow indicating (while executing task) that the task should be canceled (because e.g. clearing the database was scheduled).
Diff Detail
Event TimelineComment Actions Unrelated to this diff, but wondering: why does Android initiate multithreadingEnabled(true) but iOS does multithreadingEnabled(false)? Comment Actions I had discussion about this with @tomek at the initial stage of work on GlobalDBSingleton. Before introduction of GlobalDBSingleton application created a dedicated database thread when CommCoreModule was created - when application foregrounded and started JavaScript thread. GlobalDBSingleton is meant to provide single threaded access to database not only when it is foregrounded but also in the background in response to notifications. One idea was to create dedicated database thread from the beginning of application existence. This would mean that if the application is started by the system to respond to notification we would create new thread (dedicated database thread). We didn't see it to be an issue on Android, however I was told that it might be an issue on iOS. Apple might detect that we create additional thread (use more resources) to respond to notification and send them less frequently. Therefore we decided, that GlobalDBSingleton will create dedicated database thread from the beginning on Android and only after JavaScript starts (CommCoreModule is created) on iOS. On iOS before JavaScript starts every database task is asynchronously dispatched on the application's main thread queue (main thread will execute it).
Comment Actions Thanks for explaining, @marcin!
Comment Actions Haven't worked with std::atomic before so will need to do some reading up before reviewing this... but based on the C++ book I've been using as a reference:
So we should probably be very careful with whatever we do here. Comment Actions Is there a reason we can't use std::mutex and std::lock_guard instead? That's a pattern we use elsewhere in the codebase and more importantly std::mutex + lock-based synchronization is something I understand in much more depth than lock-free concurrency... Comment Actions Can you explain how/where/when the value of tasksCancelled will be consumed?
Comment Actions Honestly, I think that mutexes are more complicated and error-prone than atomic variables. Designing a lock-free solution is indeed complicated, but in our case we don't need synchronization, but only visibility so it's a lot easier. Using mutexes will be huge overkill when the only thing we need is for one thread to see an update that other thread might have done. So basically, our goal is to avoid data races https://en.cppreference.com/w/cpp/language/memory_model.
Comment Actions
Comment Actions I've discussed this change with @tomek but sharing what we established. @atul and @ashoat fairly pointed problem with the previous solution, here is the vulnerable scenario:
to avoid this the flag is not set to false after task execution directly but setting the flag is scheduled as another non-cancellable task which means it will set the flag after execution of second`clearSensitiveData` in the previous example.
we don not consider this as bug, what is more it will cause that tasks already scheduled in queue will not be cancelled. We can add this additionally but I don't think there is a need to do it. |