1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 21:23:52 +00:00

Replace raw pointer by observer_ptr to avoid dangling pointer dereferencing

When game exit is requests when initial loading screen is active LightManager
can be destructed in the main thread before LightManagerStateAttribute::apply
is completed by different thread. Given that it uses raw pointer at some point
it becomes dangling because object is destructed this leads to UB and eventual
SIGSEGV.
This commit is contained in:
elsid 2021-05-15 12:36:37 +02:00
parent 5d83de189a
commit 5373cf1cd5
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40

View file

@ -731,7 +731,7 @@ namespace SceneUtil
META_StateAttribute(NifOsg, LightManagerStateAttribute, osg::StateAttribute::LIGHT) META_StateAttribute(NifOsg, LightManagerStateAttribute, osg::StateAttribute::LIGHT)
void initSharedLayout(osg::GLExtensions* ext, int handle) const void initSharedLayout(osg::GLExtensions* ext, int handle, LightManager& lightManager) const
{ {
constexpr std::array<unsigned int, 1> index = { static_cast<unsigned int>(Shader::UBOBinding::LightBuffer) }; constexpr std::array<unsigned int, 1> index = { static_cast<unsigned int>(Shader::UBOBinding::LightBuffer) };
int totalBlockSize = -1; int totalBlockSize = -1;
@ -753,13 +753,17 @@ namespace SceneUtil
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
{ {
auto& buf = mLightManager->getLightBuffer(i); auto& buf = lightManager.getLightBuffer(i);
buf->configureLayout(offsets[0], offsets[1], offsets[2], totalBlockSize, stride); buf->configureLayout(offsets[0], offsets[1], offsets[2], totalBlockSize, stride);
} }
} }
void apply(osg::State& state) const override void apply(osg::State& state) const override
{ {
osg::ref_ptr<LightManager> lightManager;
if (!mLightManager.lock(lightManager))
return;
if (!mInitLayout) if (!mInitLayout)
{ {
mDummyProgram->apply(state); mDummyProgram->apply(state);
@ -772,12 +776,12 @@ namespace SceneUtil
// wait until the UBO binding is created // wait until the UBO binding is created
if (activeUniformBlocks > 0) if (activeUniformBlocks > 0)
{ {
initSharedLayout(ext, handle); initSharedLayout(ext, handle, *lightManager);
mInitLayout = true; mInitLayout = true;
} }
} }
mLightManager->getLightBuffer(state.getFrameStamp()->getFrameNumber())->uploadCachedSunPos(state.getInitialViewMatrix()); lightManager->getLightBuffer(state.getFrameStamp()->getFrameNumber())->uploadCachedSunPos(state.getInitialViewMatrix());
mLightManager->getLightBuffer(state.getFrameStamp()->getFrameNumber())->dirty(); lightManager->getLightBuffer(state.getFrameStamp()->getFrameNumber())->dirty();
} }
private: private:
@ -807,7 +811,7 @@ namespace SceneUtil
return shader; return shader;
} }
LightManager* mLightManager; osg::observer_ptr<LightManager> mLightManager;
osg::ref_ptr<osg::Program> mDummyProgram; osg::ref_ptr<osg::Program> mDummyProgram;
mutable bool mInitLayout; mutable bool mInitLayout;
}; };