##// END OF EJS Templates
Added IObservable to TraceRegistry
Added IObservable to TraceRegistry

File last commit:

r288:90cef6117ced v3
r288:90cef6117ced v3
Show More
TraceRegistry.cs
85 lines | 2.8 KiB | text/x-csharp | CSharpLexer
cin
Working on Implab.Diagnostics
r286 using System;
using System.Collections.Generic;
using System.Diagnostics;
using Implab.Parallels;
namespace Implab.Diagnostics {
cin
Added IObservable to TraceRegistry
r288 public class TraceRegistry: IObservable<TraceChannel> {
cin
Working on Implab.Diagnostics
r286
class Subscription : IDisposable {
readonly WeakReference<TraceRegistry> m_registry;
public Subscription(TraceRegistry registry) {
m_registry = new WeakReference<TraceRegistry>(registry);
}
public void Dispose() {
TraceRegistry t;
if (m_registry.TryGetTarget(out t))
t.RemoveSubscription(this);
}
}
cin
Added IObservable to TraceRegistry
r288 /// <summary>
/// The global collection of available diagnostic channels
/// </summary>
/// <returns></returns>
cin
Working on Implab.Diagnostics
r286 public static TraceRegistry Global { get; } = new TraceRegistry();
readonly object m_lock = new object();
cin
Added IObservable to TraceRegistry
r288 readonly Dictionary<object, IObserver<TraceChannel>> m_subscriptions = new Dictionary<object, IObserver<TraceChannel>>();
cin
Working on Implab.Diagnostics
r286 readonly SimpleAsyncQueue<TraceChannel> m_channels = new SimpleAsyncQueue<TraceChannel>();
cin
Added IObservable to TraceRegistry
r288 public void Register(TraceChannel channel) {
cin
Working on Implab.Diagnostics
r286 // notifications can run in parallel
cin
Added IObservable to TraceRegistry
r288 IObserver<TraceChannel>[] handlers = null;
cin
Working on Implab.Diagnostics
r286
lock(m_lock) {
m_channels.Enqueue(channel);
if (m_subscriptions.Count > 0) {
cin
Added IObservable to TraceRegistry
r288 handlers = new IObserver<TraceChannel>[m_subscriptions.Count];
cin
Working on Implab.Diagnostics
r286 m_subscriptions.Values.CopyTo(handlers, 0);
}
}
if (handlers != null)
foreach(var h in handlers)
cin
Added IObservable to TraceRegistry
r288 h.OnNext(channel);
cin
Working on Implab.Diagnostics
r286 }
/// <summary>
/// Subscribes the specified handler to notifications about new trace
/// channels
/// </summary>
/// <param name="handler"></param>
/// <returns></returns>
cin
Added IObservable to TraceRegistry
r288 public IDisposable Subscribe(IObserver<TraceChannel> handler) {
cin
Working on Implab.Diagnostics
r286 Safe.ArgumentNotNull(handler, nameof(handler));
var cookie = new Subscription(this);
IEnumerable<TraceChannel> snap;
// lock to ensure that no new channels will be added
// while the subscription is added
lock(m_lock) {
m_subscriptions.Add(cookie, handler);
snap = m_channels.Snapshot();
}
// announce previously declared channels if required
cin
Added IObservable to TraceRegistry
r288 if (snap != null) {
cin
Working on Implab.Diagnostics
r286 foreach(var c in snap)
cin
Added IObservable to TraceRegistry
r288 handler.OnNext(c);
cin
Working on Implab.Diagnostics
r286 }
// return the subscription
return cookie;
}
void RemoveSubscription(object cookie) {
lock(m_lock)
m_subscriptions.Remove(cookie);
}
}
}