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