Skip to content

Commit

Permalink
Merge pull request #1379 from microsoft/main
Browse files Browse the repository at this point in the history
Merge 'main' into 'release_mdd'
  • Loading branch information
WardenGnaw authored Dec 2, 2022
2 parents 58a3b11 + e34f879 commit 8685148
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 38 deletions.
2 changes: 1 addition & 1 deletion src/DebugEngineHost/HostNatvisProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static IDisposable WatchNatvisOptionSetting(HostConfigurationStore config
IDisposable disposable = rmw.CurrentMonitor;

// Watch NatvisDiagnostic section
rmw = new RegisterMonitorWrapper(CreateAndStartNatvisDiagnosticMonitor(natvisDiagnosticSection, natvisLogger));
rmw = new RegisterMonitorWrapper(CreateAndStartNatvisDiagnosticMonitor(checkForSection, natvisLogger));

disposable.Dispose();
}
Expand Down
78 changes: 41 additions & 37 deletions src/DebugEngineHost/RegistryMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ private static extern int RegNotifyChangeKeyValue(SafeRegistryHandle hKey, bool

#endregion

private HostConfigurationSection _section;
private readonly HostConfigurationSection _section;
private readonly bool _watchSubtree;

// Set when registry value is changed
private AutoResetEvent m_changeEvent;

// Set when monitoring is stopped
private AutoResetEvent m_stoppedEvent;
private AutoResetEvent _stoppedEvent;

// Members to handle multiple stop calls.
private bool _isStopped = false;
private readonly object _stopLock = new object();

/// <summary>
/// Occurs when the specified registry key has changed.
Expand All @@ -80,9 +81,13 @@ public void Start()

public void Stop()
{
if (m_stoppedEvent != null)
lock (_stopLock)
{
m_stoppedEvent.Set();
if (!_isStopped)
{
_stoppedEvent?.Set();
_isStopped = true;
}
}
}

Expand All @@ -93,53 +98,52 @@ private void Monitor()
bool stopped = false;
try
{
m_stoppedEvent = new AutoResetEvent(false);
m_changeEvent = new AutoResetEvent(false);

IntPtr handle = m_changeEvent.SafeWaitHandle.DangerousGetHandle();

int errorCode = RegNotifyChangeKeyValue(_section.Handle, _watchSubtree, RegChangeNotifyFilter.REG_NOTIFY_CHANGE_NAME | RegChangeNotifyFilter.REG_NOTIFY_CHANGE_LAST_SET, handle, true);
if (errorCode != 0) // 0 is ERROR_SUCCESS
{
_nativsLogger?.WriteLine(LogLevel.Error, Resource.Error_WatchRegistry, errorCode);
}
else
_stoppedEvent = new AutoResetEvent(false);
using (AutoResetEvent registryChangedEvent = new AutoResetEvent(false))
{
while (!stopped)
{
int waitResult = WaitHandle.WaitAny(new WaitHandle[] { m_stoppedEvent, m_changeEvent });
IntPtr handle = registryChangedEvent.SafeWaitHandle.DangerousGetHandle();

if (waitResult == 0)
{
stopped = true;
}
else
int errorCode = RegNotifyChangeKeyValue(_section.Handle, _watchSubtree, RegChangeNotifyFilter.REG_NOTIFY_CHANGE_NAME | RegChangeNotifyFilter.REG_NOTIFY_CHANGE_LAST_SET, handle, true);
if (errorCode != 0) // 0 is ERROR_SUCCESS
{
_nativsLogger?.WriteLine(LogLevel.Error, Resource.Error_WatchRegistry, errorCode);
}
else
{
while (!stopped)
{
errorCode = RegNotifyChangeKeyValue(_section.Handle, _watchSubtree, RegChangeNotifyFilter.REG_NOTIFY_CHANGE_NAME | RegChangeNotifyFilter.REG_NOTIFY_CHANGE_LAST_SET, handle, true);
if (errorCode != 0) // 0 is ERROR_SUCCESS
int waitResult = WaitHandle.WaitAny(new WaitHandle[] { _stoppedEvent, registryChangedEvent });

if (waitResult == 0)
{
_nativsLogger?.WriteLine(LogLevel.Error, Resource.Error_WatchRegistry, errorCode);
break;
stopped = true;
}
else
{
errorCode = RegNotifyChangeKeyValue(_section.Handle, _watchSubtree, RegChangeNotifyFilter.REG_NOTIFY_CHANGE_NAME | RegChangeNotifyFilter.REG_NOTIFY_CHANGE_LAST_SET, handle, true);
if (errorCode != 0) // 0 is ERROR_SUCCESS
{
_nativsLogger?.WriteLine(LogLevel.Error, Resource.Error_WatchRegistry, errorCode);
break;
}
RegChanged?.Invoke(this, null);
}
RegChanged?.Invoke(this, null);
}
}
}
}
finally
{
_section.Dispose();
m_stoppedEvent?.Dispose();
m_changeEvent?.Dispose();
_stoppedEvent.Dispose();
_stoppedEvent = null;

m_stoppedEvent = null;
m_changeEvent = null;
_section.Dispose();
}
}

public void Dispose()
{
m_stoppedEvent?.Dispose();
Stop(); // Stopping the monitor will dispose of the AutoResetEvent and HostConfigurationSection
}
}
}

0 comments on commit 8685148

Please sign in to comment.