Robert Shearman : ole: Store the destination context and the destination context data in

Alexandre Julliard julliard at wine.codeweavers.com
Mon Mar 6 04:50:46 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 92a1f52b4d8dea527abc0b037b50a10a70237cc8
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=92a1f52b4d8dea527abc0b037b50a10a70237cc8

Author: Robert Shearman <rob at codeweavers.com>
Date:   Sun Mar  5 13:37:22 2006 +0000

ole: Store the destination context and the destination context data in
the proxy manager when unmarshaling.

---

 dlls/ole32/compobj_private.h |    2 +
 dlls/ole32/marshal.c         |   83 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index caa84de..8aeb0e0 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -127,6 +127,8 @@ struct proxy_manager
   ULONG sorflags;           /* STDOBJREF flags (RO) */
   IRemUnknown *remunk;      /* proxy to IRemUnknown used for lifecycle management (CS cs) */
   HANDLE remoting_mutex;    /* mutex used for synchronizing access to IRemUnknown */
+  MSHCTX dest_context;      /* context used for activating optimisations (LOCK) */
+  void *dest_context_data;  /* reserved context value (LOCK) */
 };
 
 /* this needs to become a COM object that implements IRemUnknown */
diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c
index 8f952f9..95ff257 100644
--- a/dlls/ole32/marshal.c
+++ b/dlls/ole32/marshal.c
@@ -56,7 +56,9 @@ extern const CLSID CLSID_DfMarshal;
  * when the proxy disconnects or is destroyed */
 #define SORFP_NOLIFETIMEMGMT SORF_OXRES1
 
-static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFIID riid, void **object);
+static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
+                                MSHCTX dest_context, void *dest_context_data,
+                                REFIID riid, void **object);
 
 /* Marshalling just passes a unique identifier to the remote client,
  * that makes it possible to find the passed interface again.
@@ -300,6 +302,8 @@ static HRESULT WINAPI ClientIdentity_Que
                 HRESULT hrobj = qiresults[i].hResult;
                 if (hrobj == S_OK)
                     hrobj = unmarshal_object(&qiresults[i].std, This->parent,
+                                             This->dest_context,
+                                             This->dest_context_data,
                                              pMQIs[index].pIID,
                                              (void **)&pMQIs[index].pItf);
 
@@ -586,6 +590,11 @@ static HRESULT proxy_manager_construct(
     /* we create the IRemUnknown proxy on demand */
     This->remunk = NULL;
 
+    /* initialise these values to the weakest values and they will be
+     * overwritten in proxy_manager_set_context */
+    This->dest_context = MSHCTX_INPROC;
+    This->dest_context_data = NULL;
+
     EnterCriticalSection(&apt->cs);
     /* FIXME: we are dependent on the ordering in here to make sure a proxy's
      * IRemUnknown proxy doesn't get destroyed before the regual proxy does
@@ -602,6 +611,63 @@ static HRESULT proxy_manager_construct(
     return S_OK;
 }
 
+static inline void proxy_manager_set_context(struct proxy_manager *This, MSHCTX dest_context, void *dest_context_data)
+{
+    MSHCTX old_dest_context = This->dest_context;
+    MSHCTX new_dest_context;
+
+    do
+    {
+        new_dest_context = old_dest_context;
+        /* "stronger" values overwrite "weaker" values. stronger values are
+         * ones that disable more optimisations */
+        switch (old_dest_context)
+        {
+        case MSHCTX_INPROC:
+            new_dest_context = dest_context;
+            break;
+        case MSHCTX_CROSSCTX:
+            switch (dest_context)
+            {
+            case MSHCTX_INPROC:
+                break;
+            default:
+                new_dest_context = dest_context;
+            }
+            break;
+        case MSHCTX_LOCAL:
+            switch (dest_context)
+            {
+            case MSHCTX_INPROC:
+            case MSHCTX_CROSSCTX:
+                break;
+            default:
+                new_dest_context = dest_context;
+            }
+            break;
+        case MSHCTX_NOSHAREDMEM:
+            switch (dest_context)
+            {
+            case MSHCTX_DIFFERENTMACHINE:
+                new_dest_context = dest_context;
+                break;
+            default:
+                break;
+            }
+            break;
+        default:
+            break;
+        }
+
+        if (old_dest_context == new_dest_context) break;
+
+        old_dest_context = InterlockedCompareExchange((PLONG)&This->dest_context, new_dest_context, old_dest_context);
+    } while (new_dest_context != old_dest_context);
+
+    if (dest_context_data)
+        InterlockedExchangePointer(&This->dest_context_data, dest_context_data);
+}
+
 static HRESULT proxy_manager_query_local_interface(struct proxy_manager * This, REFIID riid, void ** ppv)
 {
     HRESULT hr;
@@ -799,7 +865,9 @@ static HRESULT proxy_manager_get_remunkn
         memcpy(&stdobjref.ipid.Data4, &stdobjref.oxid, sizeof(OXID));
         
         /* do the unmarshal */
-        hr = unmarshal_object(&stdobjref, This->parent, &IID_IRemUnknown, (void**)&This->remunk);
+        hr = unmarshal_object(&stdobjref, This->parent, This->dest_context,
+                              This->dest_context_data, &IID_IRemUnknown,
+                              (void**)&This->remunk);
         if (hr == S_OK)
             *remunk = This->remunk;
     }
@@ -990,7 +1058,9 @@ StdMarshalImpl_MarshalInterface(
 /* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
  * no questions asked about the rules surrounding same-apartment unmarshals
  * and table marshaling */
-static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFIID riid, void **object)
+static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
+                                MSHCTX dest_context, void *dest_context_data,
+                                REFIID riid, void **object)
 {
     struct proxy_manager *proxy_manager = NULL;
     HRESULT hr = S_OK;
@@ -1017,6 +1087,9 @@ static HRESULT unmarshal_object(const ST
     if (hr == S_OK)
     {
         struct ifproxy * ifproxy;
+
+        proxy_manager_set_context(proxy_manager, dest_context, dest_context_data);
+
         hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy);
         if (hr == E_NOINTERFACE)
         {
@@ -1043,6 +1116,7 @@ static HRESULT unmarshal_object(const ST
 static HRESULT WINAPI
 StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
 {
+    StdMarshalImpl *This = (StdMarshalImpl *)iface;
     struct stub_manager  *stubmgr;
     STDOBJREF stdobjref;
     ULONG res;
@@ -1112,7 +1186,8 @@ StdMarshalImpl_UnmarshalInterface(LPMARS
             wine_dbgstr_longlong(stdobjref.oxid));
 
     if (hres == S_OK)
-        hres = unmarshal_object(&stdobjref, apt, riid, ppv);
+        hres = unmarshal_object(&stdobjref, apt, This->dwDestContext,
+                                This->pvDestContext, riid, ppv);
 
     if (hres) WARN("Failed with error 0x%08lx\n", hres);
     else TRACE("Successfully created proxy %p\n", *ppv);




More information about the wine-cvs mailing list