Issue with GC in Multi-threaded environments

Archives Forums/BlitzMax Bug Reports/Issue with GC in Multi-threaded environments

Rozek(Posted 2010) [#1]
Well,

as usual in such a situation, it is difficult to isolate the problem, but: it seems that (under Mac OS X, at least) the GC for MT applications causes crashes.

See http://www.blitzmax.com/Community/posts.php?topic=89912 and http://www.blitzmax.com/Community/posts.php?topic=88578#1005858 for descriptions.

Just contact me if you need more information and I'll see what I can do...this issue prevents me from continuing with my development (I'll see if I can live with a single-threaded app in the beginning...)

Thanks in advance for your effort!


Rozek(Posted 2010) [#2]
Ok,

meanwhile (and with the help of others!) I've been able to isolate the problem and develop a workaround (for a particular type of problem, at least)

The underlying problem is: destructor methods get called from outside the main thread (i.e. from within non-main threads) and do "things" which should only be done from within the main thread!

One such destructor is that of "TGLImageFrame", which internally invokes "glDeleteTextures", which then crashes the application.

A workaround for that particular destructor can be found at the end of http://www.blitzmax.com/Community/posts.php?topic=89912

As a more generic approach, I would suggest a
function invoke_async (handler(data:object), data:object)
end function

which accepts a "handler" together with all the "data" it needs and invokes it the next time "waitevent" (or similar) is called from within the main thread. The "handler" could then do anything that should not be done within subthreads.

This would still require the programmer to think about any potential problems within destructors but would also allow her/him to tackle such issues relatively painlessly.


marksibly(Posted 2010) [#3]
Hi,

Nice find!

What I think I'll do for now is queue up 'dead' gl textures like this and flush the queue before allocating new ones. Does that sound OK? I'm not too keen on adding a new global invoke_async() handler until we have more than one use-case to go by...also, this way should be able to handle GL contexts on non-main threads (to a degree...)?

Can anyone think of any other situations like this?

As far as I know, OpenAL is not architected to be 'context-per-thread' the way GL is, so I don't think that's a problem.


Rozek(Posted 2010) [#4]
Hello Mark!

Queuing up dead textures and freeing them later sounds ok - just make sure that you free them in the main thread ;-)

It's ok not to add s.th. like "invoke_async" although I mainly had user-defined situations (not only destructors but also, e.g., MaxGUI-related operations) in mind for this routine: Java is in a similar situation with its "Swing" package and solves this using an "invokeLater" method which does exactly what the "invoke_async" (or similar) should do.

On the other hand: such an "invoke_async" can easily be emulated using an approach similar to what I am currently doing with "glDeleteTextures" - thus, there is no urgent need for *you* to provide it.

Nevertheless, thanks for fixing this bug!