www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - WinAPI callbacks and GC

reply "Jack Applegame" <japplegame gmail.com> writes:
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.
Apr 23 2013
next sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Tuesday, 23 April 2013 at 21:21:28 UTC, Jack Applegame 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.
i guess it call ur callback(enters D code, so GC is in), alloc new instance, and after callback return it should collect it, but there is no such thing like guessing, just try it and see if it works correctly. also there is an option without using GC at all, use struct instead of class if you don't need polymorphism(for most tasks structs is really enough, they are as powerful as c++ class just without polymorphism and other nasties) also if you really need class or whole program lifetime memory, you may declare instance in module level with __gshared("__gshared SomeClass tmp;", don't forget to alloc if is class) so gc won't touch it. also it may be better to read related docs in language reference on this site for more info, since i'm somehow bad with remembering all the details.
Apr 23 2013
prev sibling next sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Tuesday, 23 April 2013 at 21:21:28 UTC, Jack Applegame wrote:

 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.
what stops you from calling normal functions in nothrow one? use try-catch inside nothrow. nothrow means that function doesn't throw, not it can call only nothrow. also if another func is C language func, you may try to add nothrow to it's signature since it's anyway can't throw anything. ------------------- example: void doWithThrow() { int x = 1; x++; } nothrow void doStuff() { try { doWithThrow(); } catch ( Exception e ) { // your handling code here... } } void main() { doStuff(); } ------------------- i hope i don't learn people to do bad or stupid things :(
Apr 23 2013
prev sibling next sibling parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 23 Apr 2013 22:21:27 +0100, Jack Applegame <japplegame 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/
Apr 24 2013
parent "evilrat" <evilrat666 gmail.com> writes:
On Wednesday, 24 April 2013 at 09:51:29 UTC, Regan Heath wrote:
 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).
look at "__gshared", might be useful for when one need to interop things with non D code. http://dlang.org/attribute.html#gshared
Apr 24 2013
prev sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
On Apr 23, 2013, at 2:21 PM, Jack Applegame <japplegame gmail.com> =
wrote:
=20
 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 no throw. thread_attachThis should probably just be labeled nothrow. I don't = think there's anything in that function that can throw an Exception.=
Apr 30 2013
parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Wed, 01 May 2013 01:12:39 +0100, Sean Kelly <sean invisibleduck.org>  
wrote:

 On Apr 23, 2013, at 2:21 PM, Jack Applegame <japplegame gmail.com> wrote:
 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 no throw.
thread_attachThis should probably just be labeled nothrow. I don't think there's anything in that function that can throw an Exception.
That makes it callable.. but did you see my post about the various timing issues with using this in a non-GC thread (potentially while the GC is already collecting - or similar). R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
May 02 2013
parent reply Sean Kelly <sean invisibleduck.org> writes:
On May 2, 2013, at 6:17 AM, Regan Heath <regan netmail.co.nz> wrote:

 On Wed, 01 May 2013 01:12:39 +0100, Sean Kelly =
<sean invisibleduck.org> wrote:
=20
 On Apr 23, 2013, at 2:21 PM, Jack Applegame <japplegame gmail.com> =
wrote:
=20
 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 no throw.
=20
=20
 thread_attachThis should probably just be labeled nothrow.  I don't =
think there's anything in that function that can throw an Exception.
=20
 That makes it callable.. but did you see my post about the various =
timing issues with using this in a non-GC thread (potentially while the = GC is already collecting - or similar). The GC holds a lock on the global thread list while collecting, so it = shouldn't be possible for thread_attachThis to register a thread when = this is happening. In fact, thread_attachThis even temporarily disables = the GC, and since this operation is protected by the GC lock, it's = blocked there as well.=
May 06 2013
parent "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 07 May 2013 00:03:58 +0100, Sean Kelly <sean invisibleduck.org>  
wrote:

 On May 2, 2013, at 6:17 AM, Regan Heath <regan netmail.co.nz> wrote:

 On Wed, 01 May 2013 01:12:39 +0100, Sean Kelly <sean invisibleduck.org>  
 wrote:

 On Apr 23, 2013, at 2:21 PM, Jack Applegame <japplegame gmail.com>  
 wrote:
 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 no throw.
thread_attachThis should probably just be labeled nothrow. I don't think there's anything in that function that can throw an Exception.
That makes it callable.. but did you see my post about the various timing issues with using this in a non-GC thread (potentially while the GC is already collecting - or similar).
The GC holds a lock on the global thread list while collecting, so it shouldn't be possible for thread_attachThis to register a thread when this is happening. In fact, thread_attachThis even temporarily disables the GC, and since this operation is protected by the GC lock, it's blocked there as well.
Excellent. Might be nice to see some of these details in the docs :p .. or even just a "will block if collection is in progress". R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
May 07 2013