Re: [osg-users] Text Crash On Main Thread While DB Pager Unrefs Font From Temp Object Cache

2009-12-16 Thread Robert Osfield
Hi Ryan,

On Wed, Dec 16, 2009 at 9:43 AM, Ryan H. Kawicki
 wrote:
> It might not be convincing to have to go back to the code base and remove 
> these unsafe sections of code, but by having a set of documentation is really 
> not going to help eighty or ninety percent of the OSG community.  I rarely 
> look at the documentation.  My documentation is really just the source code 
> that is provided.  With multiple cores available on the cheap and new and old 
> applications requiring database support, I feel that it is in the best 
> interest of OSG to have these functions removed.  It will save for headaches 
> in the long run for you, as you will not have to explain each and every time 
> to use the ref version instead of the other.

I understand the principle of short term pain for long term gain...  but...

In the current case I'm looking towards getting the OSG users moving
on to the upcoming 3.0, during this transition their will inevitably
be some refactor work required by users due to the wider changes such
as GLES/GL3 support, but the more pain there is the slower the uptake
will be and the slower we'll sort out all the bugs/issues.  In this
context I want to minimize how much more pain we might introduce.  The
less pain the quicker people will try out and move to OSG 3.x and the
quicker it's quality will improve.

So right now I don't want to add any further backwards compatibility
breakages if I can avoid it.

>> The cache flipping trick used is not good needs to be removed. I'd be
>> inclined towards use osgDB::Options to store the cache, and have an in
>> memory ObjectCache to mirror the current FileCache. Such an approach
>> would allow you to override the default ObjectCache to a single read
>> call, such as ones done from the DatabasePager and avoid the need to
>> cache flipping completely.
>>
>
> Are there plans for this to be addressed for a future release?  If so, can 
> you detail which release you are trying to target?

I don't have any specific version for this.  It's an issue right now
and should be fixed a soon as I or others have time to tackle it.  I
would guess that it's a day or two's work.

Robert.
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Text Crash On Main Thread While DB Pager Unrefs Font From Temp Object Cache

2009-12-16 Thread Ryan H. Kawicki

> 
> More generally I'm not convinced that we need to deprecate the none
> ref versions. I'd be inclined towards just documenting that
> multi-threaded reads should use the Ref versions.
> 


It might not be convincing to have to go back to the code base and remove these 
unsafe sections of code, but by having a set of documentation is really not 
going to help eighty or ninety percent of the OSG community.  I rarely look at 
the documentation.  My documentation is really just the source code that is 
provided.  With multiple cores available on the cheap and new and old 
applications requiring database support, I feel that it is in the best interest 
of OSG to have these functions removed.  It will save for headaches in the long 
run for you, as you will not have to explain each and every time to use the ref 
version instead of the other.


> 
> The cache flipping trick used is not good needs to be removed. I'd be
> inclined towards use osgDB::Options to store the cache, and have an in
> memory ObjectCache to mirror the current FileCache. Such an approach
> would allow you to override the default ObjectCache to a single read
> call, such as ones done from the DatabasePager and avoid the need to
> cache flipping completely.
> 


Are there plans for this to be addressed for a future release?  If so, can you 
detail which release you are trying to target?

Thanks,
Ryan

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=21553#21553





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Text Crash On Main Thread While DB Pager Unrefs Font From Temp Object Cache

2009-12-14 Thread Robert Osfield
Hi Ryan,

On Mon, Dec 14, 2009 at 10:38 AM, Ryan H. Kawicki
 wrote:
> Observation 1:
> Using the unsafe versions is bad.  Now we know and knowing is half the 
> battler, but should this be take further.  It might be a good idea to tag the 
> unsafe versions as deprecated, this way a compiler warning can be generated.  
> This can be rolled into the 2.10 release of OSG.  I would then say that a 
> version of two later, they can be removed all together.

Within the OSG we should certainly move across to use the ref versions
internally in NodeKits and plugins.

