Ah, I think I understand.

The idea of multiple calls to TextureSystem::create (or the underlying 
ImageCache::create) was that multiple plugins, libraries, or components within 
an app may each need a TextureSystem, but you don't want multiple underlying 
image caches live, and the component have a hard time coordinating among them 
or even be unaware whether there are other components sharing the cache, so 
TS::create is able to dole out multiple TS's with a single shared cache.

We never assumed that individual threads, constantly being created and 
destroyed, would be requesting TS::create every time they start up. It's not 
meant to handle that usage case, because you're not supposed to want a 
different TextureSystem for each thread. There's a difference between sharing 
one texture system, versus everybody getting a their own texture system which 
all reference the same underlying ImageCache. See?

I think the right thing to do is to request the texture cache handle just once 
for the app, store it in a global variable, and have your threads all just use 
that pointer when they are created.

I suppose another option would be to have a global OIIO option that controls 
whether an invalidate_all() call is made upon a create() that returns the 
shared cache. But, that approach would still wastefully do an 
allocation/construction of a TextureSystem every time you spawn a thread, which 
is unnecessary.

        -- lg


On Dec 8, 2014, at 11:56 AM, Simon Smith <[email protected]> wrote:

> Hi,
> 
> I have a question about shared texture caches.
> Basically, are these a “Good Thing” to use across threads?
> If not, how “bad” is it?
> 
> We have a system whereby threads are created for jobs whenever they are 
> needed (it actually uses Qt’s Concurrent system).
> Each thread can use the texture system, so I had it set to share the texture 
> cache across threads.
> 
> This is fine until you have a file that does not exist.
> 
> One thread will come along, try to open the file, fail, and mark it as broken 
> (this is all done when inside the get_texture_handle) which is correct.
> Now, this thread is going to call texture() in a little while, but in the 
> meantime another thread is fired up as part of the job.
> 
> When this gets initialised, we create a new texture cache member pointer by 
> calling TextureSystem::create()
> Inside here, because it’s marked as being shared, it will invalidate all 
> files in the cache.
> Part of this invalidation means the broken flag is reset to false.
> 
> Now the other thread gets a look in, tries to use the file in the texture 
> call, and crashes because the broken flag is reset and it goes sailing 
> through and tries to access the 0th element in the subimage list (which 
> obviously does not exist!)
> 
> So, I’m wondering how I should best handle this situation.
> Should I perhaps:
> a) Not use a shared texture cach (this sounds like a bad thing to me)
> b) Not create new texture cache pointers but to share the one globally over 
> threads - but how would I get the PerThreadInfo instances that I need?
> c) Something else ….
> 
> Any thoughts or help on this would be greatly appreciated - I’m sure this 
> must be a very common scenario!
> 
> Best Regards,
>    Simon
> _______________________________________________
> Oiio-dev mailing list
> [email protected]
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

--
Larry Gritz
[email protected]



_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

Reply via email to