TraceChannelRegistry.cs
75 lines
| 2.3 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r285 | using System; | |
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using Implab.Parallels; | |||
namespace Implab.Diagnostics { | |||
public class TraceChannelRegistry { | |||
class Subscription : IDisposable { | |||
readonly Action<object> m_unsubscribe; | |||
public Subscription(Action<object> unsubscribe) { | |||
m_unsubscribe = unsubscribe; | |||
} | |||
public void Dispose() { | |||
m_unsubscribe(this); | |||
} | |||
} | |||
public static TraceChannelRegistry AllCannels { get; } = new TraceChannelRegistry(); | |||
readonly object m_lock = new object(); | |||
readonly Dictionary<object, Action<ChannelInfo>> m_subscriptions = new Dictionary<object, Action<ChannelInfo>>(); | |||
readonly SimpleAsyncQueue<ChannelInfo> m_channels = new SimpleAsyncQueue<ChannelInfo>(); | |||
internal void NotifyChannelCreated(ChannelInfo channel) { | |||
// notifications can run in parallel | |||
Action<ChannelInfo>[] handlers = null; | |||
lock(m_lock) { | |||
m_channels.Enqueue(channel); | |||
if (m_subscriptions.Count > 0) { | |||
handlers = new Action<ChannelInfo>[m_subscriptions.Count]; | |||
m_subscriptions.Values.CopyTo(handlers, 0); | |||
} | |||
} | |||
if (handlers != null) | |||
foreach(var h in handlers) | |||
h(channel); | |||
} | |||
/// <summary> | |||
/// Subscribes the specified handler to notifications about new trace | |||
/// channels | |||
/// </summary> | |||
/// <param name="handler"></param> | |||
/// <returns></returns> | |||
public IDisposable Subscribe(Action<ChannelInfo> handler, bool existing) { | |||
Safe.ArgumentNotNull(handler, nameof(handler)); | |||
var cookie = new Subscription(RemoveSubscription); | |||
IEnumerable<ChannelInfo> snap; | |||
lock(m_lock) { | |||
m_subscriptions.Add(cookie, handler); | |||
snap = m_channels.Snapshot(); | |||
} | |||
if (existing) { | |||
foreach(var c in snap) | |||
handler(c); | |||
} | |||
return cookie; | |||
} | |||
void RemoveSubscription(object cookie) { | |||
lock(m_lock) | |||
m_subscriptions.Remove(cookie); | |||
} | |||
} | |||
} |