Skip to content

Commit eb249ef

Browse files
committed
Add flags parameter on mmap.flush
1 parent 37d16f7 commit eb249ef

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

Doc/library/mmap.rst

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
212212
Writable :term:`bytes-like object` is now accepted.
213213

214214

215-
.. method:: flush([offset[, size]])
215+
.. method:: flush([offset[, size]], *, flags=MS_SYNC)
216216

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

224+
The *flags* parameter specifies the synchronization behavior.
225+
*flags* must be one of the :ref:`MS_* constants <ms-constants>` available
226+
on the system.
227+
228+
On Windows, the *flags* parameter is ignored.
229+
224230
``None`` is returned to indicate success. An exception is raised when the
225231
call failed.
226232

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

244+
.. versionchanged:: next
245+
Added *flags* parameter to control synchronization behavior.
246+
238247

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

@@ -450,3 +459,22 @@ MAP_* Constants
450459
:data:`MAP_TPRO`, :data:`MAP_TRANSLATED_ALLOW_EXECUTE`, and
451460
:data:`MAP_UNIX03` constants.
452461

462+
.. _ms-constants:
463+
464+
MS_* Constants
465+
++++++++++++++
466+
467+
.. data:: MS_SYNC
468+
MS_ASYNC
469+
MS_INVALIDATE
470+
471+
These flags control the synchronization behavior for :meth:`mmap.flush`:
472+
473+
* :data:`MS_SYNC` - Synchronous flush: writes are scheduled and the call
474+
blocks until they are physically written to storage.
475+
* :data:`MS_ASYNC` - Asynchronous flush: writes are scheduled but the call
476+
returns immediately without waiting for completion.
477+
* :data:`MS_INVALIDATE` - Invalidate cached data: invalidates other mappings
478+
of the same file so they can see the changes.
479+
480+
.. versionadded:: next

Lib/test/test_mmap.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,15 @@ def test_flush_parameters(self):
11571157
m.flush(PAGESIZE)
11581158
m.flush(PAGESIZE, PAGESIZE)
11591159

1160+
if hasattr(mmap, 'MS_SYNC'):
1161+
m.flush(0, PAGESIZE, flags=mmap.MS_SYNC)
1162+
if hasattr(mmap, 'MS_ASYNC'):
1163+
m.flush(flags=mmap.MS_ASYNC)
1164+
if hasattr(mmap, 'MS_INVALIDATE'):
1165+
m.flush(PAGESIZE * 2, flags=mmap.MS_INVALIDATE)
1166+
if hasattr(mmap, 'MS_ASYNC') and hasattr(mmap, 'MS_INVALIDATE'):
1167+
m.flush(0, PAGESIZE, flags=mmap.MS_ASYNC | mmap.MS_INVALIDATE)
1168+
11601169

11611170
class LargeMmapTests(unittest.TestCase):
11621171

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add a ``flags`` parameter to :meth:`mmap.mmap.flush` to control synchronization behavior.

Modules/mmapmodule.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -930,13 +930,16 @@ mmap_tell_method(PyObject *op, PyObject *Py_UNUSED(ignored))
930930
}
931931

932932
static PyObject *
933-
mmap_flush_method(PyObject *op, PyObject *args)
933+
mmap_flush_method(PyObject *op, PyObject *args, PyObject *kwargs)
934934
{
935935
Py_ssize_t offset = 0;
936936
Py_ssize_t size = -1;
937+
int flags = MS_SYNC;
937938
mmap_object *self = mmap_object_CAST(op);
939+
static char *kwlist[] = {"offset", "size", "flags", NULL};
938940
CHECK_VALID(NULL);
939-
if (!PyArg_ParseTuple(args, "|nn:flush", &offset, &size)) {
941+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|nn$i:flush", kwlist,
942+
&offset, &size, &flags)) {
940943
return NULL;
941944
}
942945
if (size == -1) {
@@ -957,8 +960,7 @@ mmap_flush_method(PyObject *op, PyObject *args)
957960
}
958961
Py_RETURN_NONE;
959962
#elif defined(UNIX)
960-
/* XXX flags for msync? */
961-
if (-1 == msync(self->data + offset, size, MS_SYNC)) {
963+
if (-1 == msync(self->data + offset, size, flags)) {
962964
PyErr_SetFromErrno(PyExc_OSError);
963965
return NULL;
964966
}
@@ -1203,7 +1205,7 @@ static struct PyMethodDef mmap_object_methods[] = {
12031205
{"close", mmap_close_method, METH_NOARGS},
12041206
{"find", mmap_find_method, METH_VARARGS},
12051207
{"rfind", mmap_rfind_method, METH_VARARGS},
1206-
{"flush", mmap_flush_method, METH_VARARGS},
1208+
{"flush", _PyCFunction_CAST(mmap_flush_method), METH_VARARGS | METH_KEYWORDS},
12071209
#ifdef HAVE_MADVISE
12081210
{"madvise", mmap_madvise_method, METH_VARARGS},
12091211
#endif
@@ -2047,6 +2049,16 @@ mmap_exec(PyObject *module)
20472049
ADD_INT_MACRO(module, ACCESS_WRITE);
20482050
ADD_INT_MACRO(module, ACCESS_COPY);
20492051

2052+
#ifdef MS_INVALIDATE
2053+
ADD_INT_MACRO(module, MS_INVALIDATE);
2054+
#endif
2055+
#ifdef MS_ASYNC
2056+
ADD_INT_MACRO(module, MS_ASYNC);
2057+
#endif
2058+
#ifdef MS_SYNC
2059+
ADD_INT_MACRO(module, MS_SYNC);
2060+
#endif
2061+
20502062
#ifdef HAVE_MADVISE
20512063
// Conventional advice values
20522064
#ifdef MADV_NORMAL

0 commit comments

Comments
 (0)