using System; using System.Collections.Generic; using System.Linq; namespace Xilium.CefGlue { public static class CefObjectTracker { [ThreadStatic] private static HashSet _disposables; private class TrackingSession : IDisposable { public static readonly TrackingSession Default = new TrackingSession(stopTracking: true); public static readonly TrackingSession Nop = new TrackingSession(stopTracking: false); private readonly bool _stopTracking; private TrackingSession(bool stopTracking) { _stopTracking = stopTracking; } public void Dispose() { if (_stopTracking) { StopTracking(); } } } /// /// Starts tracking the objects created on the current thread. /// /// public static IDisposable StartTracking() { if (_disposables != null) { return TrackingSession.Nop; // return a nop session, won't stop tracking, the outer most session should do the job } _disposables = new HashSet(); return TrackingSession.Default; } /// /// Disposes the objects registered on the current thread since tracker was started. /// public static void StopTracking() { if (_disposables == null) { return; } var disposables = _disposables.ToArray(); _disposables = null; // set null before running dispose to prevent objects running untrack foreach (var disposable in disposables) { disposable.Dispose(); } } /// /// Registers the specified object to be disposed later. /// /// public static void Track(IDisposable obj) { if (_disposables != null) { _disposables.Add(obj); } } /// /// Removes the specified object from the tracking list. /// /// public static void Untrack(IDisposable obj) { if (_disposables != null) { _disposables.Remove(obj); } } } }