Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-44098: Release the GIL while calling mmap() in the mmap module on Windows#14114

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
ZackerySpytz wants to merge4 commits intopython:main
base:main
Choose a base branch
Loading
fromZackerySpytz:bpo-1572968-GIL-mmap-module

Conversation

@ZackerySpytz
Copy link
Contributor

@ZackerySpytzZackerySpytz commentedJun 15, 2019
edited by bedevere-appbot
Loading

It is not safe to release the GIL for other relevant syscalls (for example, ftruncate()
or mremap()) in the mmap module -- segfaults could occur if the mmap
object is accessed from multiple threads.

https://bugs.python.org/issue1572968

@eryksun
Copy link
Contributor

For Windows we should ensure that the GIL is released for all calls toCreateFileMapping /MapViewOfFile,UnmapViewOfFile,SetFilePointer /SetEndOfFile, andCloseHandle (for the section and file handle). TheCloseHandle calls can actually take as long asCreateFileMapping,MapViewOfFile, andUnmapViewOfFile. But to put this into perspective, aCreateFile call takes about 10 times longer. Note thatSetEndOfFile can be on the order of aCreateFile call in terms of I/O system-call overhead and updating filesystem records for allocated disk space, but it doesn't actually zero the extended region on disk, which would be far more expensive. Zeroing occurs on access when the valid data length is extended.


Another issue I notice with this module is thattagname is achar * that we're encoding as UTF-8 and passing to ANSICreateFileMappingA. This creates mojibake for non-ASCII strings on all but the latest Windows 10 systems that have the system locale configure to use UTF-8.tagname should be awchar_t *, and we should be callingCreateFileMappingW.

@ZackerySpytz
Copy link
ContributorAuthor

Thank you, Eryk Sun.

If it is possible for access violations to occur when the mmap object is, for example, accessed by multiple threads, the GIL should not be released.

For what it's worth, I did encounter an access violation when releasing the GIL inmmap.resize() at some point (when using threads). It reminded me ofhttps://bugs.python.org/issue16212, though that bug was encountered on Linux.

I will create a BPO issue for the mojibake issue.

@eryksun
Copy link
Contributor

Right. Releasing the global lock inmmap_resize_method would require redesigning the mmap module to synchronize access with a local lock, similar to what "_io/bufferedio.c" has to do to protect its internal state.resize isn't called frequently enough to justify the potential for introducing new bugs here.

I did a little timing test in C to gauge the relative time taken by the calls needed to create a file, resize it to 128 MiB, get the size, create a section for it, map a view, unmap the view, and close the section and file handles. The following is the result for 1000 trials, keeping only values within a standard deviation for each call, and normalizing the averages against that ofCreateFileMapping:

FunctionAverage Time
CreateFile14.90
SetEndOfFile4.34
GetFileSize0.19
CreateFileMapping1.00
MapViewOfFile0.87
UnmapViewOfFile0.95
CloseHandle, Section0.42
CloseHandle, File3.72

Innew_mmap_object, we're not releasing the GIL forGetFileSize, but it's a relatively inexpensive call. But the cost ofMapViewOfFile is on the order ofCreateFileMapping. The two should be viewed as a unit. For example, givenm_obj->data is initiallyNULL:

Py_BEGIN_ALLOW_THREADSm_obj->map_handle = CreateFileMapping(m_obj->file_handle,                                      NULL,                                      flProtect,                                      size_hi,                                      size_lo,                                      m_obj->tagname);if (m_obj->map_handle == NULL) {    dwErr = GetLastError();} else {    m_obj->data = (char *) MapViewOfFile(m_obj->map_handle,                                         dwDesiredAccess,                                         off_hi,                                         off_lo,                                         m_obj->size);    if (m_obj->data == NULL) {        dwErr = GetLastError();        CloseHandle(m_obj->map_handle);        m_obj->map_handle = NULL;    }}Py_END_ALLOW_THREADSif (m_obj->data == NULL) {    Py_DECREF(m_obj);    PyErr_SetFromWindowsErr(dwErr);    return NULL;}return (PyObject *)m_obj;

@eryksun
Copy link
Contributor

Innew_mmap_object, we're not releasing the GIL forGetFileSize, but it's a relatively inexpensive call.

On second thought, the file could be remote, in which case the underlyingNtQueryInformationFile:FileStandardInformation call is subject to network latency. We should release the GIL when callingGetFileSize inmmap_size_method andnew_mmap_object.


This is unrelated, but a possible bug. For Unix, shouldn'tmmap_size_method returnPyLong_FromSsize_t(self->size) ifself->fd is -1, like the Windows implementation? Currently in Linuxsize() of an anonymous mapping raisesOSError: [Errno 9] Bad file descriptor.

@brettcannonbrettcannon added the type-bugAn unexpected behavior, bug, or error labelJun 21, 2019
@ambv
Copy link
Contributor

Hey,@isidentical@ZackerySpytz@eryksun: this has been authored and accepted two years back. If this is still relevant, can you rebase onmain?

@netlify
Copy link

netlifybot commentedDec 12, 2022
edited
Loading

Deploy Preview forpython-cpython-preview ready!

NameLink
🔨 Latest commitc196466
🔍 Latest deploy loghttps://app.netlify.com/sites/python-cpython-preview/deploys/6396a25564a80c0009885b80
😎 Deploy Previewhttps://deploy-preview-14114--python-cpython-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to yourNetlify site settings.

@erlend-aaslanderlend-aasland changed the titlebpo-1572968: Release the GIL while calling mmap() in the mmap modulegh-44098: Release the GIL while calling mmap() in the mmap module on WindowsJan 5, 2024
size_hi,
size_lo,
m_obj->tagname);
Py_END_ALLOW_THREADS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This should be after theMapViewOfFile call. We can probably restructure the function to store results in locals and then determine success/failure after we have the GIL back

@python-cla-bot
Copy link

The following commit authors need to sign the Contributor License Agreement:

CLA signed

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@zoobazoobazooba left review comments

@isidenticalisidenticalisidentical approved these changes

@eryksuneryksunAwaiting requested review from eryksun

Assignees

No one assigned

Labels

awaiting core reviewOS-windowstype-bugAn unexpected behavior, bug, or error

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

11 participants

@ZackerySpytz@eryksun@ambv@zooba@isidentical@brettcannon@erlend-aasland@the-knights-who-say-ni@ezio-melotti@bedevere-bot@nanjekyejoannah

[8]ページ先頭

©2009-2025 Movatter.jp