Data races with rain intensity uniform set by sky and used by water

Currently we try to edit uniforms, already assigned to the stateset, in the SkyManager::update() and the MWShadowTechnique::cull(). It is not right since it is not safe to modify used statesets directly - the draw thread uses them too. Possible ways to avoid this issue:

  1. Mark such statesets as DYNAMIC
  2. Replace whole statsets
  3. Use the StateSetUpdater class

Usually we use the last approach in our codebase.

An example of race:

WARNING: ThreadSanitizer: data race (pid=30877)
  Write of size 4 at 0x7b30001139f0 by main thread (mutexes: write M1077058552368044424):
    #0 osg::Uniform::setElement(unsigned int, osg::Matrixd const&) <null> (libosg.so.156+0x127f8c)
    #1 osg::Uniform::set(osg::Matrixd const&) <null> (libosg.so.156+0x13163b)
    #2 SceneUtil::MWShadowTechnique::cull(osgUtil::CullVisitor&) /home/andrei/Downloads/openmw/components/sceneutil/mwshadowtechnique.cpp:1345 (openmw+0xc55627)
    #3 osgShadow::ShadowTechnique::traverse(osg::NodeVisitor&) <null> (libosgShadow.so.156+0x7665f)
    #4 osgShadow::ShadowedScene::traverse(osg::NodeVisitor&) <null> (libosgShadow.so.156+0x764be)
    #5 <null> <null> (libosgUtil.so.156+0x1bfc3f)
    #6 osgUtil::CullVisitor::apply(osg::Group&) <null> (libosgUtil.so.156+0x1c81da)
    #7 <null> <null> (libosgShadow.so.156+0x7add0)
    #8 osg::Group::traverse(osg::NodeVisitor&) <null> (libosg.so.156+0x239001)
    #9 <null> <null> (libosgUtil.so.156+0x1bfc3f)
    #10 osgUtil::CullVisitor::apply(osg::Group&) <null> (libosgUtil.so.156+0x1c81da)
    #11 <null> <null> (libosg.so.156+0x2ef907)
    #12 osg::Group::traverse(osg::NodeVisitor&) <null> (libosg.so.156+0x239001)
    #13 <null> <null> (libosgUtil.so.156+0x1bfc3f)
    #14 osgUtil::SceneView::cullStage(osg::Matrixd const&, osg::Matrixd const&, osgUtil::CullVisitor*, osgUtil::StateGraph*, osgUtil::RenderStage*, osg::Viewport*) <null> (libosgUtil.so.156+0xe07da)
    #15 osgUtil::SceneView::cull() <null> (libosgUtil.so.156+0xdd224)
    #16 osgViewer::Renderer::cull() <null> (libosgViewer.so.156+0xc089f)
    #17 osgViewer::ViewerBase::renderingTraversals() <null> (libosgViewer.so.156+0x7922c)
    #18 OMW::Engine::go() /home/andrei/Downloads/openmw/apps/openmw/engine.cpp:757 (openmw+0xb61b4e)
    #19 runApplication(int, char**) /home/andrei/Downloads/openmw/apps/openmw/main.cpp:260 (openmw+0xb45d17)
    #20 wrapApplication(int (*)(int, char**), int, char**, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/andrei/Downloads/openmw/components/debug/debugging.cpp:137 (openmw+0xd719ed)
    #21 main /home/andrei/Downloads/openmw/apps/openmw/main.cpp:272 (openmw+0x46d51c)

  Previous read of size 4 at 0x7b30001139f0 by thread T1:
    #0 <null> <null> (libosg.so.156+0x18189d)
    #1 <null> <null> (libosg.so.156+0x181d8f)
    #2 osg::State::apply(osg::StateSet const*) <null> (libosg.so.156+0x185185)
    #3 osgUtil::RenderLeaf::render(osg::RenderInfo&, osgUtil::RenderLeaf*) <null> (libosgUtil.so.156+0xe1f79)
    #4 osgUtil::RenderBin::drawImplementation(osg::RenderInfo&, osgUtil::RenderLeaf*&) <null> (libosgUtil.so.156+0xe43c3)
    #5 osgUtil::RenderBin::draw(osg::RenderInfo&, osgUtil::RenderLeaf*&) <null> (libosgUtil.so.156+0xe4f39)
    #6 osgUtil::RenderBin::drawImplementation(osg::RenderInfo&, osgUtil::RenderLeaf*&) <null> (libosgUtil.so.156+0xe4454)
    #7 osgUtil::RenderStage::drawImplementation(osg::RenderInfo&, osgUtil::RenderLeaf*&) <null> (libosgUtil.so.156+0xe4aa1)
    #8 osgUtil::RenderBin::draw(osg::RenderInfo&, osgUtil::RenderLeaf*&) <null> (libosgUtil.so.156+0xe4f39)
    #9 osgUtil::RenderStage::drawInner(osg::RenderInfo&, osgUtil::RenderLeaf*&, bool&) <null> (libosgUtil.so.156+0xe5c03)
    #10 osgUtil::RenderStage::draw(osg::RenderInfo&, osgUtil::RenderLeaf*&) <null> (libosgUtil.so.156+0xee7bc)
    #11 osgUtil::SceneView::draw() <null> (libosgUtil.so.156+0xd643b)
    #12 osgViewer::Renderer::draw() <null> (libosgViewer.so.156+0xc0485)
    #13 osgViewer::Renderer::operator()(osg::GraphicsContext*) <null> (libosgViewer.so.156+0xb378e)
    #14 osg::GraphicsContext::runOperations() <null> (libosg.so.156+0x2465f2)
    #15 osg::RunOperations::operator()(osg::GraphicsContext*) <null> (libosg.so.156+0x239082)
    #16 osg::GraphicsOperation::operator()(osg::Object*) <null> (libosg.so.156+0x2394c9)
    #17 osg::OperationThread::run() <null> (libosg.so.156+0x1df5fe)
    #18 osg::GraphicsThread::run() <null> (libosg.so.156+0x246f99)
    #19 OpenThreads::ThreadPrivateActions::StartThread(void*) <null> (libOpenThreads.so.21+0x6f5b)

  Location is heap block of size 184 at 0x7b3000113940 allocated by main thread:
    #0 operator new(unsigned long) /tmp/portage/sys-devel/gcc-8.2.0-r6/work/gcc-8.2.0/libsanitizer/tsan/tsan_new_delete.cc:42 (libtsan.so.0+0x7481a)
    #1 SceneUtil::MWShadowTechnique::cull(osgUtil::CullVisitor&) /home/andrei/Downloads/openmw/components/sceneutil/mwshadowtechnique.cpp:1341 (openmw+0xc55d14)
    #2 osgShadow::ShadowTechnique::traverse(osg::NodeVisitor&) <null> (libosgShadow.so.156+0x7665f)
    #3 osgShadow::ShadowedScene::traverse(osg::NodeVisitor&) <null> (libosgShadow.so.156+0x764be)
    #4 <null> <null> (libosgUtil.so.156+0x1bfc3f)
    #5 osgUtil::CullVisitor::apply(osg::Group&) <null> (libosgUtil.so.156+0x1c81da)
    #6 <null> <null> (libosgShadow.so.156+0x7add0)
    #7 osg::Group::traverse(osg::NodeVisitor&) <null> (libosg.so.156+0x239001)
    #8 <null> <null> (libosgUtil.so.156+0x1bfc3f)
    #9 osgUtil::CullVisitor::apply(osg::Group&) <null> (libosgUtil.so.156+0x1c81da)
    #10 <null> <null> (libosg.so.156+0x2ef907)
    #11 osg::Group::traverse(osg::NodeVisitor&) <null> (libosg.so.156+0x239001)
    #12 <null> <null> (libosgUtil.so.156+0x1bfc3f)
    #13 osgUtil::SceneView::cullStage(osg::Matrixd const&, osg::Matrixd const&, osgUtil::CullVisitor*, osgUtil::StateGraph*, osgUtil::RenderStage*, osg::Viewport*) <null> (libosgUtil.so.156+0xe07da)
    #14 osgUtil::SceneView::cull() <null> (libosgUtil.so.156+0xdd224)
    #15 osgViewer::Renderer::cull() <null> (libosgViewer.so.156+0xc089f)
    #16 osgViewer::ViewerBase::renderingTraversals() <null> (libosgViewer.so.156+0x7922c)
    #17 OMW::Engine::go() /home/andrei/Downloads/openmw/apps/openmw/engine.cpp:757 (openmw+0xb61b4e)
    #18 runApplication(int, char**) /home/andrei/Downloads/openmw/apps/openmw/main.cpp:260 (openmw+0xb45d17)
    #19 wrapApplication(int (*)(int, char**), int, char**, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/andrei/Downloads/openmw/components/debug/debugging.cpp:137 (openmw+0xd719ed)
    #20 main /home/andrei/Downloads/openmw/apps/openmw/main.cpp:272 (openmw+0x46d51c)
Edited by AnyOldName3