Skip to content

Commit

Permalink
Fixes microsoft#558 Crash when uninstalling Python
Browse files Browse the repository at this point in the history
Handles IOException and retries getting subkeys if we race with external registry edits.
Adds test.
  • Loading branch information
zooba committed Jul 9, 2015
1 parent 586d9ac commit d9bf776
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using Microsoft.PythonTools.Analysis;
using Microsoft.VisualStudioTools;
using Microsoft.Win32;
Expand Down Expand Up @@ -143,7 +144,23 @@ private static bool TryParsePythonVersion(string spec, out Version version, out
private bool RegisterInterpreters(HashSet<string> registeredPaths, RegistryKey python, ProcessorArchitecture? arch) {
bool anyAdded = false;

foreach (var key in python.GetSubKeyNames()) {
string[] subKeyNames = null;
for (int retries = 5; subKeyNames == null && retries > 0; --retries) {
try {
subKeyNames = python.GetSubKeyNames();
} catch (IOException) {
// Registry changed while enumerating subkeys. Give it a
// short period to settle down and try again.
// We are almost certainly being called from a background
// thread, so sleeping here is fine.
Thread.Sleep(100);
}
}
if (subKeyNames == null) {
return false;
}

foreach (var key in subKeyNames) {
Version version;
ProcessorArchitecture? arch2;
if (TryParsePythonVersion(key, out version, out arch2)) {
Expand Down
15 changes: 15 additions & 0 deletions Python/Tests/Core/CPythonInterpreterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using System.Linq;
using Microsoft.PythonTools.Interpreter;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Win32;
using TestUtilities;
using TestUtilities.Python;

Expand Down Expand Up @@ -49,5 +50,19 @@ public void FactoryProvider() {
}
}
}

[TestMethod, Priority(0)]
public void DiscoverRegistryRace() {
// https://github.com/Microsoft/PTVS/issues/558

using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Python\PythonCore", true)) {
for (int changes = 0; changes < 1000; ++changes) {
// Doesn't matter about the name - we just want to trigger
// discovery and then remove the key during GetSubKeyNames.
key.CreateSubKey("NotARealInterpreter").Close();
key.DeleteSubKey("NotARealInterpreter", false);
}
}
}
}
}

0 comments on commit d9bf776

Please sign in to comment.