-
Notifications
You must be signed in to change notification settings - Fork 1.3k
OfflineMapManager is crashing on serial queue access #15536
Comments
@racer1988 thanks for the report. A few comments/questions:
/cc @jmkiley |
@julianrex Good questions! I'll give the best answers I have at the moment:
|
Re 3. - I'm able to reproduce a similar crash, and am investigating solutions. Stay tuned. |
I suspect what's happening in your crash is that an In your scenario I would to do two things:
|
@julianrex Ok Thanks. I know the singleton is not thread safe, however it adds a huge layer of complexity as everything is a "race condition" coming either with KVO or notifications while I might be iterating on the packs. I understand the need of this but I wonder if accessing am invalid pack or removing a invalid pack and similar scenarios wouldn't be better handled with a This way if there is some sort of reloadPacks in the middle of my iteration (caused by something else) I could still safely fallback to do nothing on that pack and avoid a user crash. The main problematic thing for me is the |
by the way all of my operations are run after the first load of packs in KVO (I use that to trigger the cleanup section) (so on keyPath packs change (NSKeyValueChange.settings)) |
Yep, since mapbox-gl-native/platform/darwin/src/MGLOfflineStorage.mm Lines 313 to 317 in 5f1a062
Absolutely - we don't want it to crash! 😄 Fixing the crash is happening in #15582 - it won't trigger an exception (at the moment) given the current situation, however longer term I think that's the right thing to do. I think the solution here is to:
These three will be addressed in follow-on work from #15582. |
For tracking, here's a related ticket: #14206 |
Ah Thanks for the explanation. What I would think of: (I hope random brainstorming inputs are welcome 😄 )
combining the above together will make the database storage more thread-safe and probably avoid race conditions. EDIT: just saw your comment about #14206. If there is no other way to make thread safety a possibility (due to caching etc) maybe the entire storage should either be documented as mandatory to be called on the mainThread and raise exception if not) or should internally dispatch to it's own queue to ensure thread-safety. As with the points above and my previous comments, I am totally for removing the Every other interaction method with the storage (add, remove, invalidate) is already having a completionBlock. |
Always! As are PRs 😃
Yep, that's what I'm thinking. We already use this pattern elsewhere in the SDK so it's 👍.
This may not be necessary, though it could become a convenience property. Either way this may involve a SEMVER change, though ideally we could do the bulk of the changes without needing one. I added #15598 as a catchall ticket declaring our desire for refactoring - it'll make our testing more stable regardless. Re #14206 - I think this class should be able to be used from a background thread. At the moment it's precarious as you've found. Hopefully with the crash fixed, that'll get you closer to where you want to be. The refactoring is going to take a little longer. |
@julianrex I did move my entire implementation today to access all Due to the old implementation I have main Dispatch one inside the other, always to the main queue.. however I wanted to report that even this way I get the same crash. See below a screenshot of the same stack trace I reported before, but all coming from the main thread |
Yep, I think this is still to be expected. The crash will be fixed in #15582. |
Crash:
mbgl::DefaultFileSource::setOfflineRegionObserver(mbgl::OfflineRegion&, std::__1::unique_ptr<mbgl::OfflineRegionObserver, std::__1::default_delete<mbgl::OfflineRegionObserver> >) + 162
crash.txt
Hello,
in order to remove all packs that are not needed anymore, we use a serial queue to remove all packs as soon as the Mabbox DB is loaded.
so on
keyPath
packs
change (NSKeyValueChange.settings
)we dispatch to a
SerialQueue
and remove the pack one by one and wait for the first one to be completed before proceeding to reduce the load on the Database access.However this seems to crash for many users.
Could you help us out?
we know the storage is a singleton, there is any indications on thread-safety that we are not aware about?
is the singleton expecting to be accessed from the main thread or any other type of single thread-queue access?
Thanks
The text was updated successfully, but these errors were encountered: