[OLE] Better handling of References

Mike Hearn mike at navi.cx
Wed May 26 05:26:41 CDT 2004


On Wed, 26 May 2004 03:55:25 +0200, Raphael wrote:
>  I'm trying to install Splinter Cell Demo (installshield).
>  And i have seen:
>  - one typelib was released while typeinfos (childs of typelib) are in use
>  - the install "crash" (catched and returns an E_UNEXPECTED error) when it 
> wants to call ITypeInfo_fnGetContainingTypeLib (who want to AddRef the 
> freshly released TypeLib)

Hi Raphael, 

This has been a known problem for a long time now, with several attempts
to fix it, all of them have been incorrect. It seems your approach is a
new one and interesting, but I'm not sure this is how Windows does it.
Does anybody know exactly what Windows does in this situation? It might be
worth writing a test case to find out. 

Objects in a semi-freed state seem like a slightly odd way to do things.

> Now i have another crash later, but it seems a problem with an invoke method 
> who failed :(
> If any ole/rpc expert can look at this problem i'll be very happy :)

Well, if you could provide more detail (backtrace etc) on the crash it
would be good.

A few comments on the patch:

-    --(This->ref);
+    /** escape decrement for soft_references */
+    if (This->ref > 0) {
+      --(This->ref);
+    } else {
+      ERR("trying to Release again an ITypeLib2 in freing state waiting for ITypeInfo (%p) childs Releases\n", This);
+    }

I don't remember whether this object is supposed to be thread safe or not,
but should this not be an InterlockedDecrement?

I think the error could be better phrased as:

ERR("Reference count on an ITypeLib2 object (%p) already zero: waiting for
ITypeInfo children to be released as well");

or words to that effect.

+      if (This->soft_ref > 0) {
+	ERR("trying to Release an ITypeLib2 while some ITypeInfo (%p) childs are actually with Refs > 1. So Dont free it now \n", This);
+	/** maybe scaning ITypeInfo list to dump ITypeInfos with Refs  > 1 */
+	return 1;
+      }

Is it actually an error to do that? If you free a typelib while refs are
held on child typeinfos, is this a bug in the app or a legitimate thing to
do? If it's not a bug in the app we probably shouldn't use ERR here.

     ++(This->ref);
 
+    if (This->ref > 1) {
+      if (NULL != This->pTypeLib) ++(This->pTypeLib->soft_ref);
+    }
+

Ditto on thread safety. Please forgive me if this object is not free
threaded.

--- variant.c	30 Apr 2004 18:32:58 -0000	1.97
+++ variant.c	26 May 2004 01:46:44 -0000
@@ -605,6 +605,8 @@
 
   hres = VARIANT_ValidateType(V_VT(pVarg));
 
+  if (V_VT(pVarg) == VT_EMPTY) return hres;
+
   if (SUCCEEDED(hres))
   {
     if (!V_ISBYREF(pVarg))

This change looks OK though I'm not sure why it's necessary. Does the
Splinter Cell installer actually need this?

thanks -mike




More information about the wine-patches mailing list