Skip to content

Commit 7bddd96

Browse files
authored
bpo-45621: Small changes to mmap (GH-29247)
* Small tidy-ups / comments * Use randomized names when testing tagged mmaps to avoid any risk of parallel tests treading on each others' toes
1 parent 074fa57 commit 7bddd96

File tree

2 files changed

+21
-24
lines changed

2 files changed

+21
-24
lines changed

Lib/test/test_mmap.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import itertools
88
import random
99
import socket
10+
import string
1011
import sys
1112
import weakref
1213

@@ -15,6 +16,10 @@
1516

1617
PAGESIZE = mmap.PAGESIZE
1718

19+
tagname_prefix = f'python_{os.getpid()}_test_mmap'
20+
def random_tagname(length=10):
21+
suffix = ''.join(random.choices(string.ascii_uppercase, k=length))
22+
return f'{tagname_prefix}_{suffix}'
1823

1924
class MmapTests(unittest.TestCase):
2025

@@ -610,21 +615,23 @@ def test_tagname(self):
610615
data1 = b"0123456789"
611616
data2 = b"abcdefghij"
612617
assert len(data1) == len(data2)
618+
tagname1 = random_tagname()
619+
tagname2 = random_tagname()
613620

614621
# Test same tag
615-
m1 = mmap.mmap(-1, len(data1), tagname="foo")
622+
m1 = mmap.mmap(-1, len(data1), tagname=tagname1)
616623
m1[:] = data1
617-
m2 = mmap.mmap(-1, len(data2), tagname="foo")
624+
m2 = mmap.mmap(-1, len(data2), tagname=tagname1)
618625
m2[:] = data2
619626
self.assertEqual(m1[:], data2)
620627
self.assertEqual(m2[:], data2)
621628
m2.close()
622629
m1.close()
623630

624631
# Test different tag
625-
m1 = mmap.mmap(-1, len(data1), tagname="foo")
632+
m1 = mmap.mmap(-1, len(data1), tagname=tagname1)
626633
m1[:] = data1
627-
m2 = mmap.mmap(-1, len(data2), tagname="boo")
634+
m2 = mmap.mmap(-1, len(data2), tagname=tagname2)
628635
m2[:] = data2
629636
self.assertEqual(m1[:], data1)
630637
self.assertEqual(m2[:], data2)
@@ -635,17 +642,18 @@ def test_tagname(self):
635642
@unittest.skipUnless(os.name == 'nt', 'requires Windows')
636643
def test_sizeof(self):
637644
m1 = mmap.mmap(-1, 100)
638-
tagname = "foo"
645+
tagname = random_tagname()
639646
m2 = mmap.mmap(-1, 100, tagname=tagname)
640647
self.assertEqual(sys.getsizeof(m2),
641648
sys.getsizeof(m1) + len(tagname) + 1)
642649

643650
@unittest.skipUnless(os.name == 'nt', 'requires Windows')
644651
def test_crasher_on_windows(self):
645652
# Should not crash (Issue 1733986)
646-
m = mmap.mmap(-1, 1000, tagname="foo")
653+
tagname = random_tagname()
654+
m = mmap.mmap(-1, 1000, tagname=tagname)
647655
try:
648-
mmap.mmap(-1, 5000, tagname="foo")[:] # same tagname, but larger size
656+
mmap.mmap(-1, 5000, tagname=tagname)[:] # same tagname, but larger size
649657
except:
650658
pass
651659
m.close()
@@ -857,7 +865,7 @@ def test_resize_succeeds_with_error_for_second_named_mapping(self):
857865
"""
858866
start_size = 2 * PAGESIZE
859867
reduced_size = PAGESIZE
860-
tagname = "TEST"
868+
tagname = random_tagname()
861869
data_length = 8
862870
data = bytes(random.getrandbits(8) for _ in range(data_length))
863871

Modules/mmapmodule.c

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232

3333
#ifdef MS_WINDOWS
3434
#include <windows.h>
35-
#include <winternl.h>
3635
static int
3736
my_getpagesize(void)
3837
{
@@ -505,21 +504,6 @@ mmap_resize_method(mmap_object *self,
505504
}
506505

507506
{
508-
/*
509-
To resize an mmap on Windows:
510-
511-
- Close the existing mapping
512-
- If the mapping is backed to a named file:
513-
unmap the view, clear the data, and resize the file
514-
If the file can't be resized (eg because it has other mapped references
515-
to it) then let the mapping be recreated at the original size and set
516-
an error code so an exception will be raised.
517-
- Create a new mapping of the relevant size to the same file
518-
- Map a new view of the resized file
519-
- If the mapping is backed by the pagefile:
520-
copy any previous data into the new mapped area
521-
unmap the original view which will release the memory
522-
*/
523507
#ifdef MS_WINDOWS
524508
DWORD error = 0, file_resize_error = 0;
525509
char* old_data = self->data;
@@ -567,6 +551,11 @@ mmap_resize_method(mmap_object *self,
567551
self->tagname);
568552

569553
error = GetLastError();
554+
/* ERROR_ALREADY_EXISTS implies that between our closing the handle above and
555+
calling CreateFileMapping here, someone's created a different mapping with
556+
the same name. There's nothing we can usefully do so we invalidate our
557+
mapping and error out.
558+
*/
570559
if (error == ERROR_ALREADY_EXISTS) {
571560
CloseHandle(self->map_handle);
572561
self->map_handle = NULL;

0 commit comments

Comments
 (0)