Beispiel #1
0
        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);
        }
Beispiel #2
0
        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();
                }
            }
Beispiel #4
0
        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
        }
Beispiel #5
0
        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();
                }
            }