Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Doc/c-api/module.rst
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ A module's token -- and the *your_token* value to use in the above code -- is:
of that slot;
- For modules created from an ``PyModExport_*``
:ref:`export hook <extension-export-hook>`: the slots array that the export
hook returned (unless overriden with :c:macro:`Py_mod_token`).
hook returned (unless overridden with :c:macro:`Py_mod_token`).
.. c:macro:: Py_mod_token
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/linecache.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The :mod:`linecache` module defines the following functions:
.. index:: triple: module; search; path

If *filename* indicates a frozen module (starting with ``'<frozen '``), the function
will attepmt to get the real file name from ``module_globals['__file__']`` if
will attempt to get the real file name from ``module_globals['__file__']`` if
*module_globals* is not ``None``.

If a file named *filename* is not found, the function first checks
Expand Down
30 changes: 29 additions & 1 deletion Doc/library/mmap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
Writable :term:`bytes-like object` is now accepted.


.. method:: flush([offset[, size]])
.. method:: flush([offset[, size]], *, flags=MS_SYNC)

Flushes changes made to the in-memory copy of a file back to disk. Without
use of this call there is no guarantee that changes are written back before
Expand All @@ -221,6 +221,12 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
whole extent of the mapping is flushed. *offset* must be a multiple of the
:const:`PAGESIZE` or :const:`ALLOCATIONGRANULARITY`.

The *flags* parameter specifies the synchronization behavior.
*flags* must be one of the :ref:`MS_* constants <ms-constants>` available
on the system.

On Windows, the *flags* parameter is ignored.

``None`` is returned to indicate success. An exception is raised when the
call failed.

Expand All @@ -235,6 +241,9 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
specified alone, and the flush operation will extend from *offset*
to the end of the mmap.

.. versionchanged:: next
Added *flags* parameter to control synchronization behavior.


.. method:: madvise(option[, start[, length]])

Expand Down Expand Up @@ -461,3 +470,22 @@ MAP_* Constants
:data:`MAP_TPRO`, :data:`MAP_TRANSLATED_ALLOW_EXECUTE`, and
:data:`MAP_UNIX03` constants.

.. _ms-constants:

MS_* Constants
++++++++++++++

.. data:: MS_SYNC
MS_ASYNC
MS_INVALIDATE

These flags control the synchronization behavior for :meth:`mmap.flush`:

* :data:`MS_SYNC` - Synchronous flush: writes are scheduled and the call
blocks until they are physically written to storage.
* :data:`MS_ASYNC` - Asynchronous flush: writes are scheduled but the call
returns immediately without waiting for completion.
* :data:`MS_INVALIDATE` - Invalidate cached data: invalidates other mappings
of the same file so they can see the changes.

.. versionadded:: next
4 changes: 2 additions & 2 deletions Doc/library/os.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5993,7 +5993,7 @@ Miscellaneous System Information

.. versionchanged:: 3.13
If :option:`-X cpu_count <-X>` is given or :envvar:`PYTHON_CPU_COUNT` is set,
:func:`cpu_count` returns the overridden value *n*.
:func:`cpu_count` returns the override value *n*.


.. function:: getloadavg()
Expand All @@ -6015,7 +6015,7 @@ Miscellaneous System Information
in the **system**.

If :option:`-X cpu_count <-X>` is given or :envvar:`PYTHON_CPU_COUNT` is set,
:func:`process_cpu_count` returns the overridden value *n*.
:func:`process_cpu_count` returns the override value *n*.

See also the :func:`sched_getaffinity` function.

Expand Down
2 changes: 1 addition & 1 deletion Doc/tools/extensions/grammar_snippet.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class GrammarSnippetDirective(GrammarSnippetBase):
into something similar to Sphinx productionlist, but better suited
for our needs:
- Instead of `::=`, use a colon, as in `Grammar/python.gram`
- Show the listing almost as is, with no auto-aligment.
- Show the listing almost as is, with no auto-alignment.
The only special character is the backtick, which marks tokens.
Unlike Sphinx's productionlist, this directive supports options.
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_build_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
class FormatTestsBase:
@property
def contents(self):
"""Install details file contents. Should be overriden by subclasses."""
"""Install details file contents. Should be overridden by subclasses."""
raise NotImplementedError

@property
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,7 @@ def check_unhashable_key():
with check_unhashable_key():
d.get(key)

# Only TypeError exception is overriden,
# Only TypeError exception is overridden,
# other exceptions are left unchanged.
class HashError:
def __hash__(self):
Expand Down
9 changes: 9 additions & 0 deletions Lib/test/test_mmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,15 @@ def test_flush_parameters(self):
m.flush(PAGESIZE)
m.flush(PAGESIZE, PAGESIZE)

if hasattr(mmap, 'MS_SYNC'):
m.flush(0, PAGESIZE, flags=mmap.MS_SYNC)
if hasattr(mmap, 'MS_ASYNC'):
m.flush(flags=mmap.MS_ASYNC)
if hasattr(mmap, 'MS_INVALIDATE'):
m.flush(PAGESIZE * 2, flags=mmap.MS_INVALIDATE)
if hasattr(mmap, 'MS_ASYNC') and hasattr(mmap, 'MS_INVALIDATE'):
m.flush(0, PAGESIZE, flags=mmap.MS_ASYNC | mmap.MS_INVALIDATE)

@unittest.skipUnless(sys.platform == 'linux', 'Linux only')
@support.requires_linux_version(5, 17, 0)
def test_set_name(self):
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ def check_unhashable_element():
with check_unhashable_element():
myset.discard(elem)

# Only TypeError exception is overriden,
# Only TypeError exception is overridden,
# other exceptions are left unchanged.
class HashError:
def __hash__(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a ``flags`` parameter to :meth:`mmap.mmap.flush` to control synchronization behavior.
67 changes: 57 additions & 10 deletions Modules/clinic/mmapmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 19 additions & 4 deletions Modules/mmapmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1034,12 +1034,15 @@ mmap.mmap.flush
offset: Py_ssize_t = 0
size: Py_ssize_t = -1
/
*
flags: int = 0

[clinic start generated code]*/

static PyObject *
mmap_mmap_flush_impl(mmap_object *self, Py_ssize_t offset, Py_ssize_t size)
/*[clinic end generated code: output=956ced67466149cf input=c50b893bc69520ec]*/
mmap_mmap_flush_impl(mmap_object *self, Py_ssize_t offset, Py_ssize_t size,
int flags)
/*[clinic end generated code: output=4225f4174dc75a53 input=42ba5fb716b6c294]*/
{
CHECK_VALID(NULL);
if (size == -1) {
Expand All @@ -1060,8 +1063,10 @@ mmap_mmap_flush_impl(mmap_object *self, Py_ssize_t offset, Py_ssize_t size)
}
Py_RETURN_NONE;
#elif defined(UNIX)
/* XXX flags for msync? */
if (-1 == msync(self->data + offset, size, MS_SYNC)) {
if (flags == 0) {
flags = MS_SYNC;
}
if (-1 == msync(self->data + offset, size, flags)) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
Expand Down Expand Up @@ -2331,6 +2336,16 @@ mmap_exec(PyObject *module)
ADD_INT_MACRO(module, ACCESS_WRITE);
ADD_INT_MACRO(module, ACCESS_COPY);

#ifdef MS_INVALIDATE
ADD_INT_MACRO(module, MS_INVALIDATE);
#endif
#ifdef MS_ASYNC
ADD_INT_MACRO(module, MS_ASYNC);
#endif
#ifdef MS_SYNC
ADD_INT_MACRO(module, MS_SYNC);
#endif

#ifdef HAVE_MADVISE
// Conventional advice values
#ifdef MADV_NORMAL
Expand Down
Loading