WinAPI callbacks and GC

Regan Heath regan at netmail.co.nz
Wed Apr 24 02:51:28 PDT 2013


On Tue, 23 Apr 2013 22:21:27 +0100, Jack Applegame <japplegame at gmail.com>  
wrote:

> I'm writing Ctrl-C handler for console application for Windows:
>
> extern(Windows) {
>    int CtrlHandler(uint flag) nothrow {
>      auto tmp = new SomeClass; // is it safe?
>      ...
>      return true;
>    }
> }
>
> ...
>
> SetConsoleCtrlHandler(&CtrlHandler, true);
>
> ...
>
> According WinAPI documentation, CtrlHandler will be called in new  
> additional thread. Is it safe to allocate GC memory in NOT Phobos  
> threads?
> If not, how to make it safe? I'm trying call thread_attachThis() at the  
> beginning of CtrlHandler fucntion, but it doesn't compile because  
> thread_attachThis() is not nothrow.

You are correct in that the issue with this handler is that it's likely  
called in a thread created by the Win32 runtime which the D GC has no  
knowledge of.  And, because of this wont get paused when the GC runs a  
collection, which is an issue because your allocation above might happen  
during a GC collection, and the GC is likely to have an 'issue' with it.

The issue here is a timing window.  Lets assume the GC is busy performing  
a collection when the handler runs.

If you wrap the thread_attachThis() in a try/catch block as evilrat has  
shown this should solve the nothrow issue.  But, the GC is unlikely to  
then pause your thread - because it's already done the thread pausing and  
is busy marking and sweeping so your thread will continue to run and  
allocate during collection.

The other idea is to call GC.disable() to disable automatic collection at  
the start of the handler, and GC.enable() at the end.  But again, if  
collection has already started this might not work, might fail horribly,  
and wont protect you.

Someone needs to check the GC code, and thread_attachThis to see if it can  
handle the situation you've presented.

Until then, I would perform manual memory allocation.  I am not sure how  
in D, but you need something like "placement new" to construct a class in  
a previously allocated block of memory (allocated with malloc or similar).

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/


More information about the Digitalmars-d-learn mailing list