#19544 [Opn->Csd]: Reference counting problem in php_COM_set
| From: | phanto@php.net | Date: | Wed, 02 Oct 2002 13:01:48 +0000 |
| Subject: | #19544 [Opn->Csd]: Reference counting problem in php_COM_set | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-21268@lists.php.net to get a copy of this message | ||
ID: 19544
Updated by: phanto@php.net
Reported By: ge@gse.nl
-Status: Open
+Status: Closed
Bug Type: COM related
Operating System: Windows 2000
PHP Version: 4.2.3
New Comment:
should be fixed in cvs now, don't know how these addrefs came there :)
Previous Comments:
------------------------------------------------------------------------
[2002-09-21 16:54:29] ge@gse.nl
I think there is a reference counting problem in function php_COM_set
in file COM.c for collection objects.
First, the DISPID_NEWENUM function is Invoke()ed to retrieve an
enumerator. If this succeeds, the enumerator is created and according
to COM rules its reference count should be 1. Next, an explicit
AddRef() is done on the enumerator, setting its reference count to 2.
The following QueryInterface (if it succeeds) will increment the
reference count to 3. After that, FREE_VARIANT will call VariantClear
which in turn will Release() the enumerator, leaving the reference
count at 2 when the function is exited.
When the object is finally released in php_COM_release, the enumerator
will be Release()ed also, but since the reference count was 2 this will
only bring the reference count down to 1 and therefore the enumerator
will not clean up itself.
I think the enumerator should NOT be AddRef()ed in php_COM_set. The
MSDN article "Implementing Automation Collections"
<http://msdn.microsoft.com/library/en-us/dnautoma/html/msdn_collect.asp>
says this about how Visual Basic handles For Each:
Step 1: Retrieve the value of docs._NewEnum into punk (remember that
_NewNum is of type IUnknown*).
Step 2: QueryInterface on punk for IEnumVARIANT (pUnk->QueryInterface(
IID_IEnumVARIANT, &penum)). Release punk.
Step 3: While penum->Next returns a valid VARIANT, execute the code
within the For Each clause, using the IDispatch pointer stored in the
variant for all references to "doc".
Step 4: Release penum.
Note that there is no AddRef() here.
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=19544&edit=1