Skip to content

Release mutex when facing AbandonedMutexException #2867

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 20, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions PSReadLine/History.cs
Original file line number Diff line number Diff line change
Expand Up @@ -313,15 +313,24 @@ private bool WithHistoryFileMutexDo(int timeout, Action action)
_historyFileMutex.ReleaseMutex();
}
}

// Consider it a failure if we timed out on the mutex.
return false;
}
catch (AbandonedMutexException)
{
retryCount += 1;

// We acquired the mutex object that was abandoned by another powershell process.
// Now, since we own it, we must release it before retry, otherwise, we will miss
// a release and keep holding the mutex, in which case the 'WaitOne' calls from
// all other powershell processes will time out.
_historyFileMutex.ReleaseMutex();
}
} while (retryCount > 0 && retryCount < 3);

// No errors to report, so consider it a success even if we timed out on the mutex.
return true;
// If we reach here, that means we've done the retries but always got the 'AbandonedMutexException'.
return false;
}

private void WriteHistoryRange(int start, int end, bool overwritten)
Expand Down Expand Up @@ -427,18 +436,16 @@ private bool MaybeReadHistoryFile()

private void ReadHistoryFile()
{
WithHistoryFileMutexDo(1000, () =>
if (File.Exists(Options.HistorySavePath))
{
if (!File.Exists(Options.HistorySavePath))
WithHistoryFileMutexDo(1000, () =>
{
return;
}

var historyLines = File.ReadAllLines(Options.HistorySavePath);
UpdateHistoryFromFile(historyLines, fromDifferentSession: false, fromInitialRead: true);
var fileInfo = new FileInfo(Options.HistorySavePath);
_historyFileLastSavedSize = fileInfo.Length;
});
var historyLines = File.ReadAllLines(Options.HistorySavePath);
UpdateHistoryFromFile(historyLines, fromDifferentSession: false, fromInitialRead: true);
var fileInfo = new FileInfo(Options.HistorySavePath);
_historyFileLastSavedSize = fileInfo.Length;
});
}
}

void UpdateHistoryFromFile(IEnumerable<string> historyLines, bool fromDifferentSession, bool fromInitialRead)
Expand Down