CR/CN: MediaPlatformEx Cached Objects' Contexts

Tad Yeager <[email protected]>
Newsgroups gmane.comp.multimedia.helix.devel
Message-ID <[email protected]>
In Atlas, MediaPlatformEx replaces Cayenne's ObjectBroker.  Cached objects 
aren't created when AddObjectToInstanceCache is called on 
MediaPlatformEx.  In Cayenne, upon creation, objects are passed the 
ObjectBroker in RegisterContext nested at the depth at which they're 
cached.  In Atlas, they're passed the inner child MediaPlatformEx from 
which creation is requested, passed as the 4th parameter to 
CreateInstanceAggregatable.  This change moves Atlas MediaPlatformEx back 
to Cayenne ObjectBroker behavior.

Branches effected:  Atlas_3_1_0, HEAD

Platforms: All with HELIX_FEATURE_EXTENDED_MEDIAPLATFORM, 
HELIX_CONFIG_USE_EXTENDED defined


Index: chxmedpltfmex.cpp
===================================================================
RCS file: /cvsroot/client/medpltfm/chxmedpltfmex.cpp,v
retrieving revision 1.6.2.3
diff -u -6 -0 -r1.6.2.3 chxmedpltfmex.cpp
--- chxmedpltfmex.cpp   17 Apr 2008 20:11:33 -0000      1.6.2.3
+++ chxmedpltfmex.cpp   31 Mar 2009 18:53:37 -0000
@@ -659,121 +659,127 @@

  STDMETHODIMP
  CHXMediaPlatformEx::CreateInstanceAggregatable
                                 (THIS_
                                 REFCLSID            /*IN*/  clsid,
                                 REF(IUnknown*)  /*OUT*/ pUnknown,
                                 IUnknown*           /*IN*/  pUnkOuter)
  {
      HX_RESULT result  = ObjectFromCLSIDPrivate(clsid, pUnknown, 
pUnkOuter, GetUnknown() );

      return result;
  }

  STDMETHODIMP
  CHXMediaPlatformEx::ObjectFromCLSIDPrivate(REFCLSID 
clsid,REF(IUnknown*)pObject,
                                             IUnknown* pUnkOuter, IUnknown* 
pContext )
  {
      HX_RESULT result = HXR_FAIL;

      // Set up a default value
      pObject = NULL;

      CLSID aliasedCLSID;
      if( SUCCEEDED( GetAliasedCLSID( clsid, &aliasedCLSID ) ) )
      {
         result = ObjectFromCLSIDPrivate( aliasedCLSID, pObject, pUnkOuter, 
pContext );

         return result;
      }

      // The somewhat odd structure here is to try and keep the cache 
locked for as little time as possible.

      // If the object's in the cache give 'em that.
      HXBOOL objectCached = FALSE;

      PObjectFromInstanceCache_( clsid, objectCached );

      if ( objectCached )
      {
         HXBOOL objectAlreadyExists = FALSE;

         // this scope is necessary to get the locking correct
         {
             HXAutoLock lock( &m_CacheLockKey );

             // XXXHP - COMING SOON: this ugliness to be replaced by 
iterators...
             CCacheNode_& cacheNodeRef = m_Cache [clsid];
             cacheNodeRef.Unqueue ();
             if (cacheNodeRef.GetObject ())
             {
                 pObject = cacheNodeRef.GetObject ();
                 pObject->AddRef ();
                 result = HXR_OK;
                 objectAlreadyExists = TRUE;
             }
         }

         if( ! objectAlreadyExists )
         {
             // Construct object here, and add it to the cache.
-           result = CHXMediaPlatform::ObjectFromCLSIDPrivate(clsid, 
pObject, pUnkOuter, pContext);
+           // The 4th Parameter is passed as Context in RegisterContext 
when base CHXMediaPlatform
+           // creates the cached object. Some cached objects assume that 
the Context they're passed
+           // will be nested at the same level at which they're cached 
(this level because objectCached==true).
+           // We must pass the cached object the Unknown of this 
MediaPlatformEx, rather than the pContext
+           // parameter passed into this function from the MediaPlatform 
that began the creation
+           // process in CreateInstanceAggregatable or similar call.
+           result = CHXMediaPlatform::ObjectFromCLSIDPrivate(clsid, 
pObject, pUnkOuter, GetUnknown());

             if( SUCCEEDED( result ) )
             {
                 HXAutoLock lock( &m_CacheLockKey );

                 CCacheNode_& cacheNodeRef = m_Cache [clsid];

                 cacheNodeRef.SetObject (pObject);
                 pObject->AddRef ();
                 AddObservers_( clsid, pObject );
             }
         }

         return result;
      }

      // The object wasn't in the cache, so defer to our parent.
      // CLSID_HXObjectManager is a special case, it should not be cached and
      // has to be created using it's parent (i.e. this), not the root CCF.
      if( !IsEqualCLSID(clsid, CLSID_HXObjectManager ) && m_pParent )
      {
         result = m_pParent->ObjectFromCLSIDPrivate( clsid, pObject, 
pUnkOuter, pContext );
      }
      else
      {
         result = CHXMediaPlatform::ObjectFromCLSIDPrivate(clsid, pObject, 
pUnkOuter, pContext);
      }

      return result;
  }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.