static McgModuleManager() { CCWLookupMap.InitializeStatics(); ContextEntry.ContextEntryManager.InitializeStatics(); ComObjectCache.InitializeStatics(); const int DefaultSize = 101; // small prime number to avoid resizing in start up code s_runtimeTypeHandleToMcgInterfaceInfoMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, McgInterfaceInfo>(DefaultSize, new RuntimeTypeHandleComparer(), /* sync = */ true); s_runtimeTypeHandleToCCWTemplateInfoMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, CCWTemplateInfo>(DefaultSize, new RuntimeTypeHandleComparer(), /* sync = */ true); }
private static bool GetIndicesFromMap(System.Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int> map, RuntimeTypeHandle typeHandle, out int moduleIndex, out int typeIndex) { int totalIndex; if (map.TryGetValue(typeHandle, out totalIndex)) { moduleIndex = totalIndex & (MAX_MODULES - 1); typeIndex = totalIndex >> NUM_BITS_FOR_MAX_MODULES; return(true); } moduleIndex = -1; typeIndex = -1; return(false); }
// Get the event registration token table for an event. These are indexed by the remove method of the event. private static System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> GetEventRegistrationTokenTable(object instance, Action <EventRegistrationToken> removeMethod) { Debug.Assert(instance != null); Debug.Assert(removeMethod != null); Debug.Assert(s_eventRegistrations != null); try { s_eventRegistrationsLock.Acquire(); System.Collections.Generic.Internal.Dictionary <IntPtr, System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> > instanceMap = null; if (!s_eventRegistrations.TryGetValue(instance, out instanceMap)) { instanceMap = new System.Collections.Generic.Internal.Dictionary <IntPtr, System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> >(); s_eventRegistrations.Add(instance, instanceMap); } System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> tokens = null; // Because this code already is tied to a specific instance, the type handle associated with the // delegate is not needed. RuntimeTypeHandle thDummy; if (!instanceMap.TryGetValue(removeMethod.GetFunctionPointer(out thDummy), out tokens)) { tokens = new System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList>(true); instanceMap.Add(removeMethod.GetFunctionPointer(out thDummy), tokens); } return(tokens); } finally { s_eventRegistrationsLock.Release(); } }
public static void Initialize() { int totalInterfaces = 0; int totalCCWTemplates = 0; int totalClasses = 0; int totalCollections = 0; int totalBoxings = 0; for (int moduleIndex = 0; moduleIndex < s_moduleCount; moduleIndex++) { totalInterfaces += s_modules[moduleIndex].GetInterfaceDataCount(); totalCCWTemplates += s_modules[moduleIndex].GetCCWTemplateDataCount(); totalClasses += s_modules[moduleIndex].GetClassDataCount(); totalCollections += s_modules[moduleIndex].GetCollectionDataCount(); totalBoxings += s_modules[moduleIndex].GetBoxingDataCount(); } s_runtimeTypeHandleToInterfaceIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalInterfaces, RuntimeTypeHandleComparer.Instance, /* sync = */ false); s_runtimeTypeHandleToCCWTemplateIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalCCWTemplates, RuntimeTypeHandleComparer.Instance, /* sync = */ false); s_runtimeTypeHandleToClassIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalClasses, RuntimeTypeHandleComparer.Instance, /* sync = */ false); s_runtimeTypeHandleToCollectionIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalCollections, RuntimeTypeHandleComparer.Instance, /* sync = */ false); s_runtimeTypeHandleToBoxingIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalBoxings, RuntimeTypeHandleComparer.Instance, /* sync = */ false); for (int moduleIndex = 0; moduleIndex < s_moduleCount; moduleIndex++) { McgInterfaceData[] interfaceData = s_modules[moduleIndex].GetAllInterfaceData(); if (interfaceData != null) { for (int typeIndex = 0; typeIndex < interfaceData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToInterfaceIndexMap, interfaceData[typeIndex].ItfType, moduleIndex, typeIndex); } } CCWTemplateData[] ccwTemplateData = s_modules[moduleIndex].GetAllCCWTemplateData(); if (ccwTemplateData != null) { for (int typeIndex = 0; typeIndex < ccwTemplateData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToCCWTemplateIndexMap, ccwTemplateData[typeIndex].ClassType, moduleIndex, typeIndex); } } McgClassData[] classData = s_modules[moduleIndex].GetAllClassData(); if (classData != null) { for (int typeIndex = 0; typeIndex < classData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToClassIndexMap, classData[typeIndex].ClassType, moduleIndex, typeIndex); } } McgCollectionData[] collectionData = s_modules[moduleIndex].GetAllCollectionData(); if (collectionData != null) { for (int typeIndex = 0; typeIndex < collectionData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToCollectionIndexMap, collectionData[typeIndex].CollectionType, moduleIndex, typeIndex); } } McgBoxingData[] boxingData = s_modules[moduleIndex].GetAllBoxingData(); if (boxingData != null) { for (int typeIndex = 0; typeIndex < boxingData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToBoxingIndexMap, boxingData[typeIndex].ManagedClassType, moduleIndex, typeIndex); } } } #if DEBUG for (int moduleIndex = 0; moduleIndex < s_moduleCount; moduleIndex++) { // TODO - bug 295670: I [trylek] have to temporarily comment out this check // as it's hitting a real inconsistency I don't know how to fix right now. // The WinRT enum type "Windows.Foundation.Metadata.AttributeTargets" // has underlying type "uint", however it's projected to "System.AttributeTargets" // which has underlying type "int". Due to this the runtime and MCG see two different // incompatible "AttributeTarget" types and verification of IReference<AttributeTargets> fails. // s_modules[moduleIndex].VerifyWinRTGenericInterfaceGuids(); } #endif }
public static void LateInitialize() { int totalInterfaces = 0; int totalCCWTemplates = 0; int totalClasses = 0; int totalCollections = 0; int totalBoxings = 0; for (int moduleIndex = 0; moduleIndex < s_moduleCount; moduleIndex++) { totalInterfaces += s_modules[moduleIndex].GetInterfaceDataCount(); totalCCWTemplates += s_modules[moduleIndex].GetCCWTemplateDataCount(); totalClasses += s_modules[moduleIndex].GetClassDataCount(); totalCollections += s_modules[moduleIndex].GetCollectionDataCount(); totalBoxings += s_modules[moduleIndex].GetBoxingDataCount(); } s_runtimeTypeHandleToInterfaceIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalInterfaces, RuntimeTypeHandleComparer.Instance, /* sync = */ false); s_runtimeTypeHandleToCCWTemplateIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalCCWTemplates, RuntimeTypeHandleComparer.Instance, /* sync = */ false); s_runtimeTypeHandleToClassIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalClasses, RuntimeTypeHandleComparer.Instance, /* sync = */ false); s_runtimeTypeHandleToCollectionIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalCollections, RuntimeTypeHandleComparer.Instance, /* sync = */ false); s_runtimeTypeHandleToBoxingIndexMap = new Collections.Generic.Internal.Dictionary <RuntimeTypeHandle, int>(totalBoxings, RuntimeTypeHandleComparer.Instance, /* sync = */ false); for (int moduleIndex = 0; moduleIndex < s_moduleCount; moduleIndex++) { McgInterfaceData[] interfaceData = s_modules[moduleIndex].GetAllInterfaceData(); if (interfaceData != null) { for (int typeIndex = 0; typeIndex < interfaceData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToInterfaceIndexMap, interfaceData[typeIndex].ItfType, moduleIndex, typeIndex); } } CCWTemplateData[] ccwTemplateData = s_modules[moduleIndex].GetAllCCWTemplateData(); if (ccwTemplateData != null) { for (int typeIndex = 0; typeIndex < ccwTemplateData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToCCWTemplateIndexMap, ccwTemplateData[typeIndex].ClassType, moduleIndex, typeIndex); } } McgClassData[] classData = s_modules[moduleIndex].GetAllClassData(); if (classData != null) { for (int typeIndex = 0; typeIndex < classData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToClassIndexMap, classData[typeIndex].ClassType, moduleIndex, typeIndex); } } McgCollectionData[] collectionData = s_modules[moduleIndex].GetAllCollectionData(); if (collectionData != null) { for (int typeIndex = 0; typeIndex < collectionData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToCollectionIndexMap, collectionData[typeIndex].CollectionType, moduleIndex, typeIndex); } } McgBoxingData[] boxingData = s_modules[moduleIndex].GetAllBoxingData(); if (boxingData != null) { for (int typeIndex = 0; typeIndex < boxingData.Length; typeIndex++) { InsertDataIntoDictionary(s_runtimeTypeHandleToBoxingIndexMap, boxingData[typeIndex].ManagedClassType, moduleIndex, typeIndex); } } } #if DEBUG if (McgModuleManager.UseDynamicInterop) { for (int moduleIndex = 0; moduleIndex < s_moduleCount; moduleIndex++) { s_modules[moduleIndex].VerifyWinRTGenericInterfaceGuids(); } } #endif }
internal static void RemoveAllEventHandlers(Action <EventRegistrationToken> removeMethod) { Debug.Assert(removeMethod != null); object instance = removeMethod.Target; System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> registrationTokens = GetEventRegistrationTokenTable(instance, removeMethod); System.Collections.Generic.Internal.List <EventRegistrationToken> tokensToRemove = new System.Collections.Generic.Internal.List <EventRegistrationToken>(); try { registrationTokens.LockAcquire(); // Copy all tokens to tokensToRemove array which later we'll call removeMethod on // outside this lock foreach (EventRegistrationTokenList tokens in registrationTokens.Values) { tokens.CopyTo(tokensToRemove); } // Clear the dictionary - at this point all event handlers are no longer in the cache // but they are not removed yet registrationTokens.Clear(); #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Cache cleared for managed instance = " + instance + "\n"); #endif } finally { registrationTokens.LockRelease(); } // // Remove all handlers outside the lock // #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Start removing all events for instance = " + instance + "\n"); #endif CallRemoveMethods(removeMethod, tokensToRemove); #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Finished removing all events for instance = " + instance + "\n"); #endif }
internal static void RemoveEventHandler <T>(Action <EventRegistrationToken> removeMethod, T handler) { Debug.Assert(removeMethod != null); object instance = removeMethod.Target; // // Temporary static event support - this is bad for a couple of reasons: // 1. This will leak the event delegates. Our real implementation fixes that // 2. We need the type itself, but we don't have delegate.Method.DeclaringType ( // but I don't know what is the best replacement). Perhaps this isn't too bad // 3. Unsubscription doesn't work due to ConditionalWeakTable work on reference equality. // I can fix this but I figured it is easier to keep this broken so that we know we'll fix // this (rather than using the slower value equality version which we might forget to fix // later // @TODO - Remove this and replace with real static support (that was #ifdef-ed out) // if (instance == null) { // Because this code only operates for delegates to static methods, the output typehandle of GetFunctionPointer is not used RuntimeTypeHandle thDummy; instance = removeMethod.GetFunctionPointer(out thDummy); } System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> registrationTokens = GetEventRegistrationTokenTable(instance, removeMethod); EventRegistrationToken token; try { registrationTokens.LockAcquire(); EventRegistrationTokenList tokens; // Failure to find a registration for a token is not an error - it's simply a no-op. if (!registrationTokens.TryGetValue(handler, out tokens)) { #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] no registrationTokens found for instance=" + instance + ", handler= " + handler + "\n"); #endif return; } // Select a registration token to unregister // We don't care which one but I'm returning the last registered token to be consistent // with native event registration implementation bool moreItems = tokens.Pop(out token); if (!moreItems) { // Remove it from cache if this list become empty // This must be done because EventRegistrationTokenList now becomes invalid // (mostly because there is no safe default value for EventRegistrationToken to express 'no token') // NOTE: We should try to remove registrationTokens itself from cache if it is empty, otherwise // we could run into a race condition where one thread removes it from cache and another thread adds // into the empty registrationToken table registrationTokens.Remove(handler); } } finally { registrationTokens.LockRelease(); } removeMethod(token); #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event unsubscribed for managed instance = " + instance + ", handler = " + handler + ", token = " + token.m_value + "\n"); #endif }
internal static void AddEventHandler <T>(Func <T, EventRegistrationToken> addMethod, Action <EventRegistrationToken> removeMethod, T handler) { Debug.Assert(addMethod != null); Debug.Assert(removeMethod != null); // Add the method, and make a note of the token -> delegate mapping. object instance = removeMethod.Target; #if !RHTESTCL Debug.Assert(instance != null && !(instance is __ComObject)); #endif System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> registrationTokens = GetEventRegistrationTokenTable(instance, removeMethod); EventRegistrationToken token = addMethod(handler); try { registrationTokens.LockAcquire(); EventRegistrationTokenList tokens; if (!registrationTokens.TryGetValue(handler, out tokens)) { tokens = new EventRegistrationTokenList(token); registrationTokens[handler] = tokens; } else { bool needCopy = tokens.Push(token); // You need to copy back this list into the dictionary (so that you don't lose change outside dictionary) if (needCopy) { registrationTokens[handler] = tokens; } } #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event subscribed for managed instance = " + instance + ", handler = " + handler + "\n"); #endif } finally { registrationTokens.LockRelease(); } }