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: s...@invisibleduck.org
        ReportedBy: samu...@voliacable.com


--- Comment #0 from Max Samukha <samu...@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: -------

Reply via email to