Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Uncaught exception starting MGLMapSnapshotter before using MGLMapView or MGLOfflineStorage #227

Closed
1ec5 opened this issue Mar 17, 2020 · 2 comments · Fixed by #259
Closed
Assignees
Labels
bug Something isn't working ios macOS

Comments

@1ec5
Copy link
Contributor

1ec5 commented Mar 17, 2020

If an application attempts to take a snapshot before ever initializing an MGLMapView or interacting with MGLOfflineStorage directly, -[MGLMapSnapshotter startWithQueue:overlayHandler:completionHandler:] raises an exception:

if (!mbgl::Scheduler::GetCurrent()) {
[NSException raise:NSInvalidArgumentException
format:@"startWithQueue:completionHandler: must be called from a thread with an active run loop."];
}

This check is premature, since the method soon afterwards causes MGLOfflineStorage to create an mbgl::util::RunLoop and various file sources on the current thread:

[self configureWithOptions:options];
auto mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource];
sharedOfflineStorage = [[self alloc] init];
static mbgl::util::RunLoop runLoop;

If we were to simply remove or defer this check, the check would pass even if starting the snapshotter on a background thread. However, the static mbgl::util::RunLoop intended for the main thread would be created for a background thread, which would lead to undefined behavior, for example when subsequently using MGLMapView.

Before #210, the same application didn’t trigger the exception because -[MGLMapSnapshotter initWithOptions:] happened to call -setOptions:, which called +[MGLOfflineStorage sharedOfflineStorage] before the run loop check. Even so, if a developer happened to initialize the snapshotter on a background thread, the static RunLoop intended for the main thread would’ve been created on the background thread.

One potential fix would be to call +[MGLOfflineStorage sharedOfflineStorage] in +[MGLMapSnapshotter initialize], but that could potentially impact startup time even in applications that don’t use MGLMapSnapshotter earlly on. Another fix would be to replace the existing check with one that explicitly raises an exception if it’s on a background thread but calls +[MGLOfflineStorage sharedOfflineStorage] if it’s on the main thread.

Thanks to @julianrex for spotting and helping to diagnose this issue.

/cc @mapbox/maps-ios @alexshalamov

@1ec5 1ec5 added bug Something isn't working ios macOS labels Mar 17, 2020
@1ec5 1ec5 added this to the release-vanillashake milestone Mar 17, 2020
@chloekraw
Copy link
Contributor

chloekraw commented Mar 27, 2020

@1ec5 @julianrex is this issue fixed with #317?

@1ec5
Copy link
Contributor Author

1ec5 commented Apr 6, 2020

No, that was a workaround in an internal testing repository. (The workaround is to call +[MGLOfflineStorage sharedOfflineStorage] pro forma before creating a snapshotter.)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working ios macOS
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants