// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Diagnostics;
using System.Threading;
// Check for recursion, and force-stop any activities if the activity already started.
if ((options & EventActivityOptions.Recursive) == 0)
{
- ActivityInfo existingActivity = FindActiveActivity(fullActivityName, currentActivity);
+ ActivityInfo? existingActivity = FindActiveActivity(fullActivityName, currentActivity);
if (existingActivity != null)
{
OnStop(providerName, activityName, task, ref activityId);
for (; ; ) // This is a retry loop.
{
- ActivityInfo currentActivity = m_current.Value;
- ActivityInfo newCurrentActivity = null; // if we have seen any live activities (orphans), at he first one we have seen.
+ ActivityInfo? currentActivity = m_current.Value;
+ ActivityInfo? newCurrentActivity = null; // if we have seen any live activities (orphans), at he first one we have seen.
// Search to find the activity to stop in one pass. This insures that we don't let one mistake
// (stopping something that was not started) cause all active starts to be stopped
// By first finding the target start to stop we are more robust.
- ActivityInfo activityToStop = FindActiveActivity(fullActivityName, currentActivity);
+ ActivityInfo? activityToStop = FindActiveActivity(fullActivityName, currentActivity);
// ignore stops where we can't find a start because we may have popped them previously.
if (activityToStop == null)
activityId = activityToStop.ActivityId;
// See if there are any orphans that need to be stopped.
- ActivityInfo orphan = currentActivity;
+ ActivityInfo? orphan = currentActivity;
while (orphan != activityToStop && orphan != null)
{
if (orphan.m_stopped != 0) // Skip dead activities.
// Catch the not Implemented
try
{
- m_current = new AsyncLocal<ActivityInfo>(ActivityChanging);
+ m_current = new AsyncLocal<ActivityInfo?>(ActivityChanging);
}
catch (NotImplementedException) {
#if (!ES_BUILD_PCL && ! ES_BUILD_PN)
/// <summary>
/// Searched for a active (nonstopped) activity with the given name. Returns null if not found.
/// </summary>
- private ActivityInfo FindActiveActivity(string name, ActivityInfo startLocation)
+ private ActivityInfo? FindActiveActivity(string name, ActivityInfo? startLocation)
{
- var activity = startLocation;
+ ActivityInfo? activity = startLocation;
while (activity != null)
{
if (name == activity.m_name && activity.m_stopped == 0)
/// </summary>
private class ActivityInfo
{
- public ActivityInfo(string name, long uniqueId, ActivityInfo creator, Guid activityIDToRestore, EventActivityOptions options)
+ public ActivityInfo(string name, long uniqueId, ActivityInfo? creator, Guid activityIDToRestore, EventActivityOptions options)
{
m_name = name;
m_eventOptions = options;
}
}
- public static string Path(ActivityInfo activityInfo)
+ public static string Path(ActivityInfo? activityInfo)
{
if (activityInfo == null)
- return ("");
+ return "";
return Path(activityInfo.m_creator) + "/" + activityInfo.m_uniqueId.ToString();
}
return m_name + "(" + Path(this) + (m_stopped != 0 ? ",DEAD)" : ")");
}
- public static string LiveActivities(ActivityInfo list)
+ public static string LiveActivities(ActivityInfo? list)
{
if (list == null)
return "";
private unsafe void CreateOverflowGuid(Guid* outPtr)
{
// Search backwards for an ancestor that has sufficient space to put the ID.
- for (ActivityInfo ancestor = m_creator; ancestor != null; ancestor = ancestor.m_creator)
+ for (ActivityInfo? ancestor = m_creator; ancestor != null; ancestor = ancestor.m_creator)
{
if (ancestor.m_activityPathGuidOffset <= 10) // we need at least 2 bytes.
{
readonly internal EventActivityOptions m_eventOptions; // Options passed to start.
internal long m_lastChildID; // used to create a unique ID for my children activities
internal int m_stopped; // This work item has stopped
- readonly internal ActivityInfo m_creator; // My parent (creator). Forms the Path() for the activity.
+ readonly internal ActivityInfo? m_creator; // My parent (creator). Forms the Path() for the activity.
readonly internal Guid m_activityIdToRestore; // The Guid to restore after a stop.
#endregion
}
// This callback is used to initialize the m_current AsyncLocal Variable.
// Its job is to keep the ETW Activity ID (part of thread local storage) in sync
// with m_current.ActivityID
- void ActivityChanging(AsyncLocalValueChangedArgs<ActivityInfo> args)
+ void ActivityChanging(AsyncLocalValueChangedArgs<ActivityInfo?> args)
{
- ActivityInfo cur = args.CurrentValue;
- ActivityInfo prev = args.PreviousValue;
+ ActivityInfo? cur = args.CurrentValue;
+ ActivityInfo? prev = args.PreviousValue;
// Are we popping off a value? (we have a prev, and it creator is cur)
// Then check if we should use the GUID at the time of the start event
///
/// This variable points to a linked list that represents all Activities that have started but have not stopped.
/// </summary>
- AsyncLocal<ActivityInfo> m_current;
+ AsyncLocal<ActivityInfo?>? m_current;
bool m_checkedForEnable;
// Singleton
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Diagnostics;
using System.Collections;
_eventSource.EventCommandExecuted += OnEventSourceCommand;
}
- private void OnEventSourceCommand(object sender, EventCommandEventArgs e)
+ private void OnEventSourceCommand(object? sender, EventCommandEventArgs e)
{
if (e.Command == EventCommand.Enable || e.Command == EventCommand.Update)
{
string valueStr;
float value;
+ Debug.Assert(e.Arguments != null);
+
if (e.Arguments.TryGetValue("EventCounterIntervalSec", out valueStr) && float.TryParse(valueStr, out value))
{
// Recursion through EventSource callbacks possible. When we enable the timer
// We need eventCounters to 'attach' themselves to a particular EventSource.
// this table provides the mapping from EventSource -> CounterGroup
// which represents this 'attached' information.
- private static WeakReference<CounterGroup>[] s_counterGroups;
+ private static WeakReference<CounterGroup>[]? s_counterGroups;
private static readonly object s_counterGroupsLock = new object();
private static void EnsureEventSourceIndexAvailable(int eventSourceIndex)
{
int eventSourceIndex = EventListener.EventSourceIndex(eventSource);
EnsureEventSourceIndexAvailable(eventSourceIndex);
+ Debug.Assert(s_counterGroups != null);
WeakReference<CounterGroup> weakRef = CounterGroup.s_counterGroups[eventSourceIndex];
- CounterGroup ret = null;
+ CounterGroup? ret = null;
if (weakRef == null || !weakRef.TryGetTarget(out ret))
{
ret = new CounterGroup(eventSource);
private DateTime _timeStampSinceCollectionStarted;
private int _pollingIntervalInMilliseconds;
- private Timer _pollingTimer;
+ private Timer? _pollingTimer;
private void DisposeTimer()
{
restoreFlow = true;
}
- _pollingTimer = new Timer(s => ((CounterGroup)s).OnTimer(null), this, _pollingIntervalInMilliseconds, _pollingIntervalInMilliseconds);
+ _pollingTimer = new Timer(s => ((CounterGroup)s!).OnTimer(null), this, _pollingIntervalInMilliseconds, _pollingIntervalInMilliseconds);
}
finally
{
OnTimer(null);
}
- private void OnTimer(object state)
+ private void OnTimer(object? state)
{
Debug.WriteLine("Timer fired at " + DateTime.UtcNow.ToString("mm.ss.ffffff"));
lock (this) // Lock the CounterGroup
#endregion // Timer Processing
}
-}
\ No newline at end of file
+}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Diagnostics;
using System.Collections;
#endif
{
[EventData]
- internal class CounterPayload : IEnumerable<KeyValuePair<string, object>>
+ internal class CounterPayload : IEnumerable<KeyValuePair<string, object?>>
{
- public string Name { get; set; }
+ public string? Name { get; set; }
- public string DisplayName { get; set; }
+ public string? DisplayName { get; set; }
public double Mean { get; set; }
public float IntervalSec { get; internal set; }
- public string Metadata { get; set; }
+ public string? Metadata { get; set; }
#region Implementation of the IEnumerable interface
- public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
+ public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
{
return ForEnumeration.GetEnumerator();
}
return ForEnumeration.GetEnumerator();
}
- private IEnumerable<KeyValuePair<string, object>> ForEnumeration
+ private IEnumerable<KeyValuePair<string, object?>> ForEnumeration
{
get
{
- yield return new KeyValuePair<string, object>("Name", Name);
- yield return new KeyValuePair<string, object>("DisplayName", DisplayName);
- yield return new KeyValuePair<string, object>("Mean", Mean);
- yield return new KeyValuePair<string, object>("StandardDeviation", StandardDeviation);
- yield return new KeyValuePair<string, object>("Count", Count);
- yield return new KeyValuePair<string, object>("Min", Min);
- yield return new KeyValuePair<string, object>("Max", Max);
- yield return new KeyValuePair<string, object>("IntervalSec", IntervalSec);
- yield return new KeyValuePair<string, object>("Series", $"Interval={IntervalSec}");
- yield return new KeyValuePair<string, object>("CounterType", "Mean");
- yield return new KeyValuePair<string, object>("Metadata", Metadata);
+ yield return new KeyValuePair<string, object?>("Name", Name);
+ yield return new KeyValuePair<string, object?>("DisplayName", DisplayName);
+ yield return new KeyValuePair<string, object?>("Mean", Mean);
+ yield return new KeyValuePair<string, object?>("StandardDeviation", StandardDeviation);
+ yield return new KeyValuePair<string, object?>("Count", Count);
+ yield return new KeyValuePair<string, object?>("Min", Min);
+ yield return new KeyValuePair<string, object?>("Max", Max);
+ yield return new KeyValuePair<string, object?>("IntervalSec", IntervalSec);
+ yield return new KeyValuePair<string, object?>("Series", $"Interval={IntervalSec}");
+ yield return new KeyValuePair<string, object?>("CounterType", "Mean");
+ yield return new KeyValuePair<string, object?>("Metadata", Metadata);
}
}
}
[EventData]
- internal class IncrementingCounterPayload : IEnumerable<KeyValuePair<string, object>>
+ internal class IncrementingCounterPayload : IEnumerable<KeyValuePair<string, object?>>
{
- public string Name { get; set; }
+ public string? Name { get; set; }
- public string DisplayName { get; set; }
+ public string? DisplayName { get; set; }
- public string DisplayRateTimeScale { get; set; }
+ public string? DisplayRateTimeScale { get; set; }
public double Increment { get; set; }
public float IntervalSec { get; internal set; }
- public string Metadata { get; set; }
+ public string? Metadata { get; set; }
#region Implementation of the IEnumerable interface
- public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
+ public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
{
return ForEnumeration.GetEnumerator();
}
return ForEnumeration.GetEnumerator();
}
- private IEnumerable<KeyValuePair<string, object>> ForEnumeration
+ private IEnumerable<KeyValuePair<string, object?>> ForEnumeration
{
get
{
- yield return new KeyValuePair<string, object>("Name", Name);
- yield return new KeyValuePair<string, object>("DisplayName", DisplayName);
- yield return new KeyValuePair<string, object>("DisplayRateTimeScale", DisplayRateTimeScale);
- yield return new KeyValuePair<string, object>("Increment", Increment);
- yield return new KeyValuePair<string, object>("IntervalSec", IntervalSec);
- yield return new KeyValuePair<string, object>("Series", $"Interval={IntervalSec}");
- yield return new KeyValuePair<string, object>("CounterType", "Sum");
- yield return new KeyValuePair<string, object>("Metadata", Metadata);
+ yield return new KeyValuePair<string, object?>("Name", Name);
+ yield return new KeyValuePair<string, object?>("DisplayName", DisplayName);
+ yield return new KeyValuePair<string, object?>("DisplayRateTimeScale", DisplayRateTimeScale);
+ yield return new KeyValuePair<string, object?>("Increment", Increment);
+ yield return new KeyValuePair<string, object?>("IntervalSec", IntervalSec);
+ yield return new KeyValuePair<string, object?>("Series", $"Interval={IntervalSec}");
+ yield return new KeyValuePair<string, object?>("CounterType", "Sum");
+ yield return new KeyValuePair<string, object?>("Metadata", Metadata);
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Diagnostics;
using System.Collections;
if (_group != null)
{
_group.Remove(this);
- _group = null;
+ _group = null!; // TODO-NULLABLE: should not be nulled out
}
}
}
}
- public string DisplayName { get; set; }
+ public string? DisplayName { get; set; }
public string Name { get; }
#region private implementation
private CounterGroup _group;
- private Dictionary<string, string> _metadata;
+ private Dictionary<string, string>? _metadata;
internal abstract void WritePayload(float intervalSec);
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Diagnostics;
using System.Collections;
EventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new CounterPayloadType(payload));
}
}
+
private void ResetStatistics()
{
Debug.Assert(Monitor.IsEntered(MyLock));
private const int BufferedSize = 10;
private const double UnusedBufferSlotValue = double.NegativeInfinity;
private const int UnsetIndex = -1;
- private volatile double[] _bufferedValues;
+ private volatile double[] _bufferedValues = null!;
private volatile int _bufferedValuesIndex;
private void InitializeBuffer()
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Runtime.InteropServices;
}
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
if (!(obj is EventDescriptor))
return false;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+
+#nullable enable
using Microsoft.Win32;
using System.Collections.Generic;
using System.Diagnostics;
}
internal IEventProvider m_eventProvider; // The interface that implements the specific logging mechanism functions.
- Interop.Advapi32.EtwEnableCallback m_etwCallback; // Trace Callback function
+ Interop.Advapi32.EtwEnableCallback? m_etwCallback; // Trace Callback function
private long m_regHandle; // Trace Registration Handle
private byte m_level; // Tracing Level
private long m_anyKeywordMask; // Trace Enable Flags
private long m_allKeywordMask; // Match all keyword
- private List<SessionInfo> m_liveSessions; // current live sessions (Tuple<sessionIdBit, etwSessionId>)
+ private List<SessionInfo>? m_liveSessions; // current live sessions (Tuple<sessionIdBit, etwSessionId>)
private bool m_enabled; // Enabled flag from Trace callback
- private string m_providerName; // Control name
+ private string? m_providerName; // Control name
private Guid m_providerId; // Control Guid
internal bool m_disposed; // when true provider has unregistered
try
{
ControllerCommand command = ControllerCommand.Update;
- IDictionary<string, string> args = null;
+ IDictionary<string, string>? args = null;
bool skipFinalOnControllerCommand = false;
if (controlCode == Interop.Advapi32.EVENT_CONTROL_CODE_ENABLE_PROVIDER)
{
filterData = null;
// read filter data only when a session is being *added*
- byte[] data;
+ byte[]? data;
int keyIndex;
if (bEnabling &&
GetDataFromController(etwSessionId, filterData, out command, out data, out keyIndex))
{
args = new Dictionary<string, string>(4);
+ Debug.Assert(data != null); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
while (keyIndex < data.Length)
{
int keyEnd = FindNull(data, keyIndex);
}
// New in CLR4.0
- protected virtual void OnControllerCommand(ControllerCommand command, IDictionary<string, string> arguments, int sessionId, int etwSessionId) { }
+ protected virtual void OnControllerCommand(ControllerCommand command, IDictionary<string, string>? arguments, int sessionId, int etwSessionId) { }
protected EventLevel Level { get { return (EventLevel)m_level; } set { m_level = (byte)value; } }
protected EventKeywords MatchAnyKeyword { get { return (EventKeywords)m_anyKeywordMask; } set { m_anyKeywordMask = unchecked((long)value); } }
protected EventKeywords MatchAllKeyword { get { return (EventKeywords)m_allKeywordMask; } set { m_allKeywordMask = unchecked((long)value); } }
/// </summary>
private List<Tuple<SessionInfo, bool>> GetSessions()
{
- List<SessionInfo> liveSessionList = null;
+ List<SessionInfo>? liveSessionList = null;
GetSessionInfo(
- (int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList) =>
+ (int etwSessionId, long matchAllKeywords, ref List<SessionInfo>? sessionList) =>
GetSessionInfoCallback(etwSessionId, matchAllKeywords, ref sessionList),
ref liveSessionList);
{
int idx;
if ((idx = IndexOfSessionInList(liveSessionList, s.etwSessionId)) < 0 ||
- (liveSessionList[idx].sessionIdBit != s.sessionIdBit))
+ (liveSessionList![idx].sessionIdBit != s.sessionIdBit))
changedSessionList.Add(Tuple.Create(s, false));
}
{
int idx;
if ((idx = IndexOfSessionInList(m_liveSessions, s.etwSessionId)) < 0 ||
- (m_liveSessions[idx].sessionIdBit != s.sessionIdBit))
+ (m_liveSessions![idx].sessionIdBit != s.sessionIdBit))
changedSessionList.Add(Tuple.Create(s, true));
}
}
/// GetSessionInfo() passes in.
/// </summary>
private static void GetSessionInfoCallback(int etwSessionId, long matchAllKeywords,
- ref List<SessionInfo> sessionList)
+ ref List<SessionInfo>? sessionList)
{
uint sessionIdBitMask = (uint)SessionMask.FromEventKeywords(unchecked((ulong)matchAllKeywords));
// an ETW controller that specifies more than the mandated bit for our EventSource
sessionList.Add(new SessionInfo(val + 1, etwSessionId));
}
- private delegate void SessionInfoCallback(int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList);
+ private delegate void SessionInfoCallback(int etwSessionId, long matchAllKeywords, ref List<SessionInfo>? sessionList);
/// <summary>
/// This method enumerates over all active ETW sessions that have enabled 'this.m_Guid'
/// for the current process ID, calling 'action' for each session, and passing it the
/// ETW session and the 'AllKeywords' the session enabled for the current provider.
/// </summary>
- private unsafe void GetSessionInfo(SessionInfoCallback action, ref List<SessionInfo> sessionList)
+ private unsafe void GetSessionInfo(SessionInfoCallback action, ref List<SessionInfo>? sessionList)
{
// We wish the EventSource package to be legal for Windows Store applications.
// Currently EnumerateTraceGuidsEx is not an allowed API, so we avoid its use here
/// Returns the index of the SesisonInfo from 'sessions' that has the specified 'etwSessionId'
/// or -1 if the value is not present.
/// </summary>
- private static int IndexOfSessionInList(List<SessionInfo> sessions, int etwSessionId)
+ private static int IndexOfSessionInList(List<SessionInfo>? sessions, int etwSessionId)
{
if (sessions == null)
return -1;
/// starts, and the command being issued associated with that data.
/// </summary>
private unsafe bool GetDataFromController(int etwSessionId,
- Interop.Advapi32.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[] data, out int dataStart)
+ Interop.Advapi32.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[]? data, out int dataStart)
{
data = null;
dataStart = 0;
// <UsesUnsafeCode Name="Parameter dataDescriptor of type: EventData*" />
// <UsesUnsafeCode Name="Parameter dataBuffer of type: Byte*" />
// </SecurityKernel>
- private static unsafe object EncodeObject(ref object data, ref EventData* dataDescriptor, ref byte* dataBuffer, ref uint totalEventSize)
+ private static unsafe object? EncodeObject(ref object data, ref EventData* dataDescriptor, ref byte* dataBuffer, ref uint totalEventSize)
/*++
Routine Description:
Again:
dataDescriptor->Reserved = 0;
- string sRet = data as string;
- byte[] blobRet = null;
+ string? sRet = data as string;
+ byte[]? blobRet = null;
if (sRet != null)
{
if (data == null)
sRet = "";
else
- sRet = data.ToString();
+ sRet = data.ToString()!;
dataDescriptor->Size = ((uint)sRet.Length + 1) * 2;
}
dataDescriptor++;
dataBuffer += s_basicTypeAllocationBufferSize;
- return (object)sRet ?? (object)blobRet;
+ return (object?)sRet ?? (object?)blobRet;
}
/// <summary>
int index;
int refObjIndex = 0;
List<int> refObjPosition = new List<int>(s_etwAPIMaxRefObjCount);
- List<object> dataRefObj = new List<object>(s_etwAPIMaxRefObjCount);
+ List<object?> dataRefObj = new List<object?>(s_etwAPIMaxRefObjCount);
EventData* userData = stackalloc EventData[2 * argCount];
for (int i = 0; i < 2 * argCount; i++)
userData[i] = default;
{
if (eventPayload[index] != null)
{
- object supportedRefObj;
- supportedRefObj = EncodeObject(ref eventPayload[index], ref userDataPtr, ref currentBuffer, ref totalEventSize);
+ object? supportedRefObj = EncodeObject(ref eventPayload[index], ref userDataPtr, ref currentBuffer, ref totalEventSize);
if (supportedRefObj != null)
{
//
// now fix any string arguments and set the pointer on the data descriptor
//
- fixed (char* v0 = (string)dataRefObj[0], v1 = (string)dataRefObj[1], v2 = (string)dataRefObj[2], v3 = (string)dataRefObj[3],
- v4 = (string)dataRefObj[4], v5 = (string)dataRefObj[5], v6 = (string)dataRefObj[6], v7 = (string)dataRefObj[7])
+ fixed (char* v0 = (string?)dataRefObj[0], v1 = (string?)dataRefObj[1], v2 = (string?)dataRefObj[2], v3 = (string?)dataRefObj[3],
+ v4 = (string?)dataRefObj[4], v5 = (string?)dataRefObj[5], v6 = (string?)dataRefObj[6], v7 = (string?)dataRefObj[7])
{
userDataPtr = (EventData*)userData;
if (dataRefObj[0] != null)
rgGCHandle[i] = GCHandle.Alloc(dataRefObj[i], GCHandleType.Pinned);
if (dataRefObj[i] is string)
{
- fixed (char* p = (string)dataRefObj[i])
+ fixed (char* p = (string?)dataRefObj[i])
userDataPtr[refObjPosition[i]].Ptr = (ulong)p;
}
else
{
- fixed (byte* p = (byte[])dataRefObj[i])
+ fixed (byte* p = (byte[]?)dataRefObj[i])
userDataPtr[refObjPosition[i]].Ptr = (ulong)p;
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
// This program uses code hyperlinks available as part of the HyperAddin Visual Studio plug-in.
// It is available from http://www.codeplex.com/hyperAddin
#if ES_BUILD_STANDALONE
if (eventSourceType == null)
throw new ArgumentNullException(nameof(eventSourceType));
- EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute));
+ EventSourceAttribute? attrib = (EventSourceAttribute?)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute));
string name = eventSourceType.Name;
if (attrib != null)
{
/// <param name="assemblyPathToIncludeInManifest">The manifest XML fragment contains the string name of the DLL name in
/// which it is embedded. This parameter specifies what name will be used</param>
/// <returns>The XML data string</returns>
- public static string GenerateManifest(Type eventSourceType, string assemblyPathToIncludeInManifest)
+ public static string? GenerateManifest(Type eventSourceType, string? assemblyPathToIncludeInManifest)
{
return GenerateManifest(eventSourceType, assemblyPathToIncludeInManifest, EventManifestOptions.None);
}
/// <param name="flags">The flags to customize manifest generation. If flags has bit OnlyIfNeededForRegistration specified
/// this returns null when the eventSourceType does not require explicit registration</param>
/// <returns>The XML data string or null</returns>
- public static string GenerateManifest(Type eventSourceType, string assemblyPathToIncludeInManifest, EventManifestOptions flags)
+ public static string? GenerateManifest(Type eventSourceType, string? assemblyPathToIncludeInManifest, EventManifestOptions flags)
{
if (eventSourceType == null)
throw new ArgumentNullException(nameof(eventSourceType));
- byte[] manifestBytes = EventSource.CreateManifestAndDescriptors(eventSourceType, assemblyPathToIncludeInManifest, null, flags);
+ byte[]? manifestBytes = EventSource.CreateManifestAndDescriptors(eventSourceType, assemblyPathToIncludeInManifest, null, flags);
return (manifestBytes == null) ? null : Encoding.UTF8.GetString(manifestBytes, 0, manifestBytes.Length);
}
var ret = new List<EventSource>();
lock (EventListener.EventListenersLock)
{
+ Debug.Assert(EventListener.s_EventSources != null);
+
foreach (WeakReference eventSourceRef in EventListener.s_EventSources)
{
if (eventSourceRef.Target is EventSource eventSource && !eventSource.IsDisposed)
/// <param name="eventSource">The instance of EventSource to send the command to</param>
/// <param name="command">A positive user-defined EventCommand, or EventCommand.SendManifest</param>
/// <param name="commandArguments">A set of (name-argument, value-argument) pairs associated with the command</param>
- public static void SendCommand(EventSource eventSource, EventCommand command, IDictionary<string, string> commandArguments)
+ public static void SendCommand(EventSource eventSource, EventCommand command, IDictionary<string, string>? commandArguments)
{
if (eventSource == null)
throw new ArgumentNullException(nameof(eventSource));
/// The event source constructor does not throw exceptions. Instead we remember any exception that
/// was generated (it is also logged to Trace.WriteLine).
/// </summary>
- public Exception ConstructionException { get { return m_constructionException; } }
+ public Exception? ConstructionException { get { return m_constructionException; } }
/// <summary>
/// EventSources can have arbitrary string key-value pairs associated with them called Traits.
/// </summary>
/// <param name="key">The key to look up in the set of key-value pairs passed to the EventSource constructor</param>
/// <returns>The value string associated with key. Will return null if there is no such key.</returns>
- public string GetTrait(string key)
+ public string? GetTrait(string key)
{
if (m_traits != null)
{
return m_traits[i + 1];
}
}
+
return null;
}
// If we have an EventHandler<EventCommandEventArgs> attached to the EventSource before the first command arrives
// It should get a chance to handle the deferred commands.
- EventCommandEventArgs deferredCommands = m_deferredCommands;
+ EventCommandEventArgs? deferredCommands = m_deferredCommands;
while (deferredCommands != null)
{
value(this, deferredCommands);
/// </summary>
/// <param name="settings">See EventSourceSettings for more.</param>
/// <param name="traits">A collection of key-value strings (must be an even number).</param>
- protected EventSource(EventSourceSettings settings, params string[] traits)
+ protected EventSource(EventSourceSettings settings, params string[]? traits)
{
m_config = ValidateSettings(settings);
Guid eventSourceGuid;
- string eventSourceName;
+ string? eventSourceName;
- EventMetadata[] eventDescriptors;
- byte[] manifest;
+ EventMetadata[]? eventDescriptors;
+ byte[]? manifest;
GetMetadata(out eventSourceGuid, out eventSourceName, out eventDescriptors, out manifest);
if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null)
}
#endif
- internal virtual void GetMetadata(out Guid eventSourceGuid, out string eventSourceName, out EventMetadata[] eventData, out byte[] manifestBytes)
+ internal virtual void GetMetadata(out Guid eventSourceGuid, out string? eventSourceName, out EventMetadata[]? eventData, out byte[]? manifestBytes)
{
//
// In ProjectN subclasses need to override this method, and return the data from their EventSourceAttribute and EventAttribute annotations.
// optimized for common signatures (strings)
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1)
+ protected unsafe void WriteEvent(int eventId, string? arg1)
{
if (m_eventSourceEnabled)
{
}
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, string arg2)
+ protected unsafe void WriteEvent(int eventId, string? arg1, string? arg2)
{
if (m_eventSourceEnabled)
{
}
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, string arg2, string arg3)
+ protected unsafe void WriteEvent(int eventId, string? arg1, string? arg2, string? arg3)
{
if (m_eventSourceEnabled)
{
// optimized for common signatures (string and ints)
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, int arg2)
+ protected unsafe void WriteEvent(int eventId, string? arg1, int arg2)
{
if (m_eventSourceEnabled)
{
}
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, int arg2, int arg3)
+ protected unsafe void WriteEvent(int eventId, string? arg1, int arg2, int arg3)
{
if (m_eventSourceEnabled)
{
// optimized for common signatures (string and longs)
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, long arg2)
+ protected unsafe void WriteEvent(int eventId, string? arg1, long arg2)
{
if (m_eventSourceEnabled)
{
// optimized for common signatures (long and string)
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, long arg1, string arg2)
+ protected unsafe void WriteEvent(int eventId, long arg1, string? arg2)
{
if (m_eventSourceEnabled)
{
// optimized for common signatures (int and string)
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, int arg1, string arg2)
+ protected unsafe void WriteEvent(int eventId, int arg1, string? arg2)
{
if (m_eventSourceEnabled)
{
}
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, byte[] arg1)
+ protected unsafe void WriteEvent(int eventId, byte[]? arg1)
{
if (m_eventSourceEnabled)
{
}
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, long arg1, byte[] arg2)
+ protected unsafe void WriteEvent(int eventId, long arg1, byte[]? arg2)
{
if (m_eventSourceEnabled)
{
{
if (m_eventSourceEnabled)
{
+ Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
try
{
- Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
if (relatedActivityId != null)
ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name);
}
else
{
- TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
+ TraceLoggingEventTypes? tlet = m_eventData[eventId].TraceLoggingEventTypes;
if (tlet == null)
{
tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
if (m_etwProvider != null)
{
m_etwProvider.Dispose();
- m_etwProvider = null;
+ m_etwProvider = null!; // TODO-NULLABLE: should not be nulled out on Dispose
}
#endif
#if FEATURE_PERFTRACING
if (m_eventPipeProvider != null)
{
m_eventPipeProvider.Dispose();
- m_eventPipeProvider = null;
+ m_eventPipeProvider = null!; // TODO-NULLABLE: should not be nulled out on Dispose
}
#endif
}
#region private
private unsafe void WriteEventRaw(
- string eventName,
+ string? eventName,
ref EventDescriptor eventDescriptor,
IntPtr eventHandle,
Guid* activityID,
{ }
// Used by the internal FrameworkEventSource constructor and the TraceLogging-style event source constructor
- internal EventSource(Guid eventSourceGuid, string eventSourceName, EventSourceSettings settings, string[] traits = null)
+ internal EventSource(Guid eventSourceGuid, string eventSourceName, EventSourceSettings settings, string[]? traits = null)
{
m_config = ValidateSettings(settings);
Initialize(eventSourceGuid, eventSourceName, traits);
/// member, and any future access to the "Log" would throw the cached exception).
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "guid")]
- private unsafe void Initialize(Guid eventSourceGuid, string eventSourceName, string[] traits)
+ private unsafe void Initialize(Guid eventSourceGuid, string eventSourceName, string[]? traits)
{
try
{
// This is the most likely place for exceptions to happen.
// Note that we are NOT resetting m_deferredCommands to NULL here,
// We are giving for EventHandler<EventCommandEventArgs> that will be attached later
- EventCommandEventArgs deferredCommands = m_deferredCommands;
+ EventCommandEventArgs? deferredCommands = m_deferredCommands;
while (deferredCommands != null)
{
DoCommand(deferredCommands); // This can never throw, it catches them and reports the errors.
if (eventSourceType == null)
throw new ArgumentNullException(nameof(eventSourceType));
- EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags);
+ EventSourceAttribute? attrib = (EventSourceAttribute?)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags);
if (attrib != null && attrib.Name != null)
return attrib.Name;
hash.Start();
hash.Append(namespaceBytes);
hash.Append(bytes);
- Array.Resize(ref bytes, 16);
+ Array.Resize(ref bytes!, 16); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
hash.Finish(bytes);
bytes[7] = unchecked((byte)((bytes[7] & 0x0F) | 0x50)); // Set high 4 bits of octet 7 to 5, as per RFC 4122
return new Guid(bytes);
}
- private unsafe object DecodeObject(int eventId, int parameterId, ref EventSource.EventData* data)
+ private unsafe object? DecodeObject(int eventId, int parameterId, ref EventSource.EventData* data)
{
// TODO FIX : We use reflection which in turn uses EventSource, right now we carefully avoid
// the recursion, but can we do this in a robust way?
// advance to next EventData in array
++data;
+ Debug.Assert(m_eventData != null);
Type dataType = GetDataType(m_eventData[eventId], parameterId);
Again:
// Finds the Dispatcher (which holds the filtering state), for a given dispatcher for the current
// eventSource).
- private EventDispatcher GetDispatcher(EventListener listener)
+ private EventDispatcher? GetDispatcher(EventListener? listener)
{
- EventDispatcher dispatcher = m_Dispatchers;
+ EventDispatcher? dispatcher = m_Dispatchers;
while (dispatcher != null)
{
if (dispatcher.m_Listener == listener)
{
if (m_eventSourceEnabled)
{
+ Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
try
{
- Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
if (childActivityID != null)
{
ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name);
}
else
{
- TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
+ TraceLoggingEventTypes? tlet = m_eventData[eventId].TraceLoggingEventTypes;
if (tlet == null)
{
tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
else
#endif // !ES_BUILD_STANDALONE
{
- object[] serializedArgs = SerializeEventArgs(eventId, args);
+ object?[] serializedArgs = SerializeEventArgs(eventId, args);
WriteToAllListeners(
eventId: eventId,
osThreadId: null,
}
}
- private unsafe object[] SerializeEventArgs(int eventId, object[] args)
+ private unsafe object?[] SerializeEventArgs(int eventId, object?[] args)
{
- TraceLoggingEventTypes eventTypes = m_eventData[eventId].TraceLoggingEventTypes;
+ Debug.Assert(m_eventData != null);
+ TraceLoggingEventTypes? eventTypes = m_eventData[eventId].TraceLoggingEventTypes;
if (eventTypes == null)
{
eventTypes = new TraceLoggingEventTypes(m_eventData[eventId].Name,
m_eventData[eventId].Parameters);
Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, eventTypes, null);
}
- var eventData = new object[eventTypes.typeInfos.Length];
+ var eventData = new object?[eventTypes.typeInfos.Length];
for (int i = 0; i < eventTypes.typeInfos.Length; i++)
{
eventData[i] = eventTypes.typeInfos[i].GetData(args[i]);
private unsafe void WriteToAllListeners(int eventId, Guid* activityID, Guid* childActivityID, int eventDataCount, EventSource.EventData* data)
{
+ Debug.Assert(m_eventData != null);
// We represent a byte[] as a integer denoting the length and then a blob of bytes in the data pointer. This causes a spurious
// warning because eventDataCount is off by one for the byte[] case since a byte[] has 2 items associated it. So we want to check
// that the number of parameters is correct against the byte[] case, but also we the args array would be one too long if
paramCount = Math.Min(paramCount, eventDataCount);
}
- object[] args = new object[paramCount];
+ object?[] args = new object[paramCount];
EventSource.EventData* dataPtr = data;
for (int i = 0; i < paramCount; i++)
}
// helper for writing to all EventListeners attached the current eventSource.
- internal unsafe void WriteToAllListeners(int eventId, uint* osThreadId, DateTime* timeStamp, Guid* activityID, Guid* childActivityID, params object[] args)
+ internal unsafe void WriteToAllListeners(int eventId, uint* osThreadId, DateTime* timeStamp, Guid* activityID, Guid* childActivityID, params object?[] args)
{
EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
eventCallbackArgs.EventId = eventId;
eventCallbackArgs.ActivityId = *activityID;
if (childActivityID != null)
eventCallbackArgs.RelatedActivityId = *childActivityID;
+
+ Debug.Assert(m_eventData != null);
eventCallbackArgs.EventName = m_eventData[eventId].Name;
eventCallbackArgs.Message = m_eventData[eventId].Message;
- eventCallbackArgs.Payload = new ReadOnlyCollection<object>(args);
+ eventCallbackArgs.Payload = new ReadOnlyCollection<object?>(args);
DispatchToAllListeners(eventId, childActivityID, eventCallbackArgs);
}
private unsafe void DispatchToAllListeners(int eventId, Guid* childActivityID, EventWrittenEventArgs eventCallbackArgs)
{
- Exception lastThrownException = null;
- for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
+ Exception? lastThrownException = null;
+ for (EventDispatcher? dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
{
Debug.Assert(dispatcher.m_EventEnabled != null);
if (eventId == -1 || dispatcher.m_EventEnabled[eventId])
EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
eventCallbackArgs.EventId = 0;
eventCallbackArgs.Message = msg;
- eventCallbackArgs.Payload = new ReadOnlyCollection<object>(new List<object>() { msg });
+ eventCallbackArgs.Payload = new ReadOnlyCollection<object?>(new List<object?>() { msg });
eventCallbackArgs.PayloadNames = new ReadOnlyCollection<string>(new List<string> { "message" });
eventCallbackArgs.EventName = eventName;
- for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
+ for (EventDispatcher? dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
{
bool dispatcherEnabled = false;
if (dispatcher.m_EventEnabled == null)
if (!enable)
return false;
+ Debug.Assert(m_eventData != null);
EventLevel eventLevel = (EventLevel)m_eventData[eventNum].Descriptor.Level;
EventKeywords eventKeywords = unchecked((EventKeywords)((ulong)m_eventData[eventNum].Descriptor.Keywords & (~(SessionMask.All.ToEventKeywords()))));
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- private void ThrowEventSourceException(string eventName, Exception innerEx = null)
+ private void ThrowEventSourceException(string? eventName, Exception? innerEx = null)
{
// If we fail during out of band logging we may end up trying
// to throw another EventSourceException, thus hitting a StackOverflowException.
}
}
- private void ValidateEventOpcodeForTransfer(ref EventMetadata eventData, string eventName)
+ private void ValidateEventOpcodeForTransfer(ref EventMetadata eventData, string? eventName)
{
if ((EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Send &&
(EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Receive &&
}
}
- internal static EventOpcode GetOpcodeWithDefault(EventOpcode opcode, string eventName)
+ internal static EventOpcode GetOpcodeWithDefault(EventOpcode opcode, string? eventName)
{
if (opcode == EventOpcode.Info && eventName != null)
{
this.m_eventSource = eventSource;
this.m_eventProviderType = providerType;
}
- protected override void OnControllerCommand(ControllerCommand command, IDictionary<string, string> arguments,
+ protected override void OnControllerCommand(ControllerCommand command, IDictionary<string, string>? arguments,
int perEventSourceSessionId, int etwSessionId)
{
// We use null to represent the ETW EventListener.
- EventListener listener = null;
+ EventListener? listener = null;
m_eventSource.SendCommand(listener, m_eventProviderType, perEventSourceSessionId, etwSessionId,
(EventCommand)command, IsEnabled(), Level, MatchAnyKeyword, arguments);
}
public byte TriggersActivityTracking; // count of listeners that marked this event as trigger for start of activity logging.
#pragma warning restore 0649
public string Name; // the name of the event
- public string Message; // If the event has a message associated with it, this is it.
+ public string? Message; // If the event has a message associated with it, this is it.
public ParameterInfo[] Parameters; // TODO can we remove?
- public TraceLoggingEventTypes TraceLoggingEventTypes;
+ public TraceLoggingEventTypes? TraceLoggingEventTypes;
public EventActivityOptions ActivityOptions;
#if ES_BUILD_PN
// * The 'enabled' 'level', matchAnyKeyword' arguments are ignored (must be true, 0, 0).
//
// dispatcher == null has special meaning. It is the 'ETW' dispatcher.
- internal void SendCommand(EventListener listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId,
+ internal void SendCommand(EventListener? listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId,
EventCommand command, bool enable,
EventLevel level, EventKeywords matchAnyKeyword,
- IDictionary<string, string> commandArguments)
+ IDictionary<string, string>? commandArguments)
{
var commandArgs = new EventCommandEventArgs(command, commandArguments, this, listener, eventProviderType, perEventSourceSessionId, etwSessionId, enable, level, matchAnyKeyword);
lock (EventListener.EventListenersLock)
for (int i = 0; i < m_eventData.Length; i++)
{
bool isEnabledForAnyListener = false;
- for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
+ for (EventDispatcher? dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
{
+ Debug.Assert(dispatcher.m_EventEnabled != null);
+
if (dispatcher.m_EventEnabled[i])
{
isEnabledForAnyListener = true;
/// of 'eventId. If value is 'false' disable the event for that dispatcher. If 'eventId' is out of
/// range return false, otherwise true.
/// </summary>
- internal bool EnableEventForDispatcher(EventDispatcher dispatcher, EventProviderType eventProviderType, int eventId, bool value)
+ internal bool EnableEventForDispatcher(EventDispatcher? dispatcher, EventProviderType eventProviderType, int eventId, bool value)
{
+ Debug.Assert(m_eventData != null);
+
if (dispatcher == null)
{
if (eventId >= m_eventData.Length)
}
else
{
+ Debug.Assert(dispatcher.m_EventEnabled != null);
if (eventId >= dispatcher.m_EventEnabled.Length)
return false;
dispatcher.m_EventEnabled[eventId] = value;
/// </summary>
private bool AnyEventEnabled()
{
+ Debug.Assert(m_eventData != null);
+
for (int i = 0; i < m_eventData.Length; i++)
if (m_eventData[i].EnabledForETW || m_eventData[i].EnabledForAnyListener
#if FEATURE_PERFTRACING
if (m_eventData == null)
{
Guid eventSourceGuid = Guid.Empty;
- string eventSourceName = null;
- EventMetadata[] eventData = null;
- byte[] manifest = null;
+ string? eventSourceName = null;
+ EventMetadata[]? eventData = null;
+ byte[]? manifest = null;
// Try the GetMetadata provided by the ILTransform in ProjectN. The default sets all to null, and in that case we fall back
// to the reflection approach.
m_rawManifest = CreateManifestAndDescriptors(this.GetType(), Name, this);
Debug.Assert(m_eventData != null);
-
}
else
{
m_rawManifest = manifest;
}
// TODO Enforce singleton pattern
+ Debug.Assert(EventListener.s_EventSources != null, "should be called within lock on EventListener.EventListenersLock which ensures s_EventSources to be initialized");
foreach (WeakReference eventSourceRef in EventListener.s_EventSources)
{
if (eventSourceRef.Target is EventSource eventSource && eventSource.Guid == m_guid && !eventSource.IsDisposed)
}
// Make certain all dispatchers also have their arrays initialized
- EventDispatcher dispatcher = m_Dispatchers;
+ EventDispatcher? dispatcher = m_Dispatchers;
while (dispatcher != null)
{
if (dispatcher.m_EventEnabled == null)
// Send out the ETW manifest XML out to ETW
// Today, we only send the manifest to ETW, custom listeners don't get it.
- private unsafe bool SendManifest(byte[] rawManifest)
+ private unsafe bool SendManifest(byte[]? rawManifest)
{
bool success = true;
// Helper to deal with the fact that the type we are reflecting over might be loaded in the ReflectionOnly context.
// When that is the case, we have the build the custom assemblies on a member by hand.
- internal static Attribute GetCustomAttributeHelper(MemberInfo member, Type attributeType, EventManifestOptions flags = EventManifestOptions.None)
+ internal static Attribute? GetCustomAttributeHelper(MemberInfo member, Type attributeType, EventManifestOptions flags = EventManifestOptions.None)
{
#if !ES_BUILD_PN
// On ProjectN, ReflectionOnly() always equals false. AllowEventSourceOverride is an option that allows either Microsoft.Diagnostics.Tracing or
#endif // !ES_BUILD_PN
{
// Let the runtime to the work for us, since we can execute code in this context.
- Attribute firstAttribute = null;
+ Attribute? firstAttribute = null;
foreach (var attribute in member.GetCustomAttributes(attributeType, false))
{
firstAttribute = (Attribute)attribute;
{
if (AttributeTypeNamesMatch(attributeType, data.Constructor.ReflectedType))
{
- Attribute attr = null;
+ Attribute? attr = null;
Debug.Assert(data.ConstructorArguments.Count <= 1);
if (data.ConstructorArguments.Count == 1)
{
- attr = (Attribute)Activator.CreateInstance(attributeType, new object[] { data.ConstructorArguments[0].Value });
+ attr = (Attribute?)Activator.CreateInstance(attributeType, new object[] { data.ConstructorArguments[0].Value });
}
else if (data.ConstructorArguments.Count == 0)
{
- attr = (Attribute)Activator.CreateInstance(attributeType);
+ attr = (Attribute?)Activator.CreateInstance(attributeType);
}
if (attr != null)
if (p.PropertyType.IsEnum)
{
- value = Enum.Parse(p.PropertyType, value.ToString());
+ string val = value.ToString()!;
+ value = Enum.Parse(p.PropertyType, val);
}
p.SetValue(attr, value, null);
);
}
- private static Type GetEventSourceBaseType(Type eventSourceType, bool allowEventSourceOverride, bool reflectionOnly)
+ private static Type? GetEventSourceBaseType(Type eventSourceType, bool allowEventSourceOverride, bool reflectionOnly)
{
+ Type? ret = eventSourceType;
+
// return false for "object" and interfaces
- if (eventSourceType.BaseType() == null)
+ if (ret.BaseType() == null)
return null;
// now go up the inheritance chain until hitting a concrete type ("object" at worse)
do
{
- eventSourceType = eventSourceType.BaseType();
+ ret = ret.BaseType();
}
- while (eventSourceType != null && eventSourceType.IsAbstract());
+ while (ret != null && ret.IsAbstract());
- if (eventSourceType != null)
+ if (ret != null)
{
if (!allowEventSourceOverride)
{
- if (reflectionOnly && eventSourceType.FullName != typeof(EventSource).FullName ||
- !reflectionOnly && eventSourceType != typeof(EventSource))
+ if (reflectionOnly && ret.FullName != typeof(EventSource).FullName ||
+ !reflectionOnly && ret != typeof(EventSource))
return null;
}
else
{
- if (eventSourceType.Name != "EventSource")
+ if (ret.Name != "EventSource")
return null;
}
}
- return eventSourceType;
+ return ret;
}
// Use reflection to look at the attributes of a class, and generate a manifest for it (as UTF8) and
// return the UTF8 bytes. It also sets up the code:EventData structures needed to dispatch events
// at run time. 'source' is the event source to place the descriptors. If it is null,
// then the descriptors are not creaed, and just the manifest is generated.
- private static byte[] CreateManifestAndDescriptors(Type eventSourceType, string eventSourceDllName, EventSource source,
+ private static byte[]? CreateManifestAndDescriptors(Type eventSourceType, string? eventSourceDllName, EventSource? source,
EventManifestOptions flags = EventManifestOptions.None)
{
- ManifestBuilder manifest = null;
+ ManifestBuilder? manifest = null;
bool bNeedsManifest = source != null ? !source.SelfDescribingEvents : true;
- Exception exception = null; // exception that might get raised during validation b/c we couldn't/didn't recover from a previous error
- byte[] res = null;
+ Exception? exception = null; // exception that might get raised during validation b/c we couldn't/didn't recover from a previous error
+ byte[]? res = null;
if (eventSourceType.IsAbstract() && (flags & EventManifestOptions.Strict) == 0)
return null;
MethodInfo[] methods = eventSourceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
EventAttribute defaultEventAttribute;
int eventId = 1; // The number given to an event that does not have a explicitly given ID.
- EventMetadata[] eventData = null;
- Dictionary<string, string> eventsByName = null;
+ EventMetadata[]? eventData = null;
+ Dictionary<string, string>? eventsByName = null;
if (source != null || (flags & EventManifestOptions.Strict) != 0)
{
eventData = new EventMetadata[methods.Length + 1];
}
// See if we have localization information.
- ResourceManager resources = null;
- EventSourceAttribute eventSourceAttrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags);
+ ResourceManager? resources = null;
+ EventSourceAttribute? eventSourceAttrib = (EventSourceAttribute?)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags);
if (eventSourceAttrib != null && eventSourceAttrib.LocalizationResources != null)
resources = new ResourceManager(eventSourceAttrib.LocalizationResources, eventSourceType.Assembly());
ParameterInfo[] args = method.GetParameters();
// Get the EventDescriptor (from the Custom attributes)
- EventAttribute eventAttribute = (EventAttribute)GetCustomAttributeHelper(method, typeof(EventAttribute), flags);
+ EventAttribute? eventAttribute = (EventAttribute?)GetCustomAttributeHelper(method, typeof(EventAttribute), flags);
// Compat: until v4.5.1 we ignored any non-void returning methods as well as virtual methods for
// the only reason of limiting the number of methods considered to be events. This broke a common
bool hasRelatedActivityID = RemoveFirstArgIfRelatedActivityId(ref args);
if (!(source != null && source.SelfDescribingEvents))
{
+ Debug.Assert(eventData != null);
manifest.StartEvent(eventName, eventAttribute);
for (int fieldIdx = 0; fieldIdx < args.Length; fieldIdx++)
{
if (source != null || (flags & EventManifestOptions.Strict) != 0)
{
+ Debug.Assert(eventData != null);
// Do checking for user errors (optional, but not a big deal so we do it).
DebugCheckEvent(ref eventsByName, eventData, method, eventAttribute, manifest, flags);
}
#endif
string eventKey = "event_" + eventName;
- string msg = manifest.GetLocalizedMessage(eventKey, CultureInfo.CurrentUICulture, etwFormat: false);
+ string? msg = manifest.GetLocalizedMessage(eventKey, CultureInfo.CurrentUICulture, etwFormat: false);
// overwrite inline message with the localized message
if (msg != null) eventAttribute.Message = msg;
- AddEventDescriptor(ref eventData, eventName, eventAttribute, args, hasRelatedActivityID);
+ AddEventDescriptor(ref eventData!, eventName, eventAttribute, args, hasRelatedActivityID); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34874
}
}
}
if (source != null)
{
- TrimEventDescriptors(ref eventData);
+ Debug.Assert(eventData != null);
+ TrimEventDescriptors(ref eventData!); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34874
source.m_eventData = eventData; // officially initialize it. We do this at most once (it is racy otherwise).
#if FEATURE_MANAGED_ETW_CHANNELS
source.m_channelData = manifest.GetChannelData();
exception = e;
}
+ Debug.Assert((flags & EventManifestOptions.Strict) != 0 && manifest != null); // TODO-NULLABLE: possible bug: if error is thrown before manifest is assigned in non-strict mode, this will NRE
if ((flags & EventManifestOptions.Strict) != 0 && (manifest.Errors.Count > 0 || exception != null))
{
string msg = string.Empty;
+
if (manifest.Errors.Count > 0)
{
bool firstError = true;
}
}
else
- msg = "Unexpected error: " + exception.Message;
+ msg = "Unexpected error: " + exception!.Message;
throw new ArgumentException(msg, exception);
}
{
if (eventData == null || eventData.Length <= eventAttribute.EventId)
{
+ Debug.Assert(eventData != null); // TODO-NULLABLE: possible bug in the code: NRE when eventData == null
EventMetadata[] newValues = new EventMetadata[Math.Max(eventData.Length + 16, eventAttribute.EventId + 1)];
Array.Copy(eventData, 0, newValues, 0, eventData.Length);
eventData = newValues;
{
lock (EventListener.EventListenersLock)
{
- bool[] enabledArray = null;
+ bool[]? enabledArray = null;
if (m_eventData != null)
enabledArray = new bool[m_eventData.Length];
m_Dispatchers = new EventDispatcher(m_Dispatchers, enabledArray, listener);
// Helper used by code:CreateManifestAndDescriptors to find user mistakes like reusing an event
// index for two distinct events etc. Throws exceptions when it finds something wrong.
- private static void DebugCheckEvent(ref Dictionary<string, string> eventsByName,
+ private static void DebugCheckEvent(ref Dictionary<string, string>? eventsByName,
EventMetadata[] eventData, MethodInfo method, EventAttribute eventAttribute,
ManifestBuilder manifest, EventManifestOptions options)
{
}
// private instance state
- private string m_name; // My friendly name (privided in ctor)
+ private string m_name = null!; // My friendly name (privided in ctor)
internal int m_id; // A small integer that is unique to this instance.
private Guid m_guid; // GUID representing the ETW eventSource to the OS.
- internal volatile EventMetadata[] m_eventData; // None per-event data
- private volatile byte[] m_rawManifest; // Bytes to send out representing the event schema
+ internal volatile EventMetadata[]? m_eventData; // None per-event data
+ private volatile byte[]? m_rawManifest; // Bytes to send out representing the event schema
- private EventHandler<EventCommandEventArgs> m_eventCommandExecuted;
+ private EventHandler<EventCommandEventArgs>? m_eventCommandExecuted;
private EventSourceSettings m_config; // configuration information
internal EventKeywords m_matchAnyKeyword; // the logical OR of all levels enabled by any output dispatcher (zero is a special case) meaning 'all keywords'
// Dispatching state
- internal volatile EventDispatcher m_Dispatchers; // Linked list of code:EventDispatchers we write the data to (we also do ETW specially)
+ internal volatile EventDispatcher? m_Dispatchers; // Linked list of code:EventDispatchers we write the data to (we also do ETW specially)
#if FEATURE_MANAGED_ETW
- private volatile OverideEventProvider m_etwProvider; // This hooks up ETW commands to our 'OnEventCommand' callback
+ private volatile OverideEventProvider m_etwProvider = null!; // This hooks up ETW commands to our 'OnEventCommand' callback
#endif
#if FEATURE_PERFTRACING
- private volatile OverideEventProvider m_eventPipeProvider;
+ private volatile OverideEventProvider m_eventPipeProvider = null!;
#endif
private bool m_completelyInited; // The EventSource constructor has returned without exception.
- private Exception m_constructionException; // If there was an exception construction, this is it
+ private Exception? m_constructionException; // If there was an exception construction, this is it
private byte m_outOfBandMessageCount; // The number of out of band messages sent (we throttle them
- private EventCommandEventArgs m_deferredCommands;// If we get commands before we are fully we store them here and run the when we are fully inited.
+ private EventCommandEventArgs? m_deferredCommands;// If we get commands before we are fully we store them here and run the when we are fully inited.
- private string[] m_traits; // Used to implement GetTraits
+ private string[]? m_traits; // Used to implement GetTraits
internal static uint s_currentPid; // current process id, used in synthesizing quasi-GUIDs
[ThreadStatic]
private static bool m_EventSourceInDecodeObject = false;
#if FEATURE_MANAGED_ETW_CHANNELS
- internal volatile ulong[] m_channelData;
+ internal volatile ulong[]? m_channelData;
#endif
// We use a single instance of ActivityTracker for all EventSources instances to allow correlation between multiple event providers.
// We have m_activityTracker field simply because instance field is more efficient than static field fetch.
- ActivityTracker m_activityTracker;
+ ActivityTracker m_activityTracker = null!;
internal const string s_ActivityStartSuffix = "Start";
internal const string s_ActivityStopSuffix = "Stop";
/// </summary>
public class EventListener : IDisposable
{
- private event EventHandler<EventSourceCreatedEventArgs> _EventSourceCreated;
+ private event EventHandler<EventSourceCreatedEventArgs>? _EventSourceCreated;
/// <summary>
/// This event is raised whenever a new eventSource is 'attached' to the dispatcher.
{
CallBackForExistingEventSources(false, value);
- this._EventSourceCreated = (EventHandler<EventSourceCreatedEventArgs>)Delegate.Combine(_EventSourceCreated, value);
+ this._EventSourceCreated = (EventHandler<EventSourceCreatedEventArgs>?)Delegate.Combine(_EventSourceCreated, value);
}
remove
{
- this._EventSourceCreated = (EventHandler<EventSourceCreatedEventArgs>)Delegate.Remove(_EventSourceCreated, value);
+ this._EventSourceCreated = (EventHandler<EventSourceCreatedEventArgs>?)Delegate.Remove(_EventSourceCreated, value);
}
}
public EventListener()
{
// This will cause the OnEventSourceCreated callback to fire.
- CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener((EventListener)obj));
+ CallBackForExistingEventSources(true, (obj, args) =>
+ {
+ args.EventSource!.AddListener((EventListener)obj!);
+ });
}
/// <summary>
EventListener prev = s_Listeners;
for (;;)
{
- EventListener cur = prev.m_Next;
+ EventListener? cur = prev.m_Next;
if (cur == null)
break;
if (cur == this)
///
/// This call never has an effect on other EventListeners.
/// </summary>
- public void EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword, IDictionary<string, string> arguments)
+ public void EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword, IDictionary<string, string>? arguments)
{
if (eventSource == null)
{
/// <param name="eventSource"></param>
internal protected virtual void OnEventSourceCreated(EventSource eventSource)
{
- EventHandler<EventSourceCreatedEventArgs> callBack = this._EventSourceCreated;
+ EventHandler<EventSourceCreatedEventArgs>? callBack = this._EventSourceCreated;
if (callBack != null)
{
EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs();
{
#endif
// Add every existing dispatcher to the new EventSource
- for (EventListener listener = s_Listeners; listener != null; listener = listener.m_Next)
+ for (EventListener? listener = s_Listeners; listener != null; listener = listener.m_Next)
newEventSource.AddListener(listener);
#if DEBUG
}
// such callbacks on process shutdown or appdomain so that unmanaged code will never
// do this. This is what this callback is for.
// See bug 724140 for more
- private static void DisposeOnShutdown(object sender, EventArgs e)
+ private static void DisposeOnShutdown(object? sender, EventArgs e)
{
lock (EventListenersLock)
{
+ Debug.Assert(s_EventSources != null);
foreach (var esRef in s_EventSources)
{
if (esRef.Target is EventSource es)
Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
#endif
// Foreach existing EventSource in the appdomain
+ Debug.Assert(s_EventSources != null);
foreach (WeakReference eventSourceRef in s_EventSources)
{
if (eventSourceRef.Target is EventSource eventSource)
{
+ Debug.Assert(eventSource.m_Dispatchers != null);
// Is the first output dispatcher the dispatcher we are removing?
if (eventSource.m_Dispatchers.m_Listener == listenerToRemove)
eventSource.m_Dispatchers = eventSource.m_Dispatchers.m_Next;
else
{
// Remove 'listenerToRemove' from the eventSource.m_Dispatchers linked list.
- EventDispatcher prev = eventSource.m_Dispatchers;
+ EventDispatcher? prev = eventSource.m_Dispatchers;
for (;;)
{
- EventDispatcher cur = prev.m_Next;
+ EventDispatcher? cur = prev.m_Next;
if (cur == null)
{
Debug.Fail("EventSource did not have a registered EventListener!");
lock (EventListenersLock)
{
+ Debug.Assert(s_EventSources != null);
// Get all listeners
Dictionary<EventListener, bool> allListeners = new Dictionary<EventListener, bool>();
- EventListener cur = s_Listeners;
+ EventListener? cur = s_Listeners;
while (cur != null)
{
allListeners.Add(cur, true);
Debug.Assert(eventSource.m_id == id, "Unexpected event source ID.");
// None listeners on eventSources exist in the dispatcher list.
- EventDispatcher dispatcher = eventSource.m_Dispatchers;
+ EventDispatcher? dispatcher = eventSource.m_Dispatchers;
while (dispatcher != null)
{
Debug.Assert(allListeners.ContainsKey(dispatcher.m_Listener), "EventSource has a listener not on the global list.");
{
if (s_EventSources == null)
Interlocked.CompareExchange(ref s_EventSources, new List<WeakReference>(2), null);
- return s_EventSources;
+ return s_EventSources!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34901
}
}
{
lock (EventListenersLock)
{
+ Debug.Assert(s_EventSources != null);
+
// Disallow creating EventListener reentrancy.
if (s_CreatingListener)
{
}
// Instance fields
- internal volatile EventListener m_Next; // These form a linked list in s_Listeners
+ internal volatile EventListener? m_Next; // These form a linked list in s_Listeners
// static fields
/// The list of all listeners in the appdomain. Listeners must be explicitly disposed to remove themselves
/// from this list. Note that EventSources point to their listener but NOT the reverse.
/// </summary>
- internal static EventListener s_Listeners;
+ internal static EventListener? s_Listeners;
/// <summary>
/// The list of all active eventSources in the appdomain. Note that eventSources do NOT
/// remove themselves from this list this is a weak list and the GC that removes them may
/// not have happened yet. Thus it can contain event sources that are dead (thus you have
/// to filter those out.
/// </summary>
- internal static List<WeakReference> s_EventSources;
+ internal static List<WeakReference>? s_EventSources;
/// <summary>
/// Used to disallow reentrancy.
/// <summary>
/// Gets the arguments for the callback.
/// </summary>
- public IDictionary<string, string> Arguments { get; internal set; }
+ public IDictionary<string, string>? Arguments { get; internal set; }
/// <summary>
/// Enables the event that has the specified identifier.
#region private
- internal EventCommandEventArgs(EventCommand command, IDictionary<string, string> arguments, EventSource eventSource,
- EventListener listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword)
+ internal EventCommandEventArgs(EventCommand command, IDictionary<string, string>? arguments, EventSource eventSource,
+ EventListener? listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword)
{
this.Command = command;
this.Arguments = arguments;
}
internal EventSource eventSource;
- internal EventDispatcher dispatcher;
+ internal EventDispatcher? dispatcher;
internal EventProviderType eventProviderType;
// These are the arguments of sendCommand and are only used for deferring commands until after we are fully initialized.
- internal EventListener listener;
+ internal EventListener? listener;
internal int perEventSourceSessionId;
internal int etwSessionId;
internal bool enable;
internal EventLevel level;
internal EventKeywords matchAnyKeyword;
- internal EventCommandEventArgs nextCommand; // We form a linked list of these deferred commands.
+ internal EventCommandEventArgs? nextCommand; // We form a linked list of these deferred commands.
#endregion
}
/// <summary>
/// The EventSource that is attaching to the listener.
/// </summary>
- public EventSource EventSource
+ public EventSource? EventSource
{
get;
internal set;
/// <summary>
/// The name of the event.
/// </summary>
- public string EventName
+ public string? EventName
{
get
{
return m_eventName;
}
else
+ {
+ Debug.Assert(m_eventSource.m_eventData != null);
return m_eventSource.m_eventData[EventId].Name;
+ }
}
internal set
{
/// <summary>
/// Gets the payload for the event.
/// </summary>
- public ReadOnlyCollection<object> Payload { get; internal set; }
+ public ReadOnlyCollection<object?>? Payload { get; internal set; }
/// <summary>
/// Gets the payload argument names.
/// </summary>
- public ReadOnlyCollection<string> PayloadNames
+ public ReadOnlyCollection<string>? PayloadNames
{
get
{
{
var names = new List<string>();
+ Debug.Assert(m_eventSource.m_eventData != null);
foreach (var parameter in m_eventSource.m_eventData[EventId].Parameters)
{
names.Add(parameter.Name);
}
+
m_payloadNames = new ReadOnlyCollection<string>(names);
}
if (EventId < 0) // TraceLogging convention EventID == -1
return m_keywords;
+ Debug.Assert(m_eventSource.m_eventData != null);
return (EventKeywords)m_eventSource.m_eventData[EventId].Descriptor.Keywords;
}
}
{
if (EventId <= 0) // TraceLogging convention EventID == -1
return m_opcode;
+
+ Debug.Assert(m_eventSource.m_eventData != null);
return (EventOpcode)m_eventSource.m_eventData[EventId].Descriptor.Opcode;
}
}
if (EventId <= 0) // TraceLogging convention EventID == -1
return EventTask.None;
+ Debug.Assert(m_eventSource.m_eventData != null);
return (EventTask)m_eventSource.m_eventData[EventId].Descriptor.Task;
}
}
{
if (EventId <= 0) // TraceLogging convention EventID == -1
return m_tags;
+
+ Debug.Assert(m_eventSource.m_eventData != null);
return m_eventSource.m_eventData[EventId].Tags;
}
}
/// <summary>
/// Gets the message for the event. If the message has {N} parameters they are NOT substituted.
/// </summary>
- public string Message
+ public string? Message
{
get
{
if (EventId <= 0) // TraceLogging convention EventID == -1
+ {
return m_message;
+ }
else
+ {
+ Debug.Assert(m_eventSource.m_eventData != null);
return m_eventSource.m_eventData[EventId].Message;
+ }
}
internal set
{
{
if (EventId <= 0) // TraceLogging convention EventID == -1
return EventChannel.None;
+
+ Debug.Assert(m_eventSource.m_eventData != null);
return (EventChannel)m_eventSource.m_eventData[EventId].Descriptor.Channel;
}
}
{
if (EventId <= 0) // TraceLogging convention EventID == -1
return 0;
+
+ Debug.Assert(m_eventSource.m_eventData != null);
return m_eventSource.m_eventData[EventId].Descriptor.Version;
}
}
{
if (EventId <= 0) // TraceLogging convention EventID == -1
return m_level;
+
+ Debug.Assert(m_eventSource.m_eventData != null);
return (EventLevel)m_eventSource.m_eventData[EventId].Descriptor.Level;
}
}
m_eventSource = eventSource;
TimeStamp = DateTime.UtcNow;
}
- private string m_message;
- private string m_eventName;
+ private string? m_message;
+ private string? m_eventName;
private EventSource m_eventSource;
- private ReadOnlyCollection<string> m_payloadNames;
+ private ReadOnlyCollection<string>? m_payloadNames;
private Guid m_activityId;
private long? m_osThreadId;
internal EventTags m_tags;
/// <summary>
/// Overrides the ETW name of the event source (which defaults to the class name)
/// </summary>
- public string Name { get; set; }
+ public string? Name { get; set; }
/// <summary>
/// Overrides the default (calculated) Guid of an EventSource type. Explicitly defining a GUID is discouraged,
/// except when upgrading existing ETW providers to using event sources.
/// </summary>
- public string Guid { get; set; }
+ public string? Guid { get; set; }
/// <summary>
/// <para>
/// which represent the payload values.
/// </para>
/// </summary>
- public string LocalizationResources { get; set; }
+ public string? LocalizationResources { get; set; }
}
/// <summary>
/// use standard .NET substitution operators (eg {1}) in the string and they will be replaced
/// with the 'ToString()' of the corresponding part of the event payload.
/// </summary>
- public string Message { get; set; }
+ public string? Message { get; set; }
/// <summary>
/// User defined options associated with the event. These do not have meaning to the EventSource but
/// Specifies an SDDL access descriptor that controls access to the log file that backs the channel.
/// See MSDN (https://docs.microsoft.com/en-us/windows/desktop/WES/eventmanifestschema-channeltype-complextype) for details.
/// </summary>
- public string Access { get; set; }
+ public string? Access { get; set; }
/// <summary>
/// Allows importing channels defined in external manifests
/// </summary>
- public string ImportChannel { get; set; }
+ public string? ImportChannel { get; set; }
#endif
// TODO: there is a convention that the name is the Provider/Type Should we provide an override?
/// </summary>
internal class EventDispatcher
{
- internal EventDispatcher(EventDispatcher next, bool[] eventEnabled, EventListener listener)
+ internal EventDispatcher(EventDispatcher? next, bool[]? eventEnabled, EventListener listener)
{
m_Next = next;
m_EventEnabled = eventEnabled;
// Instance fields
readonly internal EventListener m_Listener; // The dispatcher this entry is for
- internal bool[] m_EventEnabled; // For every event in a the eventSource, is it enabled?
+ internal bool[]? m_EventEnabled; // For every event in a the eventSource, is it enabled?
// Only guaranteed to exist after a InsureInit()
- internal EventDispatcher m_Next; // These form a linked list in code:EventSource.m_Dispatchers
+ internal EventDispatcher? m_Next; // These form a linked list in code:EventSource.m_Dispatchers
// Of all listeners for that eventSource.
}
/// Build a manifest for 'providerName' with the given GUID, which will be packaged into 'dllName'.
/// 'resources, is a resource manager. If specified all messages are localized using that manager.
/// </summary>
- public ManifestBuilder(string providerName, Guid providerGuid, string dllName, ResourceManager resources,
+ public ManifestBuilder(string providerName, Guid providerGuid, string? dllName, ResourceManager? resources,
EventManifestOptions flags)
{
#if FEATURE_MANAGED_ETW_CHANNELS
/// <summary>
/// Add a channel. channelAttribute can be null
/// </summary>
- public void AddChannel(string name, int value, EventChannelAttribute channelAttribute)
+ public void AddChannel(string? name, int value, EventChannelAttribute? channelAttribute)
{
EventChannel chValue = (EventChannel)value;
if (value < (int)EventChannel.Admin || value > 255)
}
public void EndEvent()
{
+ Debug.Assert(eventName != null);
+
if (numParams > 0)
{
templates.Append(" </template>").AppendLine();
string msg;
if (stringTab.TryGetValue("event_" + eventName, out msg))
{
- msg = TranslateToManifestConvention(msg, eventName);
+ msg = TranslateToManifestConvention(msg!, eventName); // https://github.com/dotnet/roslyn/issues/26761
stringTab["event_" + eventName] = msg;
}
int channel = kvpair.Key;
ChannelInfo channelInfo = kvpair.Value;
- string channelType = null;
+ string? channelType = null;
string elementName = "channel";
bool enabled = false;
- string fullName = null;
+ string? fullName = null;
#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- string isolation = null;
- string access = null;
+ string? isolation = null;
+ string? access = null;
#endif
if (channelInfo.Attribs != null)
{
sb.Append(" name=\"").Append(fullName).Append("\"");
if (elementName == "channel") // not applicable to importChannels.
{
+ Debug.Assert(channelInfo.Name != null);
WriteMessageAttrib(sb, "channel", channelInfo.Name, null);
sb.Append(" value=\"").Append(channel).Append("\"");
if (channelType != null)
// Output the localization information.
sb.Append("<localization>").AppendLine();
- List<CultureInfo> cultures = null;
+ List<CultureInfo>? cultures = null;
if (resources != null && (flags & EventManifestOptions.AllCultures) != 0)
{
cultures = GetSupportedCultures(resources);
foreach (var stringKey in sortedStrings)
{
- string val = GetLocalizedMessage(stringKey, ci, etwFormat: true);
+ string? val = GetLocalizedMessage(stringKey, ci, etwFormat: true);
sb.Append(" <string id=\"").Append(stringKey).Append("\" value=\"").Append(val).Append("\"/>").AppendLine();
}
sb.Append(" </stringTable>").AppendLine();
stringBuilder.Append(" name=\"").Append(name).Append("\"");
WriteMessageAttrib(sb, elementName, name, name);
}
- private void WriteMessageAttrib(StringBuilder stringBuilder, string elementName, string name, string value)
+ private void WriteMessageAttrib(StringBuilder stringBuilder, string elementName, string name, string? value)
{
string key = elementName + "_" + name;
// See if the user wants things localized.
if (resources != null)
{
// resource fallback: strings in the neutral culture will take precedence over inline strings
- string localizedString = resources.GetString(key, CultureInfo.InvariantCulture);
+ string? localizedString = resources.GetString(key, CultureInfo.InvariantCulture);
if (localizedString != null)
value = localizedString;
}
stringTab[key] = value;
}
- internal string GetLocalizedMessage(string key, CultureInfo ci, bool etwFormat)
+ internal string? GetLocalizedMessage(string key, CultureInfo ci, bool etwFormat)
{
- string value = null;
+ string? value = null;
if (resources != null)
{
- string localizedString = resources.GetString(key, ci);
+ string? localizedString = resources.GetString(key, ci);
if (localizedString != null)
{
value = localizedString;
}
#if FEATURE_MANAGED_ETW_CHANNELS
- private string GetChannelName(EventChannel channel, string eventName, string eventMessage)
+ private string? GetChannelName(EventChannel channel, string eventName, string? eventMessage)
{
- ChannelInfo info = null;
+ ChannelInfo? info = null;
if (channelTab == null || !channelTab.TryGetValue((int)channel, out info))
{
if (channel < EventChannel.Admin) // || channel > EventChannel.Debug)
// events that specify admin channels *must* have non-null "Message" attributes
if (resources != null && eventMessage == null)
eventMessage = resources.GetString("event_" + eventName, CultureInfo.InvariantCulture);
+
+ Debug.Assert(info.Attribs != null); // TODO-NULLABLE: Bug - Attribs is documented that it can be null in which case this code will NRE
if (info.Attribs.EventChannelType == EventChannelType.Admin && eventMessage == null)
ManifestError(SR.Format(SR.EventSource_EventWithAdminChannelMustHaveMessage, eventName, info.Name));
return info.Name;
return ret;
}
- private string GetOpcodeName(EventOpcode opcode, string eventName)
+ private string? GetOpcodeName(EventOpcode opcode, string eventName)
{
switch (opcode)
{
return "win:Receive";
}
- string ret;
+ string? ret;
if (opcodeTab == null || !opcodeTab.TryGetValue((int)opcode, out ret))
{
ManifestError(SR.Format(SR.EventSource_UndefinedOpcode, opcode, eventName), true);
ret = null;
}
+
return ret;
}
{
if ((keywords & bit) != 0)
{
- string keyword = null;
+ string? keyword = null;
if ((keywordTab == null || !keywordTab.TryGetValue(bit, out keyword)) &&
(bit >= (ulong)0x1000000000000))
{
}
}
- private static void UpdateStringBuilder(ref StringBuilder stringBuilder, string eventMessage, int startIndex, int count)
+ private static void UpdateStringBuilder(ref StringBuilder? stringBuilder, string eventMessage, int startIndex, int count) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 nullable in, non-nullable out
{
if (stringBuilder == null)
stringBuilder = new StringBuilder();
// .NET conventions. We can't use RegEx for this (we are in mscorlib), so we do it 'by hand'
private string TranslateToManifestConvention(string eventMessage, string evtName)
{
- StringBuilder stringBuilder = null; // We lazily create this
+ StringBuilder? stringBuilder = null; // We lazily create this
int writtenSoFar = 0;
int chIdx = -1;
for (int i = 0; ;)
if (stringBuilder == null)
return eventMessage;
UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
- return stringBuilder.ToString();
+ return stringBuilder!.ToString(); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
}
if (eventMessage[i] == '%')
{
// handle format message escaping character '%' by escaping it
UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
- stringBuilder.Append("%%");
+ stringBuilder!.Append("%%"); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
i++;
writtenSoFar = i;
}
{
// handle C# escaped '{" and '}'
UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
- stringBuilder.Append(eventMessage[i]);
+ stringBuilder!.Append(eventMessage[i]); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
i++; i++;
writtenSoFar = i;
}
i++;
UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, leftBracket - writtenSoFar);
int manIndex = TranslateIndexToManifestConvention(argNum, evtName);
- stringBuilder.Append('%').Append(manIndex);
+ stringBuilder!.Append('%').Append(manIndex); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
// An '!' after the insert specifier {n} will be interpreted as a literal.
// We'll escape it so that mc.exe does not attempt to consider it the
// beginning of a format string.
{
UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
i++;
- stringBuilder.Append(s_escapes[chIdx]);
+ stringBuilder!.Append(s_escapes[chIdx]); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
writtenSoFar = i;
}
else
#if FEATURE_MANAGED_ETW_CHANNELS
class ChannelInfo
{
- public string Name;
+ public string? Name;
public ulong Keywords;
- public EventChannelAttribute Attribs;
+ public EventChannelAttribute? Attribs;
}
#endif
Dictionary<int, string> opcodeTab;
- Dictionary<int, string> taskTab;
+ Dictionary<int, string>? taskTab;
#if FEATURE_MANAGED_ETW_CHANNELS
- Dictionary<int, ChannelInfo> channelTab;
+ Dictionary<int, ChannelInfo>? channelTab;
#endif
- Dictionary<ulong, string> keywordTab;
- Dictionary<string, Type> mapsTab;
+ Dictionary<ulong, string>? keywordTab;
+ Dictionary<string, Type>? mapsTab;
Dictionary<string, string> stringTab; // Maps unlocalized strings to localized ones
#if FEATURE_MANAGED_ETW_CHANNELS
string providerName;
#endif
- ResourceManager resources; // Look up localized strings here.
+ ResourceManager? resources; // Look up localized strings here.
EventManifestOptions flags;
IList<string> errors; // list of currently encountered errors
Dictionary<string, List<int>> perEventByteArrayArgIndices; // "event_name" -> List_of_Indices_of_Byte[]_Arg
// State we track between StartEvent and EndEvent.
- string eventName; // Name of the event currently being processed.
+ string? eventName; // Name of the event currently being processed.
int numParams; // keeps track of the number of args the event has.
- List<int> byteArrArgIndices; // keeps track of the index of each byte[] argument
+ List<int>? byteArrArgIndices; // keeps track of the index of each byte[] argument
#endregion
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using Internal.Runtime.CompilerServices;
namespace System.Diagnostics.Tracing
// optimized for common signatures (used by the ThreadTransferSend/Receive events)
[NonEvent]
- private unsafe void WriteEvent(int eventId, long arg1, int arg2, string arg3, bool arg4, int arg5, int arg6)
+ private unsafe void WriteEvent(int eventId, long arg1, int arg2, string? arg3, bool arg4, int arg5, int arg6)
{
if (IsEnabled())
{
// optimized for common signatures (used by the ThreadTransferSend/Receive events)
[NonEvent]
- private unsafe void WriteEvent(int eventId, long arg1, int arg2, string arg3)
+ private unsafe void WriteEvent(int eventId, long arg1, int arg2, string? arg3)
{
if (IsEnabled())
{
// 3 - WinRT dispatch operations
// info - any additional information user code might consider interesting
[Event(151, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = EventOpcode.Receive)]
- public void ThreadTransferReceive(long id, int kind, string info)
+ public void ThreadTransferReceive(long id, int kind, string? info)
{
WriteEvent(151, id, kind, info);
}
// keep track of GC movements in order to correlate the value passed to XyzSend with the
// (possibly changed) value passed to XyzReceive
[NonEvent]
- public unsafe void ThreadTransferReceiveObj(object id, int kind, string info)
+ public unsafe void ThreadTransferReceiveObj(object id, int kind, string? info)
{
ThreadTransferReceive((long)*((void**)Unsafe.AsPointer(ref id)), kind, info);
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using Microsoft.Win32;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Diagnostics;
using System.Collections;
/// <param name="increment">The value to increment by.</param>
public void Increment(double increment = 1)
{
- lock(MyLock)
+ lock (MyLock)
{
_increment += increment;
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Diagnostics;
using System.Collections;
/// <param name="eventSource">The event source.</param>
public IncrementingPollingCounter(string name, EventSource eventSource, Func<double> totalValueProvider) : base(name, eventSource)
{
+ if (totalValueProvider == null)
+ throw new ArgumentNullException(nameof(totalValueProvider));
+
_totalValueProvider = totalValueProvider;
}
{
try
{
- lock(MyLock)
+ lock (MyLock)
{
_increment = _totalValueProvider();
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Diagnostics;
using System.Collections;
/// <param name="eventSource">The event source.</param>
public PollingCounter(string name, EventSource eventSource, Func<double> metricProvider) : base(name, eventSource)
{
+ if (metricProvider == null)
+ throw new ArgumentNullException(nameof(metricProvider));
+
_metricProvider = metricProvider;
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
public static int TickCount
{ get { return System.Environment.TickCount; } }
- public static string GetResourceString(string key, params object[] args)
+ public static string GetResourceString(string key, params object?[] args)
{
- string fmt = rm.GetString(key);
+ string? fmt = rm.GetString(key);
if (fmt != null)
return string.Format(fmt, args);
- string sargs = string.Empty;
- foreach(var arg in args)
- {
- if (sargs != string.Empty)
- sargs += ", ";
- sargs += arg.ToString();
- }
+ string sargs = string.Join(", ", args);
return key + " (" + sargs + ")";
}
- public static string GetRuntimeResourceString(string key, params object[] args)
+ public static string GetRuntimeResourceString(string key, params object?[] args)
{
return GetResourceString(key, args);
}
}
return fieldInfos.ToArray();
}
- public static Type GetNestedType(this Type type, string nestedTypeName)
+ public static Type? GetNestedType(this Type type, string nestedTypeName)
{
- TypeInfo ti = null;
+ TypeInfo? ti = null;
foreach(var nt in type.GetTypeInfo().DeclaredNestedTypes)
{
if (nt.Name == nestedTypeName)
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format)
{
collector.BeginBufferedArray();
var bookmark = collector.BeginBufferedArray();
var count = 0;
- Array array = (Array)value.ReferenceValue;
+ Array? array = (Array?)value.ReferenceValue;
if (array != null)
{
count = array.Length;
collector.EndBufferedArray(bookmark, count);
}
- public override object GetData(object value)
+ public override object? GetData(object? value)
{
+ Debug.Assert(value != null, "null accepted only for some overrides");
var array = (Array)value;
- var serializedArray = new object[array.Length];
+ var serializedArray = new object?[array.Length];
for (int i = 0; i < array.Length; i++)
{
serializedArray[i] = this.elementInfo.GetData(array.GetValue(i));
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using Interlocked = System.Threading.Interlocked;
internal struct ConcurrentSet<KeyType, ItemType>
where ItemType : ConcurrentSetItem<KeyType, ItemType>
{
- private ItemType[] items;
+ private ItemType[]? items;
- public ItemType TryGet(KeyType key)
+ public ItemType? TryGet(KeyType key)
{
- ItemType item;
+ ItemType? item;
var oldItems = this.items;
if (oldItems != null)
Array.Copy(oldItems, lo, newItems, lo + 1, oldLength - lo);
}
- newItems = Interlocked.CompareExchange(ref this.items, newItems, oldItems);
+ newItems = Interlocked.CompareExchange(ref this.items, newItems, oldItems)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34901
if (oldItems != newItems)
{
oldItems = newItems;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
#if ES_BUILD_STANDALONE
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Resources;
using System.Runtime.InteropServices;
private byte* scratch;
private EventSource.EventData* datas;
private GCHandle* pins;
- private byte[] buffer;
+ private byte[]? buffer;
private int bufferPos;
private int bufferNesting; // We may merge many fields int a single blob. If we are doing this we increment this.
private bool writingScalars;
var oldPos = this.bufferPos;
this.bufferPos = checked(this.bufferPos + size);
this.EnsureBuffer();
+ Debug.Assert(buffer != null);
+
for (int i = 0; i != size; i++, oldPos++)
{
this.buffer[oldPos] = pb[i];
}
}
- internal void AddBinary(string value, int size)
+ internal void AddBinary(string? value, int size)
{
if (size > ushort.MaxValue)
{
var oldPos = this.bufferPos;
this.bufferPos = checked(this.bufferPos + size);
this.EnsureBuffer();
+ Debug.Assert(buffer != null);
+
fixed (void* p = value)
{
Marshal.Copy((IntPtr)p, buffer, oldPos, size);
}
}
- internal unsafe void AddNullTerminatedString(string value)
+ internal unsafe void AddNullTerminatedString(string? value)
{
// Treat null strings as empty strings.
if (value == null)
var oldPos = this.bufferPos;
this.bufferPos = checked(this.bufferPos + size);
this.EnsureBuffer();
+ Debug.Assert(buffer != null);
+
fixed (void* p = value)
{
Marshal.Copy((IntPtr)p, buffer, oldPos, size);
this.AddArray(value, size, 1);
}
- internal void AddArray(Array value, int length, int itemSize)
+ internal void AddArray(Array? value, int length, int itemSize)
{
if (length > ushort.MaxValue)
{
var oldPos = this.bufferPos;
this.bufferPos = checked(this.bufferPos + size);
this.EnsureBuffer();
+ Debug.Assert(value != null && buffer != null);
Buffer.BlockCopy(value, 0, this.buffer, oldPos, size);
}
}
internal void EndBufferedArray(int bookmark, int count)
{
this.EnsureBuffer();
+ Debug.Assert(buffer != null);
this.buffer[bookmark - 2] = unchecked((byte)count);
this.buffer[bookmark - 1] = unchecked((byte)(count >> 8));
this.EndBuffered();
*/
this.EnsureBuffer();
+ Debug.Assert(buffer != null);
this.PinArray(this.buffer, this.bufferPos);
this.buffer = null;
this.bufferPos = 0;
Array.Resize(ref this.buffer, newSize);
}
- private void PinArray(object value, int size)
+ private void PinArray(object? value, int size)
{
var pinsTemp = this.pins;
if (this.pinsEnd <= pinsTemp)
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
#if ES_BUILD_STANDALONE
namespace Microsoft.Diagnostics.Tracing
#else
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+
+#nullable enable
#if EVENTSOURCE_GENERICS
?using System;
using System.Reflection;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections;
using System.Collections.Generic;
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format)
{
collector.BeginBufferedArray();
var bookmark = collector.BeginBufferedArray();
var count = 0;
- IEnumerable enumerable = (IEnumerable)value.ReferenceValue;
+ IEnumerable? enumerable = (IEnumerable?)value.ReferenceValue;
if (enumerable != null)
{
foreach (var element in enumerable)
collector.EndBufferedArray(bookmark, count);
}
- public override object GetData(object value)
+ public override object? GetData(object? value)
{
+ Debug.Assert(value != null, "null accepted only for some overrides");
var iterType = (IEnumerable)value;
- List<object> serializedEnumerable = new List<object>();
+ List<object?> serializedEnumerable = new List<object?>();
foreach (var element in iterType)
{
serializedEnumerable.Add(elementInfo.GetData(element));
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
#if ES_BUILD_STANDALONE
/// else
/// fieldName = typeof(T).Name;
/// </summary>
- public string Name
+ public string? Name
{
get;
set;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
#if ES_BUILD_STANDALONE
/// as the event field's name.
/// TODO REMOVE
/// </summary>
- internal string Name
+ internal string? Name
{
get;
set;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
#if ES_BUILD_STANDALONE
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
using System.Collections;
/// EventSource APIs.
/// Preserving the order of the elements as they were found inside user defined types is the most important characteristic of this class.
/// </summary>
- internal class EventPayload : IDictionary<string, object>
+ internal class EventPayload : IDictionary<string, object?>
{
- internal EventPayload(List<string> payloadNames, List<object> payloadValues)
+ internal EventPayload(List<string> payloadNames, List<object?> payloadValues)
{
Debug.Assert(payloadNames.Count == payloadValues.Count);
}
public ICollection<string> Keys { get { return m_names; } }
- public ICollection<object> Values { get { return m_values; } }
+ public ICollection<object?> Values { get { return m_values; } }
- public object this[string key]
+ public object? this[string key]
{
get
{
}
}
- public void Add(string key, object value)
+ public void Add(string key, object? value)
{
throw new System.NotSupportedException();
}
- public void Add(KeyValuePair<string, object> payloadEntry)
+ public void Add(KeyValuePair<string, object?> payloadEntry)
{
throw new System.NotSupportedException();
}
throw new System.NotSupportedException();
}
- public bool Contains(KeyValuePair<string, object> entry)
+ public bool Contains(KeyValuePair<string, object?> entry)
{
return ContainsKey(entry.Key);
}
public bool IsReadOnly { get { return true; } }
- public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
+ public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
{
for (int i = 0; i < Keys.Count; i++)
{
- yield return new KeyValuePair<string, object>(this.m_names[i], this.m_values[i]);
+ yield return new KeyValuePair<string, object?>(this.m_names[i], this.m_values[i]);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
- var instance = this as IEnumerable<KeyValuePair<string, object>>;
+ var instance = this as IEnumerable<KeyValuePair<string, object?>>;
return instance.GetEnumerator();
}
- public void CopyTo(KeyValuePair<string, object>[] payloadEntries, int count)
+ public void CopyTo(KeyValuePair<string, object?>[] payloadEntries, int count)
{
throw new System.NotSupportedException();
}
throw new System.NotSupportedException();
}
- public bool Remove(KeyValuePair<string, object> entry)
+ public bool Remove(KeyValuePair<string, object?> entry)
{
throw new System.NotSupportedException();
}
- public bool TryGetValue(string key, out object value)
+ public bool TryGetValue(string key, out object? value)
{
if (key == null)
throw new System.ArgumentNullException(nameof(key));
#region private
private List<string> m_names;
- private List<object> m_values;
+ private List<object?> m_values;
#endregion
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
#if !ES_BUILD_AGAINST_DOTNET_V35
/// <param name="options">Allow options (keywords, level) to be set for the write associated with this start
/// These will also be used for the stop event.</param>
/// <param name="data">The data to include in the event.</param>
- public EventSourceActivity Start<T>(string eventName, EventSourceOptions options, T data)
+ public EventSourceActivity Start<T>(string? eventName, EventSourceOptions options, T data)
{
return this.Start(eventName, ref options, ref data);
}
/// Shortcut version see Start(string eventName, EventSourceOptions options, T data) Options is empty (no keywords
/// and level==Info) Data payload is empty.
/// </summary>
- public EventSourceActivity Start(string eventName)
+ public EventSourceActivity Start(string? eventName)
{
var options = new EventSourceOptions();
var data = new EmptyStruct();
/// <summary>
/// Shortcut version see Start(string eventName, EventSourceOptions options, T data). Data payload is empty.
/// </summary>
- public EventSourceActivity Start(string eventName, EventSourceOptions options)
+ public EventSourceActivity Start(string? eventName, EventSourceOptions options)
{
var data = new EmptyStruct();
return this.Start(eventName, ref options, ref data);
/// Shortcut version see Start(string eventName, EventSourceOptions options, T data) Options is empty (no keywords
/// and level==Info)
/// </summary>
- public EventSourceActivity Start<T>(string eventName, T data)
+ public EventSourceActivity Start<T>(string? eventName, T data)
{
var options = new EventSourceOptions();
return this.Start(eventName, ref options, ref data);
/// This can be useful to indicate unusual ways of stopping (but it is still STRONGLY recommended that
/// you start with the same prefix used for the start event and you end with the 'Stop' suffix.
/// </summary>
- public void Stop<T>(string eventName)
+ public void Stop<T>(string? eventName)
{
var data = new EmptyStruct();
this.Stop(eventName, ref data);
/// This can be useful to indicate unusual ways of stopping (but it is still STRONGLY recommended that
/// you start with the same prefix used for the start event and you end with the 'Stop' suffix.
/// </summary>
- public void Stop<T>(string eventName, T data)
+ public void Stop<T>(string? eventName, T data)
{
this.Stop(eventName, ref data);
}
/// The options to use for the event.
/// </param>
/// <param name="data">The data to include in the event.</param>
- public void Write<T>(string eventName, EventSourceOptions options, T data)
+ public void Write<T>(string? eventName, EventSourceOptions options, T data)
{
this.Write(this.eventSource, eventName, ref options, ref data);
}
/// data's type.
/// </param>
/// <param name="data">The data to include in the event.</param>
- public void Write<T>(string eventName, T data)
+ public void Write<T>(string? eventName, T data)
{
var options = new EventSourceOptions();
this.Write(this.eventSource, eventName, ref options, ref data);
/// <param name="options">
/// The options to use for the event.
/// </param>
- public void Write(string eventName, EventSourceOptions options)
+ public void Write(string? eventName, EventSourceOptions options)
{
var data = new EmptyStruct();
this.Write(this.eventSource, eventName, ref options, ref data);
/// <param name="eventName">
/// The name to use for the event. Must not be null.
/// </param>
- public void Write(string eventName)
+ public void Write(string? eventName)
{
var options = new EventSourceOptions();
var data = new EmptyStruct();
/// <summary>
/// Writes an event to a arbitrary eventSource stamped with the activity ID of this activity.
/// </summary>
- public void Write<T>(EventSource source, string eventName, EventSourceOptions options, T data)
+ public void Write<T>(EventSource source, string? eventName, EventSourceOptions options, T data)
{
this.Write(source, eventName, ref options, ref data);
}
}
#region private
- private EventSourceActivity Start<T>(string eventName, ref EventSourceOptions options, ref T data)
+ private EventSourceActivity Start<T>(string? eventName, ref EventSourceOptions options, ref T data)
{
if (this.state != State.Started)
throw new InvalidOperationException();
return newActivity;
}
- private void Write<T>(EventSource eventSource, string eventName, ref EventSourceOptions options, ref T data)
+ private void Write<T>(EventSource eventSource, string? eventName, ref EventSourceOptions options, ref T data)
{
if (this.state != State.Started)
throw new InvalidOperationException(); // Write after stop.
eventSource.Write(eventName, ref options, ref this.activityId, ref s_empty, ref data);
}
- private void Stop<T>(string eventName, ref T data)
+ private void Stop<T>(string? eventName, ref T data)
{
if (this.state != State.Started)
throw new InvalidOperationException();
if (!StartEventWasFired)
return;
+ Debug.Assert(this.eventName != null);
+
this.state = State.Stopped;
if (eventName == null)
{
internal Guid activityId;
// internal Guid relatedActivityId;
private State state;
- private string eventName;
+ private string? eventName;
internal static Guid s_empty;
#endregion
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
#if ES_BUILD_STANDALONE
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Resources;
using Encoding = System.Text.Encoding;
/// </summary>
private readonly int nameSize;
private readonly EventFieldTags tags;
- private readonly byte[] custom;
+ private readonly byte[]? custom;
/// <summary>
/// ETW supports fixed sized arrays. If inType has the InTypeFixedCountFlag then this is the
0,
null)
{
- return;
}
/// <summary>
string name,
TraceLoggingDataType type,
EventFieldTags tags,
- byte[] custom)
+ byte[]? custom)
: this(
name,
type,
EventFieldTags tags,
byte countFlags,
ushort fixedCount = 0,
- byte[] custom = null)
+ byte[]? custom = null)
{
if (name == null)
{
/// for a 'two pass' approach where you figure out how big to make the array, and then you
/// fill it in.
/// </summary>
- public void Encode(ref int pos, byte[] metadata)
+ public void Encode(ref int pos, byte[]? metadata)
{
// Write out the null terminated UTF8 encoded name
if (metadata != null)
{
if (metadata != null)
{
- Buffer.BlockCopy(this.custom, 0, metadata, pos, this.fixedCount);
+ Debug.Assert(custom != null);
+ Buffer.BlockCopy(custom, 0, metadata, pos, this.fixedCount);
}
pos += this.fixedCount;
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
/// </summary>
internal sealed class InvokeTypeInfo : TraceLoggingTypeInfo
{
- internal readonly PropertyAnalysis[] properties;
+ internal readonly PropertyAnalysis[]? properties;
public InvokeTypeInfo(
Type type,
TypeAnalysis typeAnalysis)
: base(
type,
- typeAnalysis.name,
+ typeAnalysis.name!,
typeAnalysis.level,
typeAnalysis.opcode,
typeAnalysis.keywords,
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format)
{
var groupCollector = collector.AddGroup(name);
}
}
- public override object GetData(object value)
+ public override object? GetData(object? value)
{
if (this.properties != null)
{
var membersNames = new List<string>();
- var memebersValues = new List<object>();
+ var memebersValues = new List<object?>();
for (int i = 0; i < this.properties.Length; i++)
{
var propertyValue = properties[i].propertyInfo.GetValue(value);
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Reflection;
internal readonly PropertyInfo propertyInfo;
internal readonly Func<PropertyValue, PropertyValue> getter;
internal readonly TraceLoggingTypeInfo typeInfo;
- internal readonly EventFieldAttribute fieldAttribute;
+ internal readonly EventFieldAttribute? fieldAttribute;
public PropertyAnalysis(
string name,
PropertyInfo propertyInfo,
TraceLoggingTypeInfo typeInfo,
- EventFieldAttribute fieldAttribute)
+ EventFieldAttribute? fieldAttribute)
{
this.name = name;
this.propertyInfo = propertyInfo;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Reflection;
using System.Runtime.InteropServices;
}
// Anything not covered by the Scalar union gets stored in this reference.
- readonly object _reference;
+ readonly object? _reference;
readonly Scalar _scalar;
readonly int _scalarLength;
- private PropertyValue(object value)
+ private PropertyValue(object? value)
{
_reference = value;
_scalar = default;
private PropertyValue(TimeSpan value) : this(new Scalar() { AsTimeSpan = value }, sizeof(TimeSpan)) { }
private PropertyValue(decimal value) : this(new Scalar() { AsDecimal = value }, sizeof(decimal)) { }
- public static Func<object, PropertyValue> GetFactory(Type type)
+ public static Func<object?, PropertyValue> GetFactory(Type type)
{
- if (type == typeof(bool)) return value => new PropertyValue((bool)value);
- if (type == typeof(byte)) return value => new PropertyValue((byte)value);
- if (type == typeof(sbyte)) return value => new PropertyValue((sbyte)value);
- if (type == typeof(char)) return value => new PropertyValue((char)value);
- if (type == typeof(short)) return value => new PropertyValue((short)value);
- if (type == typeof(ushort)) return value => new PropertyValue((ushort)value);
- if (type == typeof(int)) return value => new PropertyValue((int)value);
- if (type == typeof(uint)) return value => new PropertyValue((uint)value);
- if (type == typeof(long)) return value => new PropertyValue((long)value);
- if (type == typeof(ulong)) return value => new PropertyValue((ulong)value);
- if (type == typeof(IntPtr)) return value => new PropertyValue((IntPtr)value);
- if (type == typeof(UIntPtr)) return value => new PropertyValue((UIntPtr)value);
- if (type == typeof(float)) return value => new PropertyValue((float)value);
- if (type == typeof(double)) return value => new PropertyValue((double)value);
- if (type == typeof(Guid)) return value => new PropertyValue((Guid)value);
- if (type == typeof(DateTime)) return value => new PropertyValue((DateTime)value);
- if (type == typeof(DateTimeOffset)) return value => new PropertyValue((DateTimeOffset)value);
- if (type == typeof(TimeSpan)) return value => new PropertyValue((TimeSpan)value);
- if (type == typeof(decimal)) return value => new PropertyValue((decimal)value);
+ if (type == typeof(bool)) return value => new PropertyValue((bool)value!);
+ if (type == typeof(byte)) return value => new PropertyValue((byte)value!);
+ if (type == typeof(sbyte)) return value => new PropertyValue((sbyte)value!);
+ if (type == typeof(char)) return value => new PropertyValue((char)value!);
+ if (type == typeof(short)) return value => new PropertyValue((short)value!);
+ if (type == typeof(ushort)) return value => new PropertyValue((ushort)value!);
+ if (type == typeof(int)) return value => new PropertyValue((int)value!);
+ if (type == typeof(uint)) return value => new PropertyValue((uint)value!);
+ if (type == typeof(long)) return value => new PropertyValue((long)value!);
+ if (type == typeof(ulong)) return value => new PropertyValue((ulong)value!);
+ if (type == typeof(IntPtr)) return value => new PropertyValue((IntPtr)value!);
+ if (type == typeof(UIntPtr)) return value => new PropertyValue((UIntPtr)value!);
+ if (type == typeof(float)) return value => new PropertyValue((float)value!);
+ if (type == typeof(double)) return value => new PropertyValue((double)value!);
+ if (type == typeof(Guid)) return value => new PropertyValue((Guid)value!);
+ if (type == typeof(DateTime)) return value => new PropertyValue((DateTime)value!);
+ if (type == typeof(DateTimeOffset)) return value => new PropertyValue((DateTimeOffset)value!);
+ if (type == typeof(TimeSpan)) return value => new PropertyValue((TimeSpan)value!);
+ if (type == typeof(decimal)) return value => new PropertyValue((decimal)value!);
return value => new PropertyValue(value);
}
-
- public object ReferenceValue
+ public object? ReferenceValue
{
get
{
/// <returns></returns>
private static Func<PropertyValue, PropertyValue> GetReferenceTypePropertyGetter(PropertyInfo property)
{
- var helper = (TypeHelper)Activator.CreateInstance(typeof(ReferenceTypeHelper<>).MakeGenericType(property.DeclaringType));
+ var helper = (TypeHelper)Activator.CreateInstance(typeof(ReferenceTypeHelper<>).MakeGenericType(property.DeclaringType))!;
return helper.GetPropertyGetter(property);
}
#else
private
#endif
- sealed class ReferenceTypeHelper<TContainer> : TypeHelper where TContainer : class
+ sealed class ReferenceTypeHelper<TContainer> : TypeHelper where TContainer : class?
{
public override Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property)
{
if (!Statics.IsValueType(type))
{
- var getter = (Func<TContainer, object>)GetGetMethod(property, type);
- return container => new PropertyValue(getter((TContainer)container.ReferenceValue));
+ var getter = (Func<TContainer, object?>)GetGetMethod(property, type);
+ return container => new PropertyValue(getter((TContainer)container.ReferenceValue!)); // TODO-NULLABLE-GENERIC: Re-review
}
else
{
if (type.GetTypeInfo().IsEnum)
type = Enum.GetUnderlyingType(type);
- if (type == typeof(bool)) { var f = (Func<TContainer, bool>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(byte)) { var f = (Func<TContainer, byte>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(sbyte)) { var f = (Func<TContainer, sbyte>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(char)) { var f = (Func<TContainer, char>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(short)) { var f = (Func<TContainer, short>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(ushort)) { var f = (Func<TContainer, ushort>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(int)) { var f = (Func<TContainer, int>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(uint)) { var f = (Func<TContainer, uint>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(long)) { var f = (Func<TContainer, long>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(ulong)) { var f = (Func<TContainer, ulong>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(IntPtr)) { var f = (Func<TContainer, IntPtr>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(UIntPtr)) { var f = (Func<TContainer, UIntPtr>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(float)) { var f = (Func<TContainer, float>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(double)) { var f = (Func<TContainer, double>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Guid)) { var f = (Func<TContainer, Guid>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(DateTime)) { var f = (Func<TContainer, DateTime>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(DateTimeOffset)) { var f = (Func<TContainer, DateTimeOffset>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(TimeSpan)) { var f = (Func<TContainer, TimeSpan>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(decimal)) { var f = (Func<TContainer, decimal>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(bool)) { var f = (Func<TContainer, bool>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(byte)) { var f = (Func<TContainer, byte>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(sbyte)) { var f = (Func<TContainer, sbyte>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(char)) { var f = (Func<TContainer, char>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(short)) { var f = (Func<TContainer, short>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(ushort)) { var f = (Func<TContainer, ushort>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(int)) { var f = (Func<TContainer, int>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(uint)) { var f = (Func<TContainer, uint>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(long)) { var f = (Func<TContainer, long>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(ulong)) { var f = (Func<TContainer, ulong>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(IntPtr)) { var f = (Func<TContainer, IntPtr>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(UIntPtr)) { var f = (Func<TContainer, UIntPtr>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(float)) { var f = (Func<TContainer, float>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(double)) { var f = (Func<TContainer, double>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(Guid)) { var f = (Func<TContainer, Guid>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(DateTime)) { var f = (Func<TContainer, DateTime>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(DateTimeOffset)) { var f = (Func<TContainer, DateTimeOffset>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(TimeSpan)) { var f = (Func<TContainer, TimeSpan>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
+ if (type == typeof(decimal)) { var f = (Func<TContainer, decimal>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review
return container => new PropertyValue(property.GetValue(container.ReferenceValue));
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using Interlocked = System.Threading.Interlocked;
/// </typeparam>
internal static class SimpleEventTypes<T>
{
- private static TraceLoggingEventTypes instance;
+ private static TraceLoggingEventTypes? instance;
public static TraceLoggingEventTypes Instance
{
var info = TraceLoggingTypeInfo.GetInstance(typeof(T), null);
var newInstance = new TraceLoggingEventTypes(info.Name, info.Tags, new TraceLoggingTypeInfo[] { info });
Interlocked.CompareExchange(ref instance, newInstance, null);
+ Debug.Assert(instance != null);
return instance;
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
using System.Reflection;
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format)
{
collector.AddGroup(name);
return;
}
- public override object GetData(object value)
+ public override object? GetData(object? value)
{
return null;
}
this.nativeFormat = nativeFormat;
}
- public override void WriteMetadata(TraceLoggingMetadataCollector collector, string name, EventFieldFormat format)
+ public override void WriteMetadata(TraceLoggingMetadataCollector collector, string? name, EventFieldFormat format)
{
- collector.AddScalar(name, formatFunc(format, nativeFormat));
+ collector.AddScalar(name!, formatFunc(format, nativeFormat));
}
public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
this.elementSize = elementSize;
}
- public override void WriteMetadata(TraceLoggingMetadataCollector collector, string name, EventFieldFormat format)
+ public override void WriteMetadata(TraceLoggingMetadataCollector collector, string? name, EventFieldFormat format)
{
- collector.AddArray(name, formatFunc(format, nativeFormat));
+ collector.AddArray(name!, formatFunc(format, nativeFormat));
}
public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format)
{
- collector.AddNullTerminatedString(name, Statics.MakeDataType(TraceLoggingDataType.Utf16String, format));
+ collector.AddNullTerminatedString(name!, Statics.MakeDataType(TraceLoggingDataType.Utf16String, format));
}
public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
- collector.AddNullTerminatedString((string)value.ReferenceValue);
+ collector.AddNullTerminatedString((string?)value.ReferenceValue);
}
- public override object GetData(object value)
+ public override object GetData(object? value)
{
- if(value == null)
+ if (value == null)
{
return "";
}
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format)
{
- collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.FileTime, format));
+ collector.AddScalar(name!, Statics.MakeDataType(TraceLoggingDataType.FileTime, format));
}
public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
public DateTimeOffsetTypeInfo() : base(typeof(DateTimeOffset)) { }
- public override void WriteMetadata(TraceLoggingMetadataCollector collector, string name, EventFieldFormat format)
+ public override void WriteMetadata(TraceLoggingMetadataCollector collector, string? name, EventFieldFormat format)
{
var group = collector.AddGroup(name);
group.AddScalar("Ticks", Statics.MakeDataType(TraceLoggingDataType.FileTime, format));
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format)
{
- collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.Int64, format));
+ collector.AddScalar(name!, Statics.MakeDataType(TraceLoggingDataType.Int64, format));
}
public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format)
{
- collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.Double, format));
+ collector.AddScalar(name!, Statics.MakeDataType(TraceLoggingDataType.Double, format));
}
public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format)
{
var group = collector.AddGroup(name);
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
using System.Reflection;
/// This is useful for a two pass approach where you figure out how big to
/// make the array, and then you fill it in.
/// </summary>
- public static void EncodeTags(int tags, ref int pos, byte[] metadata)
+ public static void EncodeTags(int tags, ref int pos, byte[]? metadata)
{
// We transmit the low 28 bits of tags, high bits first, 7 bits at a time.
var tagsLeft = tags & 0xfffffff;
}
}
- public static void CheckName(string name)
+ public static void CheckName(string? name)
{
if (name != null && 0 <= name.IndexOf('\0'))
{
kinds of reflection operations are being done.
*/
- public static object CreateInstance(Type type, params object[] parameters)
+ public static object? CreateInstance(Type type, params object?[]? parameters)
{
return Activator.CreateInstance(type, parameters);
}
}
public static AttributeType GetCustomAttribute<AttributeType>(PropertyInfo propInfo)
- where AttributeType : Attribute
+ where AttributeType : Attribute?
{
- AttributeType result = null;
+ AttributeType result = null!; // TODO-NULLABLE-GENERIC: re-review
#if (ES_BUILD_PCL || ES_BUILD_PN)
foreach (var attrib in propInfo.GetCustomAttributes<AttributeType>(false))
{
}
public static AttributeType GetCustomAttribute<AttributeType>(Type type)
- where AttributeType : Attribute
+ where AttributeType : Attribute?
{
- AttributeType result = null;
+ AttributeType result = null!; // TODO-NULLABLE-GENERIC: re-review
#if (ES_BUILD_PCL || ES_BUILD_PN)
foreach (var attrib in type.GetTypeInfo().GetCustomAttributes<AttributeType>(false))
{
return type.GetGenericArguments();
}
- public static Type FindEnumerableElementType(Type type)
+ public static Type? FindEnumerableElementType(Type type)
{
- Type elementType = null;
+ Type? elementType = null;
if (IsGenericMatch(type, typeof(IEnumerable<>)))
{
recursionCheck.Add(dataType);
- var eventAttrib = Statics.GetCustomAttribute<EventDataAttribute>(dataType);
+ var eventAttrib = Statics.GetCustomAttribute<EventDataAttribute?>(dataType);
if (eventAttrib != null ||
- Statics.GetCustomAttribute<CompilerGeneratedAttribute>(dataType) != null ||
+ Statics.GetCustomAttribute<CompilerGeneratedAttribute?>(dataType) != null ||
IsGenericMatch(dataType, typeof(KeyValuePair<,>)))
{
var analysis = new TypeAnalysis(dataType, eventAttrib, recursionCheck);
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Security;
/// <param name="value">
/// Value to be added. A null value is treated as a zero-length string.
/// </param>
- public void AddNullTerminatedString(string value)
+ public void AddNullTerminatedString(string? value)
{
DataCollector.ThreadInstance.AddNullTerminatedString(value);
}
/// <param name="value">
/// Value to be added. A null value is treated as a zero-length string.
/// </param>
- public void AddBinary(string value)
+ public void AddBinary(string? value)
{
DataCollector.ThreadInstance.AddBinary(value, value == null ? 0 : value.Length * 2);
}
public void AddArray(PropertyValue value, int elementSize)
{
- Array array = (Array)value.ReferenceValue;
+ Array? array = (Array?)value.ReferenceValue;
DataCollector.ThreadInstance.AddArray(array, array == null ? 0 : array.Length, elementSize);
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
// This program uses code hyperlinks available as part of the HyperAddin Visual Studio plug-in.
// It is available from http://www.codeplex.com/hyperAddin
public partial class EventSource
{
#if FEATURE_MANAGED_ETW
- private byte[] providerMetadata;
+ private byte[] providerMetadata = null!;
#endif
#if FEATURE_PERFTRACING
public EventSource(
string eventSourceName,
EventSourceSettings config,
- params string[] traits)
+ params string[]? traits)
: this(
eventSourceName == null ? new Guid() : GenerateGuidFromName(eventSourceName.ToUpperInvariant()),
- eventSourceName,
+ eventSourceName!,
config, traits)
{
if (eventSourceName == null)
/// create the fields of the event.
/// </param>
public unsafe void Write<T>(
- string eventName,
+ string? eventName,
T data)
{
if (!this.IsEnabled())
/// create the fields of the event.
/// </param>
public unsafe void Write<T>(
- string eventName,
+ string? eventName,
EventSourceOptions options,
T data)
{
/// create the fields of the event.
/// </param>
public unsafe void Write<T>(
- string eventName,
+ string? eventName,
ref EventSourceOptions options,
ref T data)
{
/// create the fields of the event.
/// </param>
public unsafe void Write<T>(
- string eventName,
+ string? eventName,
ref EventSourceOptions options,
ref Guid activityId,
ref Guid relatedActivityId,
/// eventTypes parameter.
/// </param>
private unsafe void WriteMultiMerge(
- string eventName,
+ string? eventName,
ref EventSourceOptions options,
TraceLoggingEventTypes eventTypes,
Guid* activityID,
/// eventTypes parameter.
/// </param>
private unsafe void WriteMultiMergeInner(
- string eventName,
+ string? eventName,
ref EventSourceOptions options,
TraceLoggingEventTypes eventTypes,
Guid* activityID,
/// fields described by the eventTypes parameter.
/// </param>
internal unsafe void WriteMultiMerge(
- string eventName,
+ string? eventName,
ref EventSourceOptions options,
TraceLoggingEventTypes eventTypes,
Guid* activityID,
}
private unsafe void WriteImpl(
- string eventName,
+ string? eventName,
ref EventSourceOptions options,
- object data,
+ object? data,
Guid* pActivityId,
Guid* pRelatedActivityId,
TraceLoggingEventTypes eventTypes)
var pinCount = eventTypes.pinCount;
var scratch = stackalloc byte[eventTypes.scratchSize];
var descriptors = stackalloc EventData[eventTypes.dataCount + 3];
- for(int i=0; i<eventTypes.dataCount + 3; i++)
+ for (int i = 0; i < eventTypes.dataCount + 3; i++)
descriptors[i] = default;
var pins = stackalloc GCHandle[pinCount];
{
if (opcode == EventOpcode.Start)
{
+ Debug.Assert(eventName != null, "GetOpcodeWithDefault should not returned Start when eventName is null");
m_activityTracker.OnStart(m_name, eventName, 0, ref activityId, ref relatedActivityId, options.ActivityOptions);
}
else if (opcode == EventOpcode.Stop)
{
+ Debug.Assert(eventName != null, "GetOpcodeWithDefault should not returned Stop when eventName is null");
m_activityTracker.OnStop(m_name, eventName, 0, ref activityId);
}
if (activityId != Guid.Empty)
// TODO enable filtering for listeners.
if (m_Dispatchers != null)
{
- var eventData = (EventPayload)(eventTypes.typeInfos[0].GetData(data));
+ var eventData = (EventPayload?)(eventTypes.typeInfos[0].GetData(data));
WriteToAllListeners(eventName, ref descriptor, nameInfo.tags, pActivityId, pRelatedActivityId, eventData);
}
}
}
- private unsafe void WriteToAllListeners(string eventName, ref EventDescriptor eventDescriptor, EventTags tags, Guid* pActivityId, Guid* pChildActivityId, EventPayload payload)
+ private unsafe void WriteToAllListeners(string? eventName, ref EventDescriptor eventDescriptor, EventTags tags, Guid* pActivityId, Guid* pChildActivityId, EventPayload? payload)
{
EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
eventCallbackArgs.EventName = eventName;
if (payload != null)
{
- eventCallbackArgs.Payload = new ReadOnlyCollection<object>((IList<object>)payload.Values);
+ eventCallbackArgs.Payload = new ReadOnlyCollection<object?>((IList<object?>)payload.Values);
eventCallbackArgs.PayloadNames = new ReadOnlyCollection<string>((IList<string>)payload.Keys);
}
throw new ArgumentException(SR.Format(SR.EventSource_BadHexDigit, c), "traits");
}
- private NameInfo UpdateDescriptor(
- string name,
+ private NameInfo? UpdateDescriptor(
+ string? name,
TraceLoggingEventTypes eventInfo,
ref EventSourceOptions options,
out EventDescriptor descriptor)
{
- NameInfo nameInfo = null;
+ NameInfo? nameInfo = null;
int identity = 0;
byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0
? options.level
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
using Interlocked = System.Threading.Interlocked;
{
internal readonly TraceLoggingTypeInfo[] typeInfos;
#if FEATURE_PERFTRACING
- internal readonly string[] paramNames;
+ internal readonly string[]? paramNames;
#endif
internal readonly string name;
internal readonly EventTags tags;
params Type[] types)
: this(tags, name, MakeArray(types))
{
- return;
}
/// <summary>
params TraceLoggingTypeInfo[] typeInfos)
: this(tags, name, MakeArray(typeInfos))
{
- return;
}
internal TraceLoggingEventTypes(
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
internal class TraceLoggingMetadataCollector
{
private readonly Impl impl;
- private readonly FieldMetadata currentGroup;
+ private readonly FieldMetadata? currentGroup;
private int bufferedArrayFieldCount = int.MinValue;
/// <summary>
/// <returns>
/// A new metadata collector that can be used to add fields to the group.
/// </returns>
- public TraceLoggingMetadataCollector AddGroup(string name)
+ public TraceLoggingMetadataCollector AddGroup(string? name)
{
TraceLoggingMetadataCollector result = this;
this.BeginningBufferedArray) // Error, FieldMetadata's constructor will throw the appropriate exception.
{
var newGroup = new FieldMetadata(
- name,
+ name!,
TraceLoggingDataType.Struct,
this.Tags,
this.BeginningBufferedArray);
this.bufferNesting--;
}
- public int Encode(byte[] metadata)
+ public int Encode(byte[]? metadata)
{
int size = 0;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
private readonly EventOpcode opcode = (EventOpcode)(-1);
private readonly EventTags tags;
private readonly Type dataType;
- private readonly Func<object, PropertyValue> propertyValueFactory;
+ private readonly Func<object?, PropertyValue> propertyValueFactory;
internal TraceLoggingTypeInfo(Type dataType)
{
get { return this.dataType; }
}
- internal Func<object, PropertyValue> PropertyValueFactory
+ internal Func<object?, PropertyValue> PropertyValueFactory
{
get { return this.propertyValueFactory; }
}
/// </param>
public abstract void WriteMetadata(
TraceLoggingMetadataCollector collector,
- string name,
+ string? name,
EventFieldFormat format);
/// <summary>
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
- public virtual object GetData(object value)
+ public virtual object? GetData(object? value)
{
return value;
}
[ThreadStatic] // per-thread cache to avoid synchronization
- private static Dictionary<Type, TraceLoggingTypeInfo> threadCache;
+ private static Dictionary<Type, TraceLoggingTypeInfo>? threadCache;
- public static TraceLoggingTypeInfo GetInstance(Type type, List<Type> recursionCheck)
+ public static TraceLoggingTypeInfo GetInstance(Type type, List<Type>? recursionCheck)
{
var cache = threadCache ?? (threadCache = new Dictionary<Type, TraceLoggingTypeInfo>());
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
using System.Reflection;
internal sealed class TypeAnalysis
{
internal readonly PropertyAnalysis[] properties;
- internal readonly string name;
+ internal readonly string? name;
internal readonly EventKeywords keywords;
internal readonly EventLevel level = (EventLevel)(-1);
internal readonly EventOpcode opcode = (EventOpcode)(-1);
public TypeAnalysis(
Type dataType,
- EventDataAttribute eventAttrib,
+ EventDataAttribute? eventAttrib,
List<Type> recursionCheck)
{
var propertyInfos = Statics.GetProperties(dataType);
continue;
}
- MethodInfo getterInfo = Statics.GetGetMethod(propertyInfo);
+ MethodInfo? getterInfo = Statics.GetGetMethod(propertyInfo);
if (getterInfo == null)
{
continue;
var propertyType = propertyInfo.PropertyType;
var propertyTypeInfo = TraceLoggingTypeInfo.GetInstance(propertyType, recursionCheck);
- var fieldAttribute = Statics.GetCustomAttribute<EventFieldAttribute>(propertyInfo);
+ var fieldAttribute = Statics.GetCustomAttribute<EventFieldAttribute?>(propertyInfo);
string propertyName =
fieldAttribute != null && fieldAttribute.Name != null
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
/*============================================================
**
**