Skip to content

Commit d50a4f3

Browse files
committed
Resizing of anonymous mmaps
1 parent 901e810 commit d50a4f3

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

src/core/IronPython.Modules/mmap.cs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,10 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string? ta
338338
_offset = 0; // offset is ignored without an underlying file
339339
_sourceStream = null;
340340

341+
if (length == 0) {
342+
throw PythonNT.GetOsError(PythonErrno.EINVAL);
343+
}
344+
341345
// work around the .NET bug whereby CreateOrOpen throws on a null mapName
342346
if (_mapName is null) {
343347
_file = MemoryMappedFile.CreateNew(null, length, _fileAccess);
@@ -859,7 +863,7 @@ public Bytes read(int len) {
859863
len = checked((int)(_view.Capacity - pos));
860864
}
861865

862-
if (len == 0) {
866+
if (len <= 0) {
863867
return Bytes.Empty;
864868
}
865869

@@ -960,11 +964,6 @@ public void resize(long newsize) {
960964
}
961965
}
962966

963-
if (_sourceStream == null) {
964-
// resizing is not supported without an underlying file
965-
throw WindowsError(PythonExceptions._OSError.ERROR_INVALID_PARAMETER);
966-
}
967-
968967
if (_view.Capacity == newsize) {
969968
// resizing to the same size
970969
return;
@@ -979,6 +978,33 @@ public void resize(long newsize) {
979978
);
980979
}
981980

981+
if (_sourceStream is null) {
982+
// resizing of anonymous map
983+
// TODO: non-copying implementation?
984+
985+
MemoryMappedFile file;
986+
// work around the .NET bug whereby CreateOrOpen throws on a null mapName
987+
if (_mapName is null) {
988+
file = MemoryMappedFile.CreateNew(null, newsize, _fileAccess);
989+
} else {
990+
Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
991+
file = MemoryMappedFile.CreateOrOpen(_mapName, newsize, _fileAccess);
992+
}
993+
994+
using (var oldStream = _file.CreateViewStream(0, Math.Min(_view.Capacity, newsize))) {
995+
using var newStream = file.CreateViewStream();
996+
oldStream.CopyTo(newStream);
997+
}
998+
999+
_view.Flush();
1000+
_view.Dispose();
1001+
_file.Dispose();
1002+
1003+
_file = file;
1004+
_view = _file.CreateViewAccessor(_offset, newsize, _fileAccess);
1005+
return;
1006+
}
1007+
9821008
_view.Flush();
9831009
_view.Dispose();
9841010
_file.Dispose();

0 commit comments

Comments
 (0)