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

Appearance settings

bpo-1635741: - port overlapped to multi-phase #22051

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 7, 2020
Merged
Changes from 1 commit
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
Next Next commit
port overlapped to multi-phase
  • Loading branch information
koubaa committed Sep 1, 2020
commit 3914dfe7d8e7a6525f4936650bafa73040a05ac3
171 changes: 106 additions & 65 deletions 171 Modules/overlapped.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@ typedef struct {
};
} OverlappedObject;

typedef struct {
PyTypeObject *overlapped_type;
} OverlappedState;

static inline OverlappedState*
overlapped_get_state(PyObject *module)
{
void *state = PyModule_GetState(module);
assert(state != NULL);
return (OverlappedState *)state;
}


/*
* Map Windows error codes to subclasses of OSError
*/
Expand Down Expand Up @@ -706,8 +719,11 @@ Overlapped_dealloc(OverlappedObject *self)
}

Overlapped_clear(self);
PyObject_Del(self);
SetLastError(olderr);

PyTypeObject *tp = Py_TYPE(self);
PyObject_Del(self);
Py_DECREF(tp);
}


Expand Down Expand Up @@ -1846,45 +1862,22 @@ static PyGetSetDef Overlapped_getsets[] = {
{NULL},
};

PyTypeObject OverlappedType = {
PyVarObject_HEAD_INIT(NULL, 0)
/* tp_name */ "_overlapped.Overlapped",
/* tp_basicsize */ sizeof(OverlappedObject),
/* tp_itemsize */ 0,
/* tp_dealloc */ (destructor) Overlapped_dealloc,
/* tp_vectorcall_offset */ 0,
/* tp_getattr */ 0,
/* tp_setattr */ 0,
/* tp_as_async */ 0,
/* tp_repr */ 0,
/* tp_as_number */ 0,
/* tp_as_sequence */ 0,
/* tp_as_mapping */ 0,
/* tp_hash */ 0,
/* tp_call */ 0,
/* tp_str */ 0,
/* tp_getattro */ 0,
/* tp_setattro */ 0,
/* tp_as_buffer */ 0,
/* tp_flags */ Py_TPFLAGS_DEFAULT,
/* tp_doc */ _overlapped_Overlapped__doc__,
/* tp_traverse */ (traverseproc)Overlapped_traverse,
/* tp_clear */ 0,
/* tp_richcompare */ 0,
/* tp_weaklistoffset */ 0,
/* tp_iter */ 0,
/* tp_iternext */ 0,
/* tp_methods */ Overlapped_methods,
/* tp_members */ Overlapped_members,
/* tp_getset */ Overlapped_getsets,
/* tp_base */ 0,
/* tp_dict */ 0,
/* tp_descr_get */ 0,
/* tp_descr_set */ 0,
/* tp_dictoffset */ 0,
/* tp_init */ 0,
/* tp_alloc */ 0,
/* tp_new */ _overlapped_Overlapped,
static PyType_Slot overlapped_type_slots[] = {
{Py_tp_dealloc, Overlapped_dealloc},
{Py_tp_doc, (char *)_overlapped_Overlapped__doc__},
{Py_tp_traverse, Overlapped_traverse},
{Py_tp_methods, Overlapped_methods},
{Py_tp_members, Overlapped_members},
{Py_tp_getset, Overlapped_getsets},
{Py_tp_new, _overlapped_Overlapped},
{0,0}
};

static PyType_Spec overlapped_type_spec = {
.name = "_overlapped.Overlapped",
.basicsize = sizeof(OverlappedObject),
.flags = Py_TPFLAGS_DEFAULT,
.slots = overlapped_type_slots
};

static PyMethodDef overlapped_functions[] = {
Expand All @@ -1904,41 +1897,67 @@ static PyMethodDef overlapped_functions[] = {
{NULL}
};

static struct PyModuleDef overlapped_module = {
PyModuleDef_HEAD_INIT,
"_overlapped",
NULL,
-1,
overlapped_functions,
NULL,
NULL,
NULL,
NULL
};
static int
overlapped_traverse(PyObject *module, visitproc visit, void *arg)
{
OverlappedState *state = overlapped_get_state(module);
Py_VISIT(state->overlapped_type);
return 0;
}

#define WINAPI_CONSTANT(fmt, con) \
PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con))
static int
overlapped_clear(PyObject *module)
{
OverlappedState *state = overlapped_get_state(module);
Py_CLEAR(state->overlapped_type);
return 0;
}