More generally I'm not convinced that we need to deprecate the none
ref versions.  I'd be inclined towards just documenting that
multi-threaded reads should use the Ref versions.

> Observation 2:
> It looks like if you mix cached and uncached operations on different threads, 
> this is the chance that cached objects will be lost by the registry.  I'm not 
> sure how to overcome this issue, and this issue might need a more trained eye 
> and someone with greater knowledge of OSGs internal workings.  I'll leave 
> that up to you and the community to decide this one.

The cache flipping trick used is not good needs to be removed.  I'd be
inclined towards use osgDB::Options to store the cache, and have an in
memory ObjectCache to mirror the current FileCache.  Such an approach
would allow you to override the default ObjectCache to a single read
call, such as ones done from the DatabasePager and avoid the need to
cache flipping completely.

> Observation 3:
> I did try to read osgText::Font objects using a noncached call, but this was 
> a very bad thing to do.  It basically made our entire terrain page in bad 
> texture data.  I'm not sure what the problem was there, but our terrain was 
> paging in with some pink textures.  In any case, I did notice something quite 
> strange or even bad.  When caching of the font objects was off, calling to 
> read the font object internally was caching this data in 
> FreeTypeLibrary::getFont.  The _fontImplementationSet continually was growing 
> and growing.  With caching turned on, the _fontImplementationSet averaged 
> around nine objects, with some of them being the same.  I can only surmise 
> that this was due to the object cache problem I described above and would 
> fall to the same fate as using the noncached version.  In any case, I wanted 
> to point this out, as there might be some optimizations that can be placed 
> here.

Font's really do need to be cached and shared between instanced,
perhaps it even warrant's it's own separate ObjectCache?

Robert.
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Text Crash On Main Thread While DB Pager Unrefs Font From Temp Object Cache

2009-12-14 Thread Ryan H. Kawicki
Robert,

I just wanted to respond with my investigations and observations.


> 
> I sounds like the lack of a readRefFontFile() is a potential problem.
> In the case of include/osgDB/ReadFile there are readRefNodeFile() etc.
> functions that pass back a ref_ptr<> rather than a C pointer, and are
> all safer in multi-thread situations where object cache is in play.
> Could you try implementing a readRefFontFile() and convert osgText
> across to use this to see if it helps.
> 


So, I am mistaken and there is a readRefFontFile already implemented.  All I 
needed to do was look a few lines down.  I've changed my code to use this 
function instead and it seems to have solved the issue at hand.  I will go into 
more detail about this, as I've done some really deep digging into this

There are a few places that should more than likely be changed within OSG.  
TXPArchive.cpp and ScalarBar.cpp both use the unsafe version.  It will more 
than like be quicker for you to fix this issue than for me to submit source to 
the submission.  I'll just leave that one up to you.

Investigation:
So, I dug into this problem almost all day on Saturday.  I think I have a good 
understanding of what this problem is.  I also believe that there is another 
problem that needs to be addressed.  More to come on that.

In our application, we have a database pager thread that is requesting node 
files in a non-cached manner.  On our main thread, when requesting a 
osgText::Font object, the underlying function is requesting these objects to be 
cached.  I'm posting the Registry::readImplementation below for quick reference.

So, lets say that our database pager has some requests.  No remember that these 
requests are not going to be cached.  Once the Registry::readImplementation 
function is reached, the else portion of the if/else statement is executed.  
This portion of the code takes all objects in the _objectCache and swaps it 
with a temporary local object cache.

Now, lets assume that the database pager is busy at work bringing in a new node 
of data.  The temporary data is all setup and the database pager is happily in 
the readFunctor.  Now, the main thread decides to request a font object.  With 
the database pager still in the readFunctor, the font object is able to get 
inside of the if portion of the if/else statement.  The object is inserted into 
the _objectCache and happily moves on.  As the main thread continues back down 
the stack, one of the function reached first before getting to 
osgText::readFontFile is osgDB::readObjectFile.  This function basically calls 
takeObject on the read results object, which basically adds then subtracts a 
reference from the returning object.  The point I want to make is that the 
reference is 1.  At this point, the stack is unwound a bit further to the 
original calling function.  It has a pure pointer and passes that along to the 
osgText::setFont function.

