Hi Rafa,

Thanks for the testing, sorry about the regression :-|

ffmpeg is be totally unrelated to how the proxy works in the new
serialization osg plugin, and the ObserverNodePath in this plugin
should be just an empty data structure and not difficult to destruct
safely.  So my guess is that the ffmpeg part of the equation is just
coincidence and it simply changes the order of events or memory usage
enough to change the working conditions enough to reveal an underlying
bug.

My best guess would be that global mutex that the ObserverNodePath is
trying to access has already been destructed (even though it shouldn't
be..) and this is causing the crash.  To test this theory out could
you try out the attached src/osg/ObserverNodePath.cpp that comments
out the clean up that will access the mutex.  This won't fix the bug
but will teach us a bit more about what might be going amiss.

Thanks,
Robert.


On Fri, Feb 19, 2010 at 7:34 AM, Rafa Gaitan <rafa.gai...@gmail.com> wrote:
> Hi Robert,
>
> Compiled fine on MacOSX Leopard using cmake, but when testing in one
> of my applications I get a crash when closing, this is the stack
> trace:
>
> Thread 0 Crashed:
> 0   libosg.63.dylib                     0x004f9f51
> osg::ObserverNodePath::~ObserverNodePath() + 33
> 1   libosg.63.dylib                     0x004f6b8e
> osg::NodeTrackerCallback::~NodeTrackerCallback() + 46
> 2   libosgDB.63.dylib                   0x0091b665
> osgDB::ObjectWrapper::~ObjectWrapper() + 533
> 3   libosgDB.63.dylib                   0x00916f30
> osgDB::RegisterWrapperProxy::~RegisterWrapperProxy() + 160
> 4   libSystem.B.dylib                   0x94ffcdbc __cxa_finalize + 241
> 5   libSystem.B.dylib                   0x94ffccb0 exit + 33
>
> Only occurs with somehing I have, involving ffmpeg imagestreams. Maybe
> is something I have in my side.. but I didn't had time to tested yet.
> Before the inclusion of the ObserverNodePath this was not happening.
> This is a SingleThreaded app.
>
> Rafa.
>
>
> On Fri, Feb 19, 2010 at 8:20 AM, Robert Osfield
> <robert.osfi...@gmail.com> wrote:
>> On Fri, Feb 19, 2010 at 6:04 AM, Maxim Gammer <maxgam...@gmail.com> wrote:
>>> Hi Robert,
>>>
>>> I upgrade to 2.9.7 in the next days....
>>
>> Which is rather too late for making sure svn/trunk is well tested
>> prior to me tagging 2.9.7... so if 2.9.7 contains problems that
>> weren't tested and reported prior to 2.9.7 then... it's because... you
>> hang back from testing.
>>
>> Please guys we need testing NOW.
>>
>> Robert.
>> _______________________________________________
>> osg-users mailing list
>> osg-users@lists.openscenegraph.org
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>
>
>
>
> --
> Rafael Gaitán Linares
> Instituto de Automática e Informática Industrial  http://www.ai2.upv.es
> http://gvsig3d.blogspot.com
> Ciudad Politécnica de la Innovación
> Universidad Politécnica de Valencia
> _______________________________________________
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osg/ObserverNodePath>
#include <osg/Notify>

using namespace osg;

ObserverNodePath::ObserverNodePath():
    _valid(false)
{
}

ObserverNodePath::ObserverNodePath(const ObserverNodePath& rhs):
    _valid(false)
{
    RefNodePath refNodePath;
    if (rhs.getRefNodePath(refNodePath))
    {
        setNodePath(refNodePath);
    }
}

ObserverNodePath::ObserverNodePath(const osg::NodePath& nodePath):
    _valid(false)
{
    setNodePath(nodePath);
}

ObserverNodePath::~ObserverNodePath()
{
    //clearNodePath();
}

ObserverNodePath& ObserverNodePath::operator = (const ObserverNodePath& rhs)
{
    if (&rhs==this) return *this;

    RefNodePath refNodePath;
    if (rhs.getRefNodePath(refNodePath))
    {
        setNodePath(refNodePath);
    }
    return *this;
}

void ObserverNodePath::setNodePathTo(osg::Node* node)
{
    if (node)
    {
        NodePathList nodePathList = node->getParentalNodePaths();
        if (nodePathList.empty())
        {
            NodePath nodePath;
            nodePath.push_back(node);
            setNodePath(nodePath);
        }
        else
        {
            if (nodePathList[0].empty())
            {
                nodePathList[0].push_back(node);
            }
            setNodePath(nodePathList[0]);
        }
    }
    else
    {
        clearNodePath();
    }
}

void ObserverNodePath::setNodePath(const osg::NodePath& nodePath)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*getObserverMutex());
    _setNodePath(nodePath);
}

void ObserverNodePath::setNodePath(const osg::RefNodePath& refNodePath)
{
    osg::NodePath nodePath;
    for(RefNodePath::const_iterator itr = refNodePath.begin(); itr != refNodePath.end(); ++itr)
    {
        nodePath.push_back(itr->get());
    }
    setNodePath(nodePath);
}

void ObserverNodePath::clearNodePath()
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*getObserverMutex());
    _clearNodePath();
}

bool ObserverNodePath::getRefNodePath(RefNodePath& refNodePath) const
{
    refNodePath.clear();

    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*getObserverMutex());
    if (!_valid) return false;

    for(osg::NodePath::const_iterator itr = _nodePath.begin();
        itr != _nodePath.end();
        ++itr)
    {
        refNodePath.push_back(*itr);
    }

    return true;
}

bool ObserverNodePath::getNodePath(NodePath& nodePath) const
{
    nodePath.clear();

    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*getObserverMutex());
    if (!_valid) return false;
    nodePath = _nodePath;
    return true;
}

void ObserverNodePath::_setNodePath(const osg::NodePath& nodePath)
{
    if (nodePath==_nodePath) return;

    _clearNodePath();

    //OSG_NOTICE<<"ObserverNodePath["<<this<<"]::_setNodePath() nodePath.size()="<<nodePath.size()<<std::endl;

    _nodePath = nodePath;

    for(osg::NodePath::iterator itr = _nodePath.begin();
        itr != _nodePath.end();
        ++itr)
    {
        //OSG_NOTICE<<"   addObserver("<<*itr<<")"<<std::endl;
        (*itr)->addObserver(this);
    }

    _valid = true;
}

void ObserverNodePath::_clearNodePath()
{
    //OSG_NOTICE<<"ObserverNodePath["<<this<<"]::_clearNodePath() _nodePath.size()="<<_nodePath.size()<<std::endl;
    for(osg::NodePath::iterator itr = _nodePath.begin();
        itr != _nodePath.end();
        ++itr)
    {
        //OSG_NOTICE<<"   removeObserver("<<*itr<<")"<<std::endl;
        (*itr)->removeObserver(this);
    }
    _nodePath.clear();
    _valid = false;
}

bool ObserverNodePath::objectUnreferenced(void* ptr)
{
    osg::Node* node = reinterpret_cast<osg::Node*>(ptr);

    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*getObserverMutex());

    _valid = false;

    for(osg::NodePath::iterator itr = _nodePath.begin();
        itr != _nodePath.end();
        ++itr)
    {
        if (*itr == node)
        {
            _nodePath.erase(itr);

            //OSG_NOTICE<<"ObserverNodePath["<<this<<"]::objectUnreferenced("<<ptr<<") found pointer in node path."<<std::endl;

            // return true as we wish calling method to remove self from observer set.
            return true;
        }
    }

    //OSG_NOTICE<<"Error: ObserverNodePath["<<this<<"]::::objectUnreferenced("<<ptr<<") could not find pointer in node path."<<std::endl;

    // return true as we wish calling method to remove self from observer set.
    return true;
}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to