Exemplo n.º 1
0
        /// <summary>
        /// given that 'eventRecord' is a TraceLogging event (with meta-data 'metaData'), return a eventID that is unique
        /// to that provider/opcode/meta-data blob.
        /// </summary>
        private ushort GetEventIDForTraceLoggingEvent(TraceEventNativeMethods.EVENT_RECORD *eventRecord, TraceEventNativeMethods.EVENT_HEADER_EXTENDED_DATA_ITEM *metaData)
        {
            Debug.Assert(metaData->ExtType == TraceEventNativeMethods.EVENT_HEADER_EXT_TYPE_EVENT_SCHEMA_TL);
            if (m_traceLoggingEventMap == null)     // Lazy init.
            {
                m_traceLoggingEventMap          = new Dictionary <ProviderMetaDataKey, ushort>();
                m_nextTraceLoggingIDForProvider = new Dictionary <Guid, ushort>();
            }

            // Check if I am in the table of assigned eventIds for this meta-data- blob
            ProviderMetaDataKey key = new ProviderMetaDataKey(&eventRecord->EventHeader.ProviderId, eventRecord->EventHeader.Opcode, (byte *)metaData->DataPtr, metaData->DataSize);
            ushort ret;

            if (!m_traceLoggingEventMap.TryGetValue(key, out ret))
            {
                // No then get the next ID for this particular provider (and allocate a new one)
                if (!m_nextTraceLoggingIDForProvider.TryGetValue(eventRecord->EventHeader.ProviderId, out ret))
                {
                    ret = 0xFF00;   // We arbitrarily pick the 'high end' of the event ID range to stay way from user-allocated IDs.   However we also avoid the last 256 ID just in case.
                }

                --ret;
                m_nextTraceLoggingIDForProvider[eventRecord->EventHeader.ProviderId] = ret;
                if (ret == 0) // means we wrapped around.  We have no more!
                {
                    throw new InvalidOperationException("Error ran out of TraceLogging Event IDs for provider " + eventRecord->EventHeader.ProviderId);
                }

                // Make a copy of memory the key points at.   Thus the table 'owns' the data the keys point at.
                // This is reclaimed in 'Dispose'
                int   copyDataSize = (key.DataSize + 3) & ~3;       // round it up to a multiple of 4.  CopyBlob requires this.
                byte *copy         = (byte *)Marshal.AllocHGlobal(copyDataSize + sizeof(Guid));
                key.Provider = (Guid *)(copy);
                *key.Provider = eventRecord->EventHeader.ProviderId;
                copy += sizeof(Guid);
                TraceEvent.CopyBlob((IntPtr)key.Data, (IntPtr)copy, copyDataSize);
                key.Data = copy;

                // Add the new key and eventID to the table.
                m_traceLoggingEventMap.Add(key, ret);
            }
            return(ret);
        }