Summary: broken memory management for COM objects derived from
           Product: D
           Version: unspecified
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: druntime

--- Comment #0 from Rainer Schuetze <> 2010-04-14 23:44:39 
PDT ---
Currently, instances of classes that derive from IUnknown are allocated from
the C-heap (see lifetime.d, function _d_newclass), but are never released in
the default implementation ComObject (see,
ComObject.Release()), because invariants might still be called.

In addition, ComObjects are not known to the garbage collector (which is
completely useless in at least 99% of all cases), so you have to override
ComObject's new to avoid a bad collection while executing the class

I suggest allocating ComObjects from standard garbage collected objects, and
let the default imlpementation add ranges to the GC when AddRef is called with
reference count 0, and removing the range when Release is called:

class ComObject : IUnknown
    // [... QueryInterface ...]

    override ULONG AddRef()
        LONG lRef = InterlockedIncrement(&count);
        if(lRef == 1)
            uint sz = this.classinfo.init.length;
            GC.addRange(cast(void*) this, sz);
        return lRef;

    override ULONG Release()
        LONG lRef = InterlockedDecrement(&count);
        if (lRef == 0)
            GC.removeRange(cast(void*) this);
        return cast(ULONG)lRef;

Otherwise, the garbage collector is responsible of releasing memory. 

This also lets ComObject be handled like normal objects in D-Code (no need to
call AddRef/Release).

Here's the patch to lifetime.d:

Index: lifetime.d
--- lifetime.d    (revision 282)
+++ lifetime.d    (working copy)
@@ -98,7 +98,7 @@
     void* p;

     debug(PRINTF) printf("_d_newclass(ci = %p, %s)\n", ci, cast(char
-    if (ci.m_flags & 1) // if COM object
+    if (0 & ci.m_flags & 1) // if COM object
     {   /* COM objects are not garbage collected, they are reference counted
          * using AddRef() and Release().  They get free'd by C's free()
          * function called by Release() when Release()'s reference count goes

Configure issuemail:
------- You are receiving this mail because: -------

Reply via email to