PyMODINIT_FUNC
PyInit__overlapped(void)
static void
overlapped_free(void *module)
{
PyObject *m, *d;
overlapped_clear((PyObject *)module);
}

#define WINAPI_CONSTANT(fmt, con) \
Copy link
Member

Choose a reason for hiding this comment

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

I think that this can be converted into PyModule_AddObject instead of using PyModule_GetDict

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@corona10 You're right. Is that preferable to PyModule_GetDict? If so why?

Copy link
Member

Choose a reason for hiding this comment

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

https://docs.python.org/3/c-api/module.html?highlight=pymodule_getdict#c.PyModule_GetDict

It is recommended extensions use other PyModule_*() and PyObject_*() functions rather than directly manipulate a module’s __dict__.

Copy link
Contributor Author

@koubaa koubaa Sep 4, 2020

Choose a reason for hiding this comment

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

@corona10 I'm trying that now. So far it is not looking good - somehow the values are all wrong. For example when I switch to PyModule_AddObject, overlapped.__dict__["ERROR_IO_PENDING"] is 6160 instead of 997. I can't figure out why..

Edit - I figured it out. I was doing a decref on the object I passed into PyModule_AddObject, but it turns out this function steals the reference so I shouldn't do that.

do { \
PyObject *value = Py_BuildValue(fmt, con); \
if (value == NULL) { \
return -1; \
} \
if (PyDict_SetItemString(d, #con, value) < 0) { \
Py_DECREF(value); \
return -1; \
} \
Py_DECREF(value); \
} while (0)

static int
overlapped_exec(PyObject *module)
{
/* Ensure WSAStartup() called before initializing function pointers */
m = PyImport_ImportModule("_socket");
if (!m)
return NULL;
PyObject *m = PyImport_ImportModule("_socket");
if (!m) {
return -1;
}

Py_DECREF(m);

if (initialize_function_pointers() < 0)
Copy link
Member

Choose a reason for hiding this comment

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

While you modify the if, please add braces for consistency with the function (PEP 7).

return NULL;
return -1;

m = PyModule_Create(&overlapped_module);
if (PyModule_AddType(m, &OverlappedType) < 0) {
return NULL;
OverlappedState *st = overlapped_get_state(module);
st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(
m, &overlapped_type_spec, NULL);
if (st->overlapped_type == NULL) {
return -1;
}

d = PyModule_GetDict(m);
if (PyModule_AddType(module, st->overlapped_type) < 0) {
return -1;
}

PyObject *d = PyModule_GetDict(module);

WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING);
WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
Expand All @@ -1952,5 +1971,27 @@ PyInit__overlapped(void)
WINAPI_CONSTANT(F_DWORD, SO_UPDATE_CONNECT_CONTEXT);
WINAPI_CONSTANT(F_DWORD, TF_REUSE_SOCKET);

return m;
return 0;
}

static PyModuleDef_Slot overlapped_slots[] = {
{Py_mod_exec, overlapped_exec},
{0, NULL}
};

static struct PyModuleDef overlapped_module = {
PyModuleDef_HEAD_INIT,
.m_name = "_overlapped",
.m_size = sizeof(OverlappedState),
.m_methods = overlapped_functions,
.m_slots = overlapped_slots,
.m_traverse = overlapped_traverse,
.m_clear = overlapped_clear,
.m_free = overlapped_free
};

PyMODINIT_FUNC
PyInit__overlapped(void)
{
return PyModuleDef_Init(&overlapped_module);
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.