-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
API Proposal: MemoryMappedFile constructor #33206
Comments
|
A method parameter typed IDisposable seems unusual. I do not see other examples in our reference assemblies. Is there any disadavntage to just passing the FileStream and bool? It may not be as "pure" but it is perhaps more standard. We "trust" our own implementation to not do anything with the FileSTream other than dispose it (or not). This API would also be a little easier to use as there is no need for the caller to invent a "disposable wrapper" for the FileStream. |
The Unix version of The Windows version does not have a reference to the If we wanted to make the Windows version similar to the Unix one, we could add a similar constructor instead. Notice that the constructor has a boolean to indicate if the passed fileStream is related to the handle or not. It's a similar problem to the proposed constructor. @JeremyKuhne what are your thoughts on this? |
I understand it's unusual. The other constructor (the existing one that is currently private) follows a pattern that we already have in other places (having a
If the user can pass a FileStream that is completely unrelated to the passed handle, and the only reason why the FileStream is needed is so it can be disposed (it's strongest form, the stream functionality, is not used), then let's just allow passing it as an IDisposable (its highest abstraction). @bartonjs worded this suggestion better in his comment :) |
Yup, just a thought - I defer to api reviewers.. |
I'm not sure how you would do it without making it public or moving the type to FileSystem.Accesscontrol and type forwarding. The Unix one is internal. We can bring it up as an option.
I prefer the |
The problem we had with it during the initial review is that the FIleStream and file handle are being provided as peers; but there's no enforcement of their relationship (and, in fact, no requirement that they be related). If it took /just/ the FileStream and the boolean (and internally re-extracted the handle), sure. It's the triplet that seems weird. The only reason for the FileStream parameter in the internal ctor is to call Dispose on it later... hence the suggestion of IDisposable. (The "take the weakest type you require" idiom) |
namespace System.IO.MemoryMappedFiles
{
public partial class MemoryMappedFile
{
public MemoryMappedFile(SafeMemoryMappedFileHandle handle, IDisposable fileStream);
}
} |
We will close the PR and come back to this if a customer requests the feature. |
Summary
A
MemoryMappedFile
constructor is needed by theMemoryMappedFileAcl
APIs that we are porting from .NET Framework.Both classes are part of the same namespace,
System.IO.MemoryMappedFiles
, but they live in different assemblies:MemoryMappedFile
lives inSystem.IO.MemoryMappedFiles
, butMemoryMappedFileAcl
lives inSystem.IO.FileSystem.AccessControl
, which prevents the latter from consuming the existing constructor fromMemoryMappedFile
.Rationale and Usage
The APIs were approved in this proposal. They are being implemented in this PR (code complete).
The three main
MemoryMappedFileAcl
methods areCreateFromFile
,CreateNew
andCreateOrOpen
, which allow either creating or getting aMemoryMappedFile
object using the specified ACL security. The method that needs to consume the constructor we want to make public isCreateFromFile
.Having the
MemoryMappedFile
and theMemoryMappedFileAcl
classes in separate assemblies presents a few problems:InternalsVisibleToAttribute
(it would expose all internals).In .NET Framework, the
CreateFromFile
method lives insideMemoryMappedFile
, allowing to call the required constructor, which is private. The constructor receives the handle of the file, the file stream of that same file and a boolean indicating if the file stream should be disposed when the memory mapped file is created (Reference Source):The constructor exists in .NET Core with the same signature as in .NET Framework, but it would have to be slightly changed so it can be approved:
Proposed API
Differences with the .NET Framework constructor:
FileStream
object or theBoolean
. Since theFileStream
object is only used to call itsDispose()
method, this means we can instead pass its highest abstraction, theIDisposable
.FileStream
to be left open or not, but we need to ensure it is rooted by theMemoryMappedFile
, so:FileStream
to be disposed when theMemoryMappedFile
is disposed, then we can pass theFileStream
itself.FileStream
to remain open after theMemoryMappedFile
is disposed, we can pass a disposable wrapper for theFileStream
, to ensure it's rooted.Examples
The current proposal is already being used in the PR:
The constructor is being consumed by
CreateFromFile
, with either theFileStream
or the rooter class being passed:https://github.com/carlossanlop/runtime/blob/MemoryMappedFileAcl/src/libraries/System.IO.FileSystem.AccessControl/src/System/IO/MemoryMappedFiles/MemoryMappedFileAcl.cs#L42-L68
The constructor is defined here:
https://github.com/carlossanlop/runtime/blob/MemoryMappedFileAcl/src/libraries/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.cs#L51-L71
The unit tests are located here:
https://github.com/carlossanlop/runtime/blob/MemoryMappedFileAcl/src/libraries/System.IO.FileSystem.AccessControl/tests/MemoryMappedFileAclTests.cs
cc @JeremyKuhne @bartonjs @Jozkee
The text was updated successfully, but these errors were encountered: