1
0
Fork 0

VRManager: Fix crash on exit on Windows

VRManager::instance() was using a function scoped static osg::ref_ptr to
store the VRManager instance. However it needs to be used from
fgOSCloseWindow(), which is called from an atexit handler, and C++11
specifies that static object destruction and atexit handlers are reverse
sequenced, i.e. a static object initialised after an atexit call will be
destroyed before the atexit callback is called.

On Windows this can result in the osg::ref_ptr being destroyed (and
hence set to NULL) before fgOSCloseWindow() tries to call
destroyAndWait() on the instance.

Fix the resulting seg fault by moving the ref_ptr object to static file
scope so it is default constructed before the atexit call, and using
only a simple static bool to initialise it on first call to
VRManager::instance().

Reported-by: Alan Teeder <ajteeder@v-twin.org.uk>
This commit is contained in:
James Hogan 2022-08-29 21:54:09 +01:00
parent e85e5d2e5b
commit 91ddbf6a7c
No known key found for this signature in database
GPG key ID: 35CEE4862B1023F2

View file

@ -29,6 +29,11 @@
namespace flightgear namespace flightgear
{ {
// Unfortunately, this can't be scoped inside VRManager::instance().
// If its initialisation completes after main() calls atexit(fgExitCleanup),
// then its destruction should take place before fgExitCleanup() is called.
static osg::ref_ptr<VRManager> managerInstance;
VRManager::VRManager() : VRManager::VRManager() :
_reloadCompositorCallback(new ReloadCompositorCallback(this)), _reloadCompositorCallback(new ReloadCompositorCallback(this)),
_propXrLayersValidation("/sim/vr/openxr/layers/validation"), _propXrLayersValidation("/sim/vr/openxr/layers/validation"),
@ -88,8 +93,12 @@ VRManager::VRManager() :
VRManager *VRManager::instance() VRManager *VRManager::instance()
{ {
static osg::ref_ptr<VRManager> single = new VRManager; static bool initialised = false;
return single; if (!initialised) {
managerInstance = new VRManager;
initialised = true;
}
return managerInstance;
} }
void VRManager::syncProperties() void VRManager::syncProperties()