Skip to content

Commit

Permalink
Events unsubscription on package dispose.
Browse files Browse the repository at this point in the history
  • Loading branch information
jwaliszko committed Apr 25, 2014
1 parent 8055925 commit b3ccb45
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 19 deletions.
32 changes: 22 additions & 10 deletions src/Resurrect/AttachCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Resurrect
{
internal class AttachCenter
internal sealed class AttachCenter
{
private readonly IServiceProvider _provider;
private readonly Debugger3 _dteDebugger;
Expand All @@ -24,16 +24,15 @@ internal class AttachCenter
private OleMenuCommand _toggleAutoAttachCommand;

private static AttachCenter _instance;
private static readonly object _locker = new object();
private static readonly object _locker = new object();

private AttachCenter(IServiceProvider provider, Debugger3 dteDebugger)
{
_provider = provider;
_dteDebugger = dteDebugger;
_dteDebugger = dteDebugger;
_watcher = new ManagementEventWatcher("SELECT ProcessID FROM Win32_ProcessStartTrace");

BindCommands();
SendPatrol();
}

public static void Instantiate(IServiceProvider provider, Debugger3 dteDebugger)
Expand Down Expand Up @@ -67,14 +66,27 @@ private void BindCommands()
mcs.AddCommand(_toggleAutoAttachCommand);
}

private void SendPatrol()
public void SendPatrol()
{
Refresh();
Storage.Instance.SolutionActivated += (sender, args) => Refresh();
Storage.Instance.SolutionDeactivated += (sender, args) => Refresh();
Storage.Instance.SolutionActivated += SolutionActivityChanged;
Storage.Instance.SolutionDeactivated += SolutionActivityChanged;
_watcher.EventArrived += ProcessStarted;
}

public void DismissPatrol()
{
Storage.Instance.SolutionActivated -= SolutionActivityChanged;
Storage.Instance.SolutionDeactivated -= SolutionActivityChanged;
_watcher.EventArrived -= ProcessStarted;
_watcher.Stop();
}

void SolutionActivityChanged(object sender, EventArgs e)
{
Refresh();
}

public void Freeze()
{
// Freeze only if all historic processes are attached.
Expand Down Expand Up @@ -180,7 +192,7 @@ private void AttachToProcesses(object sender, EventArgs e)
}
var engines = Storage.Instance.HistoricEngines.Select(x => string.Format("{{{0}}}", x)).ToList();

PerformAttachOperation(runningProcesses, engines);
PerformAttachOperation(runningProcesses, engines);
}

private void ToggleAutoAttachSetting(object sender, EventArgs e)
Expand Down Expand Up @@ -232,7 +244,7 @@ private void PerformAttachOperation(IEnumerable<Process3> processes, IEnumerable
ThrowElevationRequired();
else
ShowMessage(string.Format(
"Unable to attach to the process {0}. A debugger can be already attached (otherwise, unexpected problem has just occured).",
"Unable to attach to the process {0}. A debugger can be already attached (otherwise, unexpected problem has just occurred).",
Path.GetFileName(process.Name)), OLEMSGICON.OLEMSGICON_CRITICAL);
}
catch (Exception ex)
Expand Down Expand Up @@ -288,6 +300,6 @@ private int AskQuestion(string message)
0, // false
out pnResult);
return pnResult;
}
}
}
}
28 changes: 26 additions & 2 deletions src/Resurrect/DebugEventsHunter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,46 @@

namespace Resurrect
{
internal class DebugEventsHunter : IVsDebuggerEvents, IDebugEventCallback2
internal sealed class DebugEventsHunter : IVsDebuggerEvents, IDebugEventCallback2
{
private readonly IVsDebugger _debugger;
private uint _cookie;

private static DebugEventsHunter _instance;
private static readonly object _locker = new object();

public DebugEventsHunter(IVsDebugger debugger)
{
_debugger = debugger;
}

public void Listen()
public static void Instantiate(IVsDebugger debugger)
{
lock (_locker)
{
if (_instance != null)
throw new InvalidOperationException(string.Format("{0} of Resurrect is already instantiated.", _instance.GetType().Name));
_instance = new DebugEventsHunter(debugger);
}
}

public static DebugEventsHunter Instance
{
get { return _instance; }
}

public void SendPatrol()
{
_debugger.AdviseDebuggerEvents(this, out _cookie);
_debugger.AdviseDebugEventCallback(this);
}

public void DismissPatrol()
{
_debugger.UnadviseDebuggerEvents(_cookie);
_debugger.UnadviseDebugEventCallback(this);
}

public int OnModeChange(DBGMODE mode)
{
switch (mode)
Expand Down
18 changes: 15 additions & 3 deletions src/Resurrect/ResurrectPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,25 @@ protected override void Initialize()
if (dteDebugger != null)
{
Storage.Instantiate(UserRegistryRoot, dte);
AttachCenter.Instantiate(this, dteDebugger);
var guard = new DebugEventsHunter(debugger);
guard.Listen();
Storage.Instance.SendPatrol();

AttachCenter.Instantiate(this, dteDebugger);
AttachCenter.Instance.SendPatrol();

DebugEventsHunter.Instantiate(debugger);
DebugEventsHunter.Instance.SendPatrol();
}
}
}
}

protected override void Dispose(bool disposing)
{
DebugEventsHunter.Instance.DismissPatrol();
AttachCenter.Instance.DismissPatrol();
Storage.Instance.DismissPatrol();
base.Dispose(disposing);
}
#endregion
}
}
12 changes: 8 additions & 4 deletions src/Resurrect/Storage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Resurrect
{
internal class Storage
internal sealed class Storage
{
private const string KeyName = "Resurrect";
private string KeyValue
Expand Down Expand Up @@ -36,8 +36,6 @@ private Storage(RegistryKey storeTarget, DTE2 application)
_solutionEvents = application.Events.SolutionEvents;
_historicProcesses = _sessionProcesses = new List<string>();
_historicEngines = _sessionEngines = new List<Guid>();

SendPatrol();
}

public static void Instantiate(RegistryKey storeTarget, DTE2 application)
Expand Down Expand Up @@ -75,12 +73,18 @@ public IEnumerable<Guid> SessionEngines
get { return _sessionEngines; }
}

private void SendPatrol()
public void SendPatrol()
{
_solutionEvents.Opened += SolutionOpened;
_solutionEvents.AfterClosing += SolutionClosed;
}

public void DismissPatrol()
{
_solutionEvents.Opened -= SolutionOpened;
_solutionEvents.AfterClosing -= SolutionClosed;
}

void SolutionOpened()
{
_historicProcesses = GetProcesses().ToList();
Expand Down

0 comments on commit b3ccb45

Please sign in to comment.