Lets say that the database pager was finally able to return from doing its read 
somewhere between the main threads execution of Registry::readImplementation 
and osgText::setFont.  Now, the database pager had done a swap of data on the 
_objectCache and the temporary object cache.  Now this means that the data in 
_objectCache belongs to whatever was swapped in from the temporary object cache 
of the database pager thread.  The main thread decided to load some data and 
cache the results.  This data is now in the _objectCache, which belongs to the 
temporary cache of the database pager.  When the database pager returns, it 
swaps again the two pointers.  Now, the temporary cache contains the newly 
cached object and the _objectCache contains nothing.  We can see where this is 
going to lead.  As the temporary cache is destructed, the stored objects, our 
font object, gets unreferenced.  This makes for a sad story when trying to 
access this data later.


Code:

ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& 
readFunctor, bool useObjectCache)
{
std::string file(readFunctor._filename);

if (useObjectCache)
{
// search for entry in the object cache.
{
OpenThreads::ScopedLock lock(_objectCacheMutex);
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<<"returning cached instanced of "second.first.get(), 
ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file does not 
contain an osg::Object");
}
}

ReaderWriter::ReadResult rr = read(readFunctor);
if (rr.validObject()) 
{
// update cache with new entry.
notify(INFO)<<"Adding to object cache "< lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}

ReaderWriter::ReadResult rr = read(readFun

Re: [osg-users] Text Crash On Main Thread While DB Pager Unrefs Font From Temp Object Cache

2009-12-12 Thread Ryan Surkamp
Is it possible for the database pager thread to switch the cache to a temp
cache, and then another thread comes in and thinks that temp cache is the
actual cache?  So when the database pager swaps the cache again, then that
ref_ptr in the tmp cache is destroyed? the other thread continues on
thinking the cache wasn't a temporary one.

Could get into a situation where multiple threads are switching the caches,
then the main cache may not be restored?



On Fri, Dec 11, 2009 at 7:53 AM, Robert Osfield wrote:

> Hi Ryan,
>
> I sounds like the lack of a readRefFontFile() is a potential problem.
> In the case of include/osgDB/ReadFile there are readRefNodeFile() etc.
> functions that pass back a ref_ptr<> rather than a C pointer, and are
> all safer in multi-thread situations where object cache is in play.
> Could you try implementing a readRefFontFile() and convert osgText
> across to use this to see if it helps.
>
> Cheers,
> Robert.
>
> On Fri, Dec 11, 2009 at 1:04 PM, Ryan H. Kawicki
>  wrote:
> > I've been investigating a crash that has plagued us for quite some time.
>  I've finally gotten some time to sit down and take a look at this.
> >
> > Details:
> > OSG: 2.8.1
> > OS: WinXP SP3 32Bit
> > CPU: 8 Core 2.5GHz Xenon
> > Graphics: Quadro FX 3700 512 MB
> > Memory: Plenty
> >
> > Description:
> > Our application embeds OSG into two views.  There are multiple threads at
> work here, but the two of importance are the Map thread and the
> DatabasePager thread.
> >
> > At certain points during the execution of our application, the Map thread
> will be given a request to create an osgText object.  One of the operations
> is to request a font for the osgText object.  At this point we call down
> into osgText::readFontFile( ... ).
> >
> > At this same time, the database pager is hard at work reading paged files
> from disk on its own thread.  At some point, the database pager gets into
> Registry::readImplementation( ... ) and begins to copy the object cache to a
> temp object cache.  There is only one object in the cache and it is an
> osgText::Font object.  At some point during this stage, an unref of the
> object happens.  Here is where the oddity comes in.  When the object is
> getting unreferenced, the code checks to see if the object needs to be
> deleted.  For some odd reason this value is 0 on the DB thread but 2 on the
> Map thread.  When the Map thread tries to use the font object, it dies, as
> the DB thread has already released it.  I would give more details on this,
> but the computer I was working on did not come back from standby and
> everything I am stating is from memory.  Sorry.
> >
> > Question:
> > Now that we have gotten through that, the question I have is related to
> the implementation of osgText::readFontFile.  Would it not be safer to have
> this function use ref_ptr objects internally rather than standard pointers?
>  I'm quite confused as to the design decisions behind this and hope someone
> can help me here.
> >
> >
> > Code:
> >
> > osgText::Font* osgText::readFontFile(const std::string& filename, const
> osgDB::ReaderWriter::Options* userOptions)
> > {
> >if (filename=="") return 0;
> >
> >std::string foundFile = findFontFile(filename);
> >if (foundFile.empty()) return 0;
> >
> >OpenThreads::ScopedLock lock(s_FontFileMutex);
> >
> >osg::ref_ptr localOptions;
> >if (!userOptions)
> >{
> >localOptions = new osgDB::ReaderWriter::Options;
> >
>  
> localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS);
> >}
> >
> >osg::Object* object = osgDB::readObjectFile(foundFile, userOptions ?
> userOptions : localOptions.get());
> >
> >// if the object is a font then return it.
> >osgText::Font* font = dynamic_cast(object);
> >if (font) return font;
> >
> >// otherwise if the object has zero references then delete it by doing
> another unref().
> >if (object && object->referenceCount()==0) object->unref();
> >return 0;
> > }
> >
> >
> >
> >
> > Thanks,
> > Ryan
> >
> > --
> > Read this topic online here:
> > http://forum.openscenegraph.org/viewtopic.php?p=21314#21314
> >
> >
> >
> >
> >
> > ___
> > osg-users mailing list
> > osg-users@lists.openscenegraph.org
> >
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> >
> ___
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Text Crash On Main Thread While DB Pager Unrefs Font From Temp Object Cache

2009-12-11 Thread Robert Osfield
Hi Ryan,

I sounds like the lack of a readRefFontFile() is a potential problem.
In the case of include/osgDB/ReadFile there are readRefNodeFile() etc.
functions that pass back a ref_ptr<> rather than a C pointer, and are
all safer in multi-thread situations where object cache is in play.
Could you try implementing a readRefFontFile() and convert osgText
across to use this to see if it helps.

Cheers,
Robert.

On Fri, Dec 11, 2009 at 1:04 PM, Ryan H. Kawicki
 wrote:
> I've been investigating a crash that has plagued us for quite some time.  
> I've finally gotten some time to sit down and take a look at this.
>
> Details:
> OSG: 2.8.1
> OS: WinXP SP3 32Bit
> CPU: 8 Core 2.5GHz Xenon
> Graphics: Quadro FX 3700 512 MB
> Memory: Plenty
>
> Description:
> Our application embeds OSG into two views.  There are multiple threads at 
> work here, but the two of importance are the Map thread and the DatabasePager 
> thread.
>
> At certain points during the execution of our application, the Map thread 
> will be given a request to create an osgText object.  One of the operations 
> is to request a font for the osgText object.  At this point we call down into 
> osgText::readFontFile( ... ).
>
> At this same time, the database pager is hard at work reading paged files 
> from disk on its own thread.  At some point, the database pager gets into 
> Registry::readImplementation( ... ) and begins to copy the object cache to a 
> temp object cache.  There is only one object in the cache and it is an 
> osgText::Font object.  At some point during this stage, an unref of the 
> object happens.  Here is where the oddity comes in.  When the object is 
> getting unreferenced, the code checks to see if the object needs to be 
> deleted.  For some odd reason this value is 0 on the DB thread but 2 on the 
> Map thread.  When the Map thread tries to use the font object, it dies, as 
> the DB thread has already released it.  I would give more details on this, 
> but the computer I was working on did not come back from standby and 
> everything I am stating is from memory.  Sorry.
>
> Question:
> Now that we have gotten through that, the question I have is related to the 
> implementation of osgText::readFontFile.  Would it not be safer to have this 
> function use ref_ptr objects internally rather than standard pointers?  I'm 
> quite confused as to the design decisions behind this and hope someone can 
> help me here.
>
>
> Code:
>
> osgText::Font* osgText::readFontFile(const std::string& filename, const 
> osgDB::ReaderWriter::Options* userOptions)
> {
>    if (filename=="") return 0;
>
>    std::string foundFile = findFontFile(filename);
>    if (foundFile.empty()) return 0;
>
>    OpenThreads::ScopedLock lock(s_FontFileMutex);
>
>    osg::ref_ptr localOptions;
>    if (!userOptions)
>    {
>        localOptions = new osgDB::ReaderWriter::Options;
>        
> localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS);
>    }
>
>    osg::Object* object = osgDB::readObjectFile(foundFile, userOptions ? 
> userOptions : localOptions.get());
>
>    // if the object is a font then return it.
>    osgText::Font* font = dynamic_cast(object);
>    if (font) return font;
>
>    // otherwise if the object has zero references then delete it by doing 
> another unref().
>    if (object && object->referenceCount()==0) object->unref();
>    return 0;
> }
>
>
>
>
> Thanks,
> Ryan
>
> --
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=21314#21314
>
>
>
>
>
> ___
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


