-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Reduce the cost of creating a MemoryMappedFile #63790
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
Conversation
|
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsExplanation:
Windows
Unix
Related to #62768
|
...libraries/System.IO.MemoryMappedFiles/src/Microsoft/Win32/SafeMemoryMappedFileHandle.Unix.cs
Show resolved
Hide resolved
| SetHandle(handlePtr); | ||
| } | ||
|
|
||
| protected override void Dispose(bool disposing) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going be an observable behavior change for user defined FileStreams? The potential user-defined Dispose is not going to be called anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, although that looks like it's already a discrepancy between our Windows and Unix implementation, with the Windows implementation not Dispose'ing of the file stream and the Unix implementation doing so (unless I'm missing it in the code). While it would then be a behavior change on Unix, as the Unix implementation is trying to match the pre-existing Windows semantics it seems like a reasonable bug fix.
...libraries/System.IO.MemoryMappedFiles/src/Microsoft/Win32/SafeMemoryMappedFileHandle.Unix.cs
Show resolved
Hide resolved
| long fileSize = mode switch | ||
| { | ||
| FileMode.CreateNew or FileMode.Create => 0, // the file is brand new | ||
| _ => RandomAccess.GetLength(fileHandle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If GetLength throws, the file handle won't be Dispose'd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, doesn't this throw for non-regular files? Is the exception that occurs in such a case the same as it was before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If GetLength throws, the file handle won't be Dispose'd.
that is correct, I am going to add a try-catch block
Also, doesn't this throw for non-regular files?
both FileStream.Length and RandomAccess.GetLength throw for non-seekable files.
the special character device files report that they are seekable and of a size equal zero
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have tests that validate the exception in this case, both with capacity == 0 and capacity != 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have tests that validate the exception in this case, both with capacity == 0 and capacity != 0?
We don't. For both cases, the current implementation would throw for non-seekable file (without closing the handle).
For capacity == 0 here when accessing fileStream.Length:
Line 159 in 8d8ef6d
| if (capacity == 0 && fileStream.Length == 0) |
For capacity != 0 here when accessing fileStream.Length:
Lines 16 to 22 in 8d8ef6d
| if (access == MemoryMappedFileAccess.Read && capacity > fileStream.Length) | |
| { | |
| throw new ArgumentException(SR.Argument_ReadAccessWithLargeCapacity); | |
| } | |
| // one can always create a small view if they do not want to map an entire file | |
| if (fileStream.Length > capacity) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stephentoub I've sent a PR with tests #63927
Once it's gets merged, I am going to sync this PR with main branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stephentoub I've merged the tests into this PR and they are all passing. PTAL
src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs
Show resolved
Hide resolved
src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs
Outdated
Show resolved
Hide resolved
...braries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.Unix.cs
Outdated
Show resolved
Hide resolved
37e5f05 to
59e4f24
Compare
Explanation:
FileStream, we can use more lightweightSafeFileHandle. It reduces the managed allocations.Windows
Unix
Related to #62768