bpo-40077: Convert mmap.mmap static type to a heap type (GH-23108)

This commit is contained in:
Erlend Egeberg Aasland 2020-11-03 10:38:31 +01:00 committed by GitHub
parent 9568622c99
commit 74b4eda98b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 68 deletions

View File

@ -0,0 +1 @@
Convert :mod:`mmap` to use heap types.

View File

@ -20,6 +20,7 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include "structmember.h" // PyMemberDef
#include <stddef.h> // offsetof() #include <stddef.h> // offsetof()
#ifndef MS_WINDOWS #ifndef MS_WINDOWS
@ -113,10 +114,23 @@ typedef struct {
access_mode access; access_mode access;
} mmap_object; } mmap_object;
typedef struct {
PyTypeObject *mmap_object_type;
} mmap_state;
static mmap_state *
get_mmap_state(PyObject *module)
{
mmap_state *state = PyModule_GetState(module);
assert(state);
return state;
}
static void static void
mmap_object_dealloc(mmap_object *m_obj) mmap_object_dealloc(mmap_object *m_obj)
{ {
PyTypeObject *tp = Py_TYPE(m_obj);
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
if (m_obj->data != NULL) if (m_obj->data != NULL)
@ -142,7 +156,9 @@ mmap_object_dealloc(mmap_object *m_obj)
if (m_obj->weakreflist != NULL) if (m_obj->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) m_obj); PyObject_ClearWeakRefs((PyObject *) m_obj);
Py_TYPE(m_obj)->tp_free((PyObject*)m_obj);
tp->tp_free(m_obj);
Py_DECREF(tp);
} }
static PyObject * static PyObject *
@ -793,6 +809,11 @@ mmap_madvise_method(mmap_object *self, PyObject *args)
} }
#endif // HAVE_MADVISE #endif // HAVE_MADVISE
static struct PyMemberDef mmap_object_members[] = {
{"__weaklistoffset__", T_PYSSIZET, offsetof(mmap_object, weakreflist), READONLY},
{NULL},
};
static struct PyMethodDef mmap_object_methods[] = { static struct PyMethodDef mmap_object_methods[] = {
{"close", (PyCFunction) mmap_close_method, METH_NOARGS}, {"close", (PyCFunction) mmap_close_method, METH_NOARGS},
{"find", (PyCFunction) mmap_find_method, METH_VARARGS}, {"find", (PyCFunction) mmap_find_method, METH_VARARGS},
@ -1035,27 +1056,6 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value)
} }
} }
static PySequenceMethods mmap_as_sequence = {
(lenfunc)mmap_length, /*sq_length*/
0, /*sq_concat*/
0, /*sq_repeat*/
(ssizeargfunc)mmap_item, /*sq_item*/
0, /*sq_slice*/
(ssizeobjargproc)mmap_ass_item, /*sq_ass_item*/
0, /*sq_ass_slice*/
};
static PyMappingMethods mmap_as_mapping = {
(lenfunc)mmap_length,
(binaryfunc)mmap_subscript,
(objobjargproc)mmap_ass_subscript,
};
static PyBufferProcs mmap_as_buffer = {
(getbufferproc)mmap_buffer_getbuf,
(releasebufferproc)mmap_buffer_releasebuf,
};
static PyObject * static PyObject *
new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict); new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict);
@ -1083,47 +1083,39 @@ The default value is MAP_SHARED.\n\
To map anonymous memory, pass -1 as the fileno (both versions)."); To map anonymous memory, pass -1 as the fileno (both versions).");
static PyTypeObject mmap_object_type = { static PyType_Slot mmap_object_slots[] = {
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_new, new_mmap_object},
"mmap.mmap", /* tp_name */ {Py_tp_alloc, PyType_GenericAlloc},
sizeof(mmap_object), /* tp_basicsize */ {Py_tp_dealloc, mmap_object_dealloc},
0, /* tp_itemsize */ {Py_tp_free, PyObject_Del},
/* methods */ {Py_tp_repr, mmap__repr__method},
(destructor)mmap_object_dealloc, /* tp_dealloc */ {Py_tp_doc, (void *)mmap_doc},
0, /* tp_vectorcall_offset */ {Py_tp_methods, mmap_object_methods},
0, /* tp_getattr */ {Py_tp_members, mmap_object_members},
0, /* tp_setattr */ {Py_tp_getset, mmap_object_getset},
0, /* tp_as_async */ {Py_tp_getattro, PyObject_GenericGetAttr},
(reprfunc)mmap__repr__method, /* tp_repr */
0, /* tp_as_number */ /* as sequence */
&mmap_as_sequence, /* tp_as_sequence */ {Py_sq_length, mmap_length},
&mmap_as_mapping, /* tp_as_mapping */ {Py_sq_item, mmap_item},
0, /* tp_hash */ {Py_sq_ass_item, mmap_ass_item},
0, /* tp_call */
0, /* tp_str */ /* as mapping */
PyObject_GenericGetAttr, /* tp_getattro */ {Py_mp_length, mmap_length},
0, /* tp_setattro */ {Py_mp_subscript, mmap_subscript},
&mmap_as_buffer, /* tp_as_buffer */ {Py_mp_ass_subscript, mmap_ass_subscript},
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
mmap_doc, /* tp_doc */ /* as buffer */
0, /* tp_traverse */ {Py_bf_getbuffer, mmap_buffer_getbuf},
0, /* tp_clear */ {Py_bf_releasebuffer, mmap_buffer_releasebuf},
0, /* tp_richcompare */ {0, NULL},
offsetof(mmap_object, weakreflist), /* tp_weaklistoffset */ };
0, /* tp_iter */
0, /* tp_iternext */ static PyType_Spec mmap_object_spec = {
mmap_object_methods, /* tp_methods */ .name = "mmap.mmap",
0, /* tp_members */ .basicsize = sizeof(mmap_object),
mmap_object_getset, /* tp_getset */ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
0, /* tp_base */ .slots = mmap_object_slots,
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
new_mmap_object, /* tp_new */
PyObject_Del, /* tp_free */
}; };
@ -1509,19 +1501,46 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
} }
#endif /* MS_WINDOWS */ #endif /* MS_WINDOWS */
static int
mmap_traverse(PyObject *module, visitproc visit, void *arg)
{
mmap_state *state = get_mmap_state(module);
Py_VISIT(state->mmap_object_type);
return 0;
}
static int
mmap_clear(PyObject *module)
{
mmap_state *state = get_mmap_state(module);
Py_CLEAR(state->mmap_object_type);
return 0;
}
static void
mmap_free(void *module)
{
mmap_clear((PyObject *)module);
}
static int static int
mmap_exec(PyObject *module) mmap_exec(PyObject *module)
{ {
if (PyType_Ready(&mmap_object_type) < 0) { mmap_state *state = get_mmap_state(module);
return -1;
}
Py_INCREF(PyExc_OSError); Py_INCREF(PyExc_OSError);
if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) { if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) {
Py_DECREF(PyExc_OSError); Py_DECREF(PyExc_OSError);
return -1; return -1;
} }
if (PyModule_AddType(module, &mmap_object_type) < 0) {
state->mmap_object_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
&mmap_object_spec,
NULL);
if (state->mmap_object_type == NULL) {
return -1;
}
if (PyModule_AddType(module, state->mmap_object_type) < 0) {
return -1; return -1;
} }
@ -1660,8 +1679,11 @@ static PyModuleDef_Slot mmap_slots[] = {
static struct PyModuleDef mmapmodule = { static struct PyModuleDef mmapmodule = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
.m_name = "mmap", .m_name = "mmap",
.m_size = 0, .m_size = sizeof(mmap_state),
.m_slots = mmap_slots, .m_slots = mmap_slots,
.m_traverse = mmap_traverse,
.m_clear = mmap_clear,
.m_free = mmap_free,
}; };
PyMODINIT_FUNC PyMODINIT_FUNC