internal static bool WalkOneRCW(__ComObject comObject) { __com_IJupiterObject* pJupiterObject = comObject.GetIJupiterObject_NoAddRef(); s_currentComObjectToWalk = comObject; // // Start building references from this RCW to all dependent CCWs // // NOTE: StdCallCOOP is used instead of Calli to avoid deadlock // int hr = CalliIntrinsics.StdCallCOOP( pJupiterObject->pVtable->pfnFindDependentWrappers, pJupiterObject, GetDependentWrapperCallbackObject() ); s_currentComObjectToWalk = null; return (hr >= 0); }
/// <summary> /// Reporting to Jupiter that we've done one Release to this object instance /// /// The ref count reporting is needed for Jupiter to determine whether there is something other than /// Jupiter and RCW that is holding onto this Jupiter object. If there is, this Jupiter object and /// all dependent CCWs must be pegged. /// /// We typically report the AddRef *after* an AddRef and report the Release *before* a Release /// It's better to leak (temporarily) than crash. /// </summary> internal static void BeforeRelease(__ComObject comObject) { Debug.Assert(comObject.IsJupiterObject); __com_IJupiterObject* pJupiterObject = comObject.GetIJupiterObject_NoAddRef(); CalliIntrinsics.StdCall<int>(pJupiterObject->pVtable->pfnBeforeRelease, pJupiterObject); }
/// <summary> /// Called after Jupiter RCW has been created /// </summary> internal static void AfterJupiterRCWCreated(__ComObject comObject) { __com_IJupiterObject* pJupiterObject = comObject.GetIJupiterObject_NoAddRef(); // // Notify Jupiter that we've created a new RCW for this Jupiter object // To avoid surprises, we should notify them before we fire the first AfterAddRef // CalliIntrinsics.StdCall<int>(pJupiterObject->pVtable->pfnConnect, pJupiterObject); // // Tell Jupiter that we've done AddRef for IJupiterObject* and IUnknown* // It's better to tell them later than earlier (prefering leaking than crashing) // AfterAddRef(comObject); AfterAddRef(comObject); }
/// <summary> /// Reporting to Jupiter that we've done one AddRef to this object instance /// /// The ref count reporting is needed for Jupiter to determine whether there is something other than /// Jupiter and RCW that is holding onto this Jupiter object. If there is, this Jupiter object and /// all dependent CCWs must be pegged. /// /// We typically report the AddRef *after* an AddRef and report the Release *before* a Release /// It's better to leak (temporarily) than crash. /// </summary> internal static void AfterAddRef(__ComObject comObject) { Debug.Assert(comObject.IsJupiterObject); __com_IJupiterObject* pJupiterObject = comObject.GetIJupiterObject_NoAddRef(); // // Send out AfterAddRef callbacks to notify Jupiter we've done AddRef for certain interfaces // We should do this *after* we made a AddRef because we should never // be in a state where report refs > actual refs // CalliIntrinsics.StdCall<int>(pJupiterObject->pVtable->pfnAfterAddRef, pJupiterObject); }
/// <summary> /// Called when Jupiter RCW is being created /// We do one-time initialization for RCW walker here /// </summary> internal static void OnJupiterRCWCreated(__ComObject comObject) { Debug.Assert(comObject.IsJupiterObject); if (s_pGCManager == default(IntPtr)) { RCWWalker.Initialize(comObject.GetIJupiterObject_NoAddRef()); } }