[osg-users] Text Crash On Main Thread While DB Pager Unrefs Font From Temp Object Cache

2009-12-11 Thread Ryan H. Kawicki
I've been investigating a crash that has plagued us for quite some time.  I've 
finally gotten some time to sit down and take a look at this.

Details:
OSG: 2.8.1
OS: WinXP SP3 32Bit
CPU: 8 Core 2.5GHz Xenon
Graphics: Quadro FX 3700 512 MB
Memory: Plenty

Description:
Our application embeds OSG into two views.  There are multiple threads at work 
here, but the two of importance are the Map thread and the DatabasePager thread.

At certain points during the execution of our application, the Map thread will 
be given a request to create an osgText object.  One of the operations is to 
request a font for the osgText object.  At this point we call down into 
osgText::readFontFile( ... ).

At this same time, the database pager is hard at work reading paged files from 
disk on its own thread.  At some point, the database pager gets into 
Registry::readImplementation( ... ) and begins to copy the object cache to a 
temp object cache.  There is only one object in the cache and it is an 
osgText::Font object.  At some point during this stage, an unref of the object 
happens.  Here is where the oddity comes in.  When the object is getting 
unreferenced, the code checks to see if the object needs to be deleted.  For 
some odd reason this value is 0 on the DB thread but 2 on the Map thread.  When 
the Map thread tries to use the font object, it dies, as the DB thread has 
already released it.  I would give more details on this, but the computer I was 
working on did not come back from standby and everything I am stating is from 
memory.  Sorry.

Question:
Now that we have gotten through that, the question I have is related to the 
implementation of osgText::readFontFile.  Would it not be safer to have this 
function use ref_ptr objects internally rather than standard pointers?  I'm 
quite confused as to the design decisions behind this and hope someone can help 
me here.


Code:

osgText::Font* osgText::readFontFile(const std::string& filename, const 
osgDB::ReaderWriter::Options* userOptions)
{
if (filename=="") return 0;

std::string foundFile = findFontFile(filename);
if (foundFile.empty()) return 0;

OpenThreads::ScopedLock lock(s_FontFileMutex);

osg::ref_ptr localOptions;
if (!userOptions)
{
localOptions = new osgDB::ReaderWriter::Options;

localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS);
}

osg::Object* object = osgDB::readObjectFile(foundFile, userOptions ? 
userOptions : localOptions.get());

// if the object is a font then return it.
osgText::Font* font = dynamic_cast(object);
if (font) return font;

// otherwise if the object has zero references then delete it by doing 
another unref().
if (object && object->referenceCount()==0) object->unref();
return 0;
}




Thanks,
Ryan

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=21314#21314





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org