Repository navigation
Make the history file mutext name unique across sessions - #1061
Conversation
|
Rather than hashing, we might as well just use the filename directly. There is a limit (260) in the mutex name, so if the name is too long, I'd drop the leading part of the filename, it's likely not unique. For example, |
|
Backslash |
|
CRC32 is actually pretty bad, I've seen collisions in practice. But I'm mostly objecting to needing to copy the code and hoping for fewer lines of code. There is also a benefit to using the filename - it should be more obvious what the mutex is protecting if you were using low level tools like the module |
|
OK, got your concern. I will update the PR to not rely on the CRC32 hashing function. |
|
If you did want to stick with hashing, I'd use something like fnv-1a instead, it's very little code. |
|
Yes, personally I still want to use a hash algorithm for the unique name purpose. I will use |
|
I suppose using a generated GUID would be too long? |
|
The GUID needs to be generated based on the history file path, so that when the path is changed in a pwsh session, a different mutex name is used to guard that file. |
|
Jason Shirk (@lzybkr) The PR has been updated to use the FNV-1a hashing algorithm. PR description is also updated. Thanks for the suggestion! |
| // Return a reasonably unique name - it's not too important as there will rarely | ||
| // be any contention. | ||
| return "PSReadLineHistoryFile_" + _options.HistorySavePath.GetHashCode(); | ||
| return "PSReadLineHistoryFile_" + FNV1a32Hash.ComputeHash(_options.HistorySavePath); |
There was a problem hiding this comment.
I was going to suggest avoiding the conversion to byte array (can we use a span somehow?) but then realized we probably should be normalizing the name anyway, e.g. ensuring consistent case on Windows.
There was a problem hiding this comment.
we probably should be normalizing the name anyway
Agreed. Update Set-PSReadLineOption to sort of resolve (not really) PSPath. Also call ToLower before sending the file path to hash method.
avoiding the conversion to byte array (can we use a span somehow?)
This is a fun exercise!
We cannot use span because we need to compile it against .NET 4.6.1, but we don't really need to use a span here.
The update ComputeHash(string input) behaves exactly the same as the ComputeHash(string input) implementation in the following code
internal static uint ComputeHash(byte[] buffer)
{
uint hash = FNV32_OFFSETBASIS;
for (int i = 0; i < buffer.Length; i++)
{
hash = (hash ^ buffer[i]) * FNV32_PRIME;
}
return hash;
}
internal static uint ComputeHash(string input)
{
return ComputeHash(Encoding.Unicode.GetBytes(input));
}
e7ad62d to
6226535
Compare
GetHistorySaveFileMutexName()usesGetHashCode()to construct the mutex name.GetHashCode()in .NET Core returns a value that is unique in the current process only, and it results in different mutex name being used for different pwsh sessions for the history file.The
FNV-1ahashing algorithm is used (32-bit) to provide a consistent hash code across different pwsh sessions.