Skip to content

Commit 9d83b06

Browse files
committed
Moved kernel32 calls to _winapi.
1 parent 868b83d commit 9d83b06

File tree

3 files changed

+295
-71
lines changed

3 files changed

+295
-71
lines changed

Lib/multiprocessing/shared_memory.py

Lines changed: 8 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -27,69 +27,10 @@
2727

2828
if os.name == "nt":
2929
import _winapi
30-
import ctypes
31-
from ctypes import wintypes
32-
33-
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
34-
35-
class MEMORY_BASIC_INFORMATION(ctypes.Structure):
36-
_fields_ = (
37-
('BaseAddress', ctypes.c_void_p),
38-
('AllocationBase', ctypes.c_void_p),
39-
('AllocationProtect', wintypes.DWORD),
40-
('RegionSize', ctypes.c_size_t),
41-
('State', wintypes.DWORD),
42-
('Protect', wintypes.DWORD),
43-
('Type', wintypes.DWORD)
44-
)
4530

46-
PMEMORY_BASIC_INFORMATION = ctypes.POINTER(MEMORY_BASIC_INFORMATION)
4731
PAGE_READONLY = 0x02
4832
PAGE_EXECUTE_READWRITE = 0x04
4933
INVALID_HANDLE_VALUE = -1
50-
ERROR_ALREADY_EXISTS = 183
51-
52-
def _errcheck_bool(result, func, args):
53-
if not result:
54-
raise ctypes.WinError(ctypes.get_last_error())
55-
return args
56-
57-
kernel32.VirtualQuery.errcheck = _errcheck_bool
58-
kernel32.VirtualQuery.restype = ctypes.c_size_t
59-
kernel32.VirtualQuery.argtypes = (
60-
wintypes.LPCVOID,
61-
PMEMORY_BASIC_INFORMATION,
62-
ctypes.c_size_t
63-
)
64-
65-
kernel32.OpenFileMappingW.errcheck = _errcheck_bool
66-
kernel32.OpenFileMappingW.restype = wintypes.HANDLE
67-
kernel32.OpenFileMappingW.argtypes = (
68-
wintypes.DWORD,
69-
wintypes.BOOL,
70-
wintypes.LPCWSTR
71-
)
72-
73-
kernel32.CreateFileMappingW.errcheck = _errcheck_bool
74-
kernel32.CreateFileMappingW.restype = wintypes.HANDLE
75-
kernel32.CreateFileMappingW.argtypes = (
76-
wintypes.HANDLE,
77-
wintypes.LPCVOID,
78-
wintypes.DWORD,
79-
wintypes.DWORD,
80-
wintypes.DWORD,
81-
wintypes.LPCWSTR
82-
)
83-
84-
kernel32.MapViewOfFile.errcheck = _errcheck_bool
85-
kernel32.MapViewOfFile.restype = wintypes.LPVOID
86-
kernel32.MapViewOfFile.argtypes = (
87-
wintypes.HANDLE,
88-
wintypes.DWORD,
89-
wintypes.DWORD,
90-
wintypes.DWORD,
91-
ctypes.c_size_t
92-
)
9334

9435

9536
class WindowsNamedSharedMemory:
@@ -102,31 +43,29 @@ def __init__(self, name, flags=None, mode=384, size=0, read_only=False):
10243
# Attempt to dynamically determine the existing named shared
10344
# memory block's size which is likely a multiple of mmap.PAGESIZE.
10445
try:
105-
h_map = kernel32.OpenFileMappingW(PAGE_READONLY, False, name)
46+
h_map = _winapi.OpenFileMappingW(PAGE_READONLY, False, name)
10647
except OSError:
10748
raise FileNotFoundError(name)
10849
try:
109-
p_buf = kernel32.MapViewOfFile(h_map, PAGE_READONLY, 0, 0, 0)
50+
p_buf = _winapi.MapViewOfFile(h_map, PAGE_READONLY, 0, 0, 0)
11051
finally:
11152
_winapi.CloseHandle(h_map)
112-
mbi = MEMORY_BASIC_INFORMATION()
113-
kernel32.VirtualQuery(p_buf, ctypes.byref(mbi), mmap.PAGESIZE)
114-
size = mbi.RegionSize
53+
size = _winapi.VirtualQuerySize(p_buf)
11554

