|  |  | 
| |  | Posted by Max Samukha |  Permalink  Reply | 
 | 
| Max Samukha  
 
 
 | http://d.puremagic.com/issues/show_bug.cgi?id=4104
           Summary: No way to get notified about D runtime termination.
           Product: D
           Version: unspecified
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: critical
          Priority: P2
         Component: druntime
        AssignedTo: sean@invisibleduck.org
        ReportedBy: samukha@voliacable.com
--- Comment #0 from Max Samukha <samukha@voliacable.com> 2010-04-19 06:07:29 PDT ---
Qt classes have corresponding D wrappers in QtD. For many Qt classes we can avoid creating duplicate wrappers (or searching a wrapper cache) and store the D wrapper pointers directly in the C++ objects.
When Qt takes ownership of such an object, QtD disables garbage collection for the D wrapper by adding its reference to the GC roots. When later Qt deletes the object, a callback to D is emitted, during which the wrapper is destroyed.
Everything works well unless the C++ object is statically allocated or is owned by a statically allocated object. If it is, the C++ destructor is called *after* the D runtime has been terminated, meaning GC pools has been freed and there is no wrapper to delete.
One solution is to have a flag that would be set after the D runtime has been terminated. Then we could avoid deleting already freed wrappers by checking the flag in the callback.
Patch for druntime/src/rt/dmain2.d:
@@ -165,12 +165,18 @@
 }
 shared bool _d_isHalting = false;
+shared bool _d_isTerminated = false;
 extern (C) bool rt_isHalting()
 {
     return _d_isHalting;
 }
+extern (C) bool rt_isTerminated()
+{
+    return _d_isTerminated;
+}
+
 // This variable is only ever set by a debugger on initialization so it should
 // be fine to leave it as __gshared.
 extern (C) __gshared bool rt_trapExceptions = true;
@@ -244,6 +250,7 @@
     finally
     {
         _d_criticalTerm();
+        _d_isTerminated = true;
     }
     return false;
 }
@@ -404,5 +411,7 @@
         _STD_critical_term();
         _STD_monitor_staticdtor();
     }
+
+    _d_isTerminated = true;
     return result;
 }
Another solution would be a notification. Tests show that 'atexit' doesn't work for us because the handlers registered with 'atexit' are invoked after the destructors has been run. So we need a separate notification.
Even better solution: don't free the GC memory on exit and give the rooted objects a chance to be finalized properly.
This is critical.
-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
 |