Hi Pjotr,

On 27 October 2014 10:58, Pjotr Svetachov <[email protected]> wrote:

> As said we have multiple files that reference the same image for a
> texture, I have found two spots that can cause problems:
> - In InputStream::readImage(bool readFromExternal) at line 777 the program
> could get an image from the cache. After this it continues to read the
> image fields and set parameters. The most problematic is at like 784 where
> it will set the image filename, which is a string. This is not thread safe.
> Looking further it will call readObjectFields which will read the name and
> userdata and crash on that.
>

I've just read through the code, it certainly assumes that it's the only
thread writing to the image data, and doesn't account for the possibility
that when the osgDB::Registry object cache is active it is possible to
start modifying an image that is already been actively used by another
thread.  I expect this is something that Rui Wang didn't pick up as a
possibility when he originally wrote the serializers.

In the case when the image is shared it looks to me like the best approach
would be to not allow any additional modifications to the image by the
InputStream::readImage() method.  Even if you added mutex locks around the
write operations to the mutex you'd ended with an image that flips state
during it's lifetime so that the original owners of the image would then
have an Image in a new state that it doesn't have baring on what it was
originally.  This might be OK in some instances, but could cause real
problems for application/code that assumes the Image is invariant once it
has been set up.

Changing the behaviour to ignore the local modifications when an Image is
shared is something that might break applications too, but my instinct is
to treat Image as invariant once setup is the more common case so will
affect users left often than the current state.  Perhaps one possibility
would be to have a flag in InputStream to give a hint to what to do.

If we do ignore the extra write for Image's pulled from the cache we'd need
to still read then discard the options to avoid breaking file compatibility.

Another, more drastic workaround would be to duplicate the osg::Image from
the cache and let the new Image be modified.  This rather defaults the
purpose of using a cache though.

It's worth adding that this cached object issue will be a wider one that
just Image handling, so whatever solution we plump for we'll need to tackle
these other cases as well.


> - When a Texture2D is read it will call Texture2D::setImage and this
> function will call _image->addClient which can mess up the _numClients
> counter.
>
> The second problem can also appear while reading ive files.


I think this problem will be easier to resolve, changing the _numClients to
an osg::Atomic should probably be sufficient.

I will test this change right now to see if it has any effect on the
crashes I'm seeing.

Robert.
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to