11655
if flags == O_CREX:
11756
# Create and reserve shared memory block with this name until
11857
# it can be attached to by mmap.
119-
h_map = kernel32.CreateFileMappingW(
58+
h_map = _winapi.CreateFileMappingW(
12059
INVALID_HANDLE_VALUE,
121-
None,
60+
_winapi.NULL,
12261
PAGE_EXECUTE_READWRITE,
123-
size >> 32,
62+
(size >> 32) & 0xFFFFFFFF,
12463
size & 0xFFFFFFFF,
12564
name
12665
)
12766
try:
128-
last_error_code = ctypes.get_last_error()
129-
if last_error_code == ERROR_ALREADY_EXISTS:
67+
last_error_code = _winapi.GetLastError()
68+
if last_error_code == _winapi.ERROR_ALREADY_EXISTS:
13069
raise FileExistsError(f"File exists: {name!r}")
13170
self._mmap = mmap.mmap(-1, size, tagname=name)
13271
finally:

Modules/_winapi.c

Lines changed: 134 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ def create_converter(type_, format_unit):
159159
create_converter('HANDLE', '" F_HANDLE "')
160160
create_converter('HMODULE', '" F_HANDLE "')
161161
create_converter('LPSECURITY_ATTRIBUTES', '" F_POINTER "')
162+
create_converter('LPCVOID', '" F_POINTER "')
162163
163164
create_converter('BOOL', 'i') # F_BOOL used previously (always 'i')
164165
create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter)
@@ -186,8 +187,17 @@ class DWORD_return_converter(CReturnConverter):
186187
self.err_occurred_if("_return_value == PY_DWORD_MAX", data)
187188
data.return_conversion.append(
188189
'return_value = Py_BuildValue("k", _return_value);\n')
190+
191+
class LPVOID_return_converter(CReturnConverter):
192+
type = 'LPVOID'
193+
194+
def render(self, function, data):
195+
self.declare(data)
196+
self.err_occurred_if("_return_value == NULL", data)
197+
data.return_conversion.append(
198+
'return_value = HANDLE_TO_PYNUM(_return_value);\n')
189199
[python start generated code]*/
190-
/*[python end generated code: output=da39a3ee5e6b4b0d input=27456f8555228b62]*/
200+
/*[python end generated code: output=da39a3ee5e6b4b0d input=79464c61a31ae932]*/
191201

192202
#include "clinic/_winapi.c.h"
193203

@@ -464,6 +474,41 @@ _winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name,
464474
return handle;
465475
}
466476

477+
/*[clinic input]
478+
_winapi.CreateFileMappingW -> HANDLE
479+
480+
file_handle: HANDLE
481+
security_attributes: LPSECURITY_ATTRIBUTES
482+
protect: DWORD
483+
max_size_high: DWORD
484+
max_size_low: DWORD
485+
name: LPCWSTR
486+
/
487+
[clinic start generated code]*/
488+
489+
static HANDLE
490+
_winapi_CreateFileMappingW_impl(PyObject *module, HANDLE file_handle,
491+
LPSECURITY_ATTRIBUTES security_attributes,
492+
DWORD protect, DWORD max_size_high,
493+
DWORD max_size_low, LPCWSTR name)
494+
/*[clinic end generated code: output=c6b017501c929de1 input=35cadabe53b3b4da]*/
495+
{
496+
HANDLE handle;
497+
498+
Py_BEGIN_ALLOW_THREADS
499+
handle = CreateFileMappingW(file_handle, security_attributes,
500+
protect, max_size_high, max_size_low,
501+
name);
502+
Py_END_ALLOW_THREADS
503+
504+
if (handle == NULL) {
505+
PyErr_SetFromWindowsErr(0);
506+
handle = INVALID_HANDLE_VALUE;
507+
}
508+
509+
return handle;
510+
}
511+
467512
/*[clinic input]
468513
_winapi.CreateJunction
469514
@@ -1295,6 +1340,64 @@ _winapi_GetVersion_impl(PyObject *module)
12951340

12961341
#pragma warning(pop)
12971342

1343+
/*[clinic input]
1344+
_winapi.MapViewOfFile -> LPVOID
1345+
1346+
file_map: HANDLE
1347+
desired_access: DWORD
1348+
file_offset_high: DWORD
1349+
file_offset_low: DWORD
1350+
number_bytes: size_t
1351+
/
1352+
[clinic start generated code]*/
1353+
1354+
static LPVOID
1355+
_winapi_MapViewOfFile_impl(PyObject *module, HANDLE file_map,
1356+
DWORD desired_access, DWORD file_offset_high,
1357+
DWORD file_offset_low, size_t number_bytes)
1358+
/*[clinic end generated code: output=f23b1ee4823663e3 input=177471073be1a103]*/
1359+
{
1360+
LPVOID address;
1361+
1362+
Py_BEGIN_ALLOW_THREADS
1363+
address = MapViewOfFile(file_map, desired_access, file_offset_high,
1364+
file_offset_low, number_bytes);
1365+
Py_END_ALLOW_THREADS
1366+
1367+
if (address == NULL)
1368+
PyErr_SetFromWindowsErr(0);
1369+
1370+
return address;
1371+
}
1372+
1373+
/*[clinic input]
1374+
_winapi.OpenFileMappingW -> HANDLE
1375+
1376+
desired_access: DWORD
1377+
inherit_handle: BOOL
1378+
name: LPCWSTR
1379+
/
1380+
[clinic start generated code]*/
1381+
1382+
static HANDLE
1383+
_winapi_OpenFileMappingW_impl(PyObject *module, DWORD desired_access,
1384+
BOOL inherit_handle, LPCWSTR name)
1385+
/*[clinic end generated code: output=ad829d0e68cac379 input=68fa4e0f2d5d5c42]*/
1386+
{
1387+
HANDLE handle;
1388+
1389+
Py_BEGIN_ALLOW_THREADS
1390+
handle = OpenFileMappingW(desired_access, inherit_handle, name);
1391+
Py_END_ALLOW_THREADS
1392+
1393+
if (handle == NULL) {
1394+
PyErr_SetFromWindowsErr(0);
1395+
handle = INVALID_HANDLE_VALUE;
1396+
}
1397+
1398+
return handle;
1399+
}
1400+
12981401
/*[clinic input]
12991402
_winapi.OpenProcess -> HANDLE
13001403
@@ -1490,6 +1593,32 @@ _winapi_TerminateProcess_impl(PyObject *module, HANDLE handle,
14901593
Py_RETURN_NONE;
14911594
}
14921595

1596+
/*[clinic input]
1597+
_winapi.VirtualQuerySize -> size_t
1598+
1599+
address: LPCVOID
1600+
/
1601+
[clinic start generated code]*/
1602+
1603+
static size_t
1604+
_winapi_VirtualQuerySize_impl(PyObject *module, LPCVOID address)
1605+
/*[clinic end generated code: output=40c8e0ff5ec964df input=6b784a69755d0bb6]*/
1606+
{
1607+
SIZE_T size_of_buf;
1608+
MEMORY_BASIC_INFORMATION mem_basic_info;
1609+
SIZE_T region_size;
1610+
1611+
Py_BEGIN_ALLOW_THREADS
1612+
size_of_buf = VirtualQuery(address, &mem_basic_info, sizeof(mem_basic_info));
1613+
Py_END_ALLOW_THREADS
1614+
1615+
if (size_of_buf == 0)
1616+
PyErr_SetFromWindowsErr(0);
1617+
1618+
region_size = mem_basic_info.RegionSize;
1619+
return region_size;
1620+
}
1621+
14931622
/*[clinic input]
14941623
_winapi.WaitNamedPipe
14951624
@@ -1719,6 +1848,7 @@ static PyMethodDef winapi_functions[] = {
17191848
_WINAPI_CLOSEHANDLE_METHODDEF
17201849
_WINAPI_CONNECTNAMEDPIPE_METHODDEF
17211850
_WINAPI_CREATEFILE_METHODDEF
1851+
_WINAPI_CREATEFILEMAPPINGW_METHODDEF
17221852
_WINAPI_CREATENAMEDPIPE_METHODDEF
17231853
_WINAPI_CREATEPIPE_METHODDEF
17241854
_WINAPI_CREATEPROCESS_METHODDEF
@@ -1731,11 +1861,14 @@ static PyMethodDef winapi_functions[] = {
17311861
_WINAPI_GETMODULEFILENAME_METHODDEF
17321862
_WINAPI_GETSTDHANDLE_METHODDEF
17331863
_WINAPI_GETVERSION_METHODDEF
1864+
_WINAPI_MAPVIEWOFFILE_METHODDEF
1865+
_WINAPI_OPENFILEMAPPINGW_METHODDEF
17341866
_WINAPI_OPENPROCESS_METHODDEF
17351867
_WINAPI_PEEKNAMEDPIPE_METHODDEF
17361868
_WINAPI_READFILE_METHODDEF
17371869
_WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF
17381870
_WINAPI_TERMINATEPROCESS_METHODDEF
1871+
_WINAPI_VIRTUALQUERYSIZE_METHODDEF
17391872
_WINAPI_WAITNAMEDPIPE_METHODDEF
17401873
_WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF
17411874
_WINAPI_WAITFORSINGLEOBJECT_METHODDEF

0 commit comments

Comments
 (0)