123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- /*
- * Extension module used by multiprocessing package
- *
- * multiprocessing.c
- *
- * Copyright (c) 2006-2008, R Oudkerk
- * Licensed to PSF under a Contributor Agreement.
- */
- #include "multiprocessing.h"
- /*[python input]
- class HANDLE_converter(CConverter):
- type = "HANDLE"
- format_unit = '"F_HANDLE"'
- def parse_arg(self, argname, displayname):
- return """
- {paramname} = PyLong_AsVoidPtr({argname});
- if (!{paramname} && PyErr_Occurred()) {{{{
- goto exit;
- }}}}
- """.format(argname=argname, paramname=self.parser_name)
- [python start generated code]*/
- /*[python end generated code: output=da39a3ee5e6b4b0d input=3e537d244034affb]*/
- /*[clinic input]
- module _multiprocessing
- [clinic start generated code]*/
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=01e0745f380ac6e3]*/
- #include "clinic/multiprocessing.c.h"
- /*
- * Function which raises exceptions based on error codes
- */
- PyObject *
- _PyMp_SetError(PyObject *Type, int num)
- {
- switch (num) {
- #ifdef MS_WINDOWS
- case MP_STANDARD_ERROR:
- if (Type == NULL)
- Type = PyExc_OSError;
- PyErr_SetExcFromWindowsErr(Type, 0);
- break;
- case MP_SOCKET_ERROR:
- if (Type == NULL)
- Type = PyExc_OSError;
- PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
- break;
- #else /* !MS_WINDOWS */
- case MP_STANDARD_ERROR:
- case MP_SOCKET_ERROR:
- if (Type == NULL)
- Type = PyExc_OSError;
- PyErr_SetFromErrno(Type);
- break;
- #endif /* !MS_WINDOWS */
- case MP_MEMORY_ERROR:
- PyErr_NoMemory();
- break;
- case MP_EXCEPTION_HAS_BEEN_SET:
- break;
- default:
- PyErr_Format(PyExc_RuntimeError,
- "unknown error number %d", num);
- }
- return NULL;
- }
- #ifdef MS_WINDOWS
- /*[clinic input]
- _multiprocessing.closesocket
- handle: HANDLE
- /
- [clinic start generated code]*/
- static PyObject *
- _multiprocessing_closesocket_impl(PyObject *module, HANDLE handle)
- /*[clinic end generated code: output=214f359f900966f4 input=8a20706dd386c6cc]*/
- {
- int ret;
- Py_BEGIN_ALLOW_THREADS
- ret = closesocket((SOCKET) handle);
- Py_END_ALLOW_THREADS
- if (ret)
- return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
- Py_RETURN_NONE;
- }
- /*[clinic input]
- _multiprocessing.recv
- handle: HANDLE
- size: int
- /
- [clinic start generated code]*/
- static PyObject *
- _multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size)
- /*[clinic end generated code: output=92322781ba9ff598 input=6a5b0834372cee5b]*/
- {
- int nread;
- PyObject *buf;
- buf = PyBytes_FromStringAndSize(NULL, size);
- if (!buf)
- return NULL;
- Py_BEGIN_ALLOW_THREADS
- nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0);
- Py_END_ALLOW_THREADS
- if (nread < 0) {
- Py_DECREF(buf);
- return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
- }
- _PyBytes_Resize(&buf, nread);
- return buf;
- }
- /*[clinic input]
- _multiprocessing.send
- handle: HANDLE
- buf: Py_buffer
- /
- [clinic start generated code]*/
- static PyObject *
- _multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf)
- /*[clinic end generated code: output=52d7df0519c596cb input=41dce742f98d2210]*/
- {
- int ret, length;
- length = (int)Py_MIN(buf->len, INT_MAX);
- Py_BEGIN_ALLOW_THREADS
- ret = send((SOCKET) handle, buf->buf, length, 0);
- Py_END_ALLOW_THREADS
- if (ret < 0)
- return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
- return PyLong_FromLong(ret);
- }
- #endif
- /*[clinic input]
- _multiprocessing.sem_unlink
- name: str
- /
- [clinic start generated code]*/
- static PyObject *
- _multiprocessing_sem_unlink_impl(PyObject *module, const char *name)
- /*[clinic end generated code: output=fcbfeb1ed255e647 input=bf939aff9564f1d5]*/
- {
- return _PyMp_sem_unlink(name);
- }
- /*
- * Function table
- */
- static PyMethodDef module_methods[] = {
- #ifdef MS_WINDOWS
- _MULTIPROCESSING_CLOSESOCKET_METHODDEF
- _MULTIPROCESSING_RECV_METHODDEF
- _MULTIPROCESSING_SEND_METHODDEF
- #endif
- #if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)
- _MULTIPROCESSING_SEM_UNLINK_METHODDEF
- #endif
- {NULL}
- };
- /*
- * Initialize
- */
- static int
- multiprocessing_exec(PyObject *module)
- {
- #ifdef HAVE_MP_SEMAPHORE
- PyTypeObject *semlock_type = (PyTypeObject *)PyType_FromModuleAndSpec(
- module, &_PyMp_SemLockType_spec, NULL);
- if (semlock_type == NULL) {
- return -1;
- }
- int rc = PyModule_AddType(module, semlock_type);
- Py_DECREF(semlock_type);
- if (rc < 0) {
- return -1;
- }
- PyObject *py_sem_value_max;
- /* Some systems define SEM_VALUE_MAX as an unsigned value that
- * causes it to be negative when used as an int (NetBSD).
- *
- * Issue #28152: Use (0) instead of 0 to fix a warning on dead code
- * when using clang -Wunreachable-code. */
- if ((int)(SEM_VALUE_MAX) < (0)) {
- py_sem_value_max = PyLong_FromLong(INT_MAX);
- }
- else {
- py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX);
- }
- if (py_sem_value_max == NULL) {
- return -1;
- }
- if (PyDict_SetItemString(semlock_type->tp_dict, "SEM_VALUE_MAX",
- py_sem_value_max) < 0) {
- Py_DECREF(py_sem_value_max);
- return -1;
- }
- Py_DECREF(py_sem_value_max);
- #endif
- /* Add configuration macros */
- PyObject *flags = PyDict_New();
- if (!flags) {
- return -1;
- }
- #define ADD_FLAG(name) \
- do { \
- PyObject *value = PyLong_FromLong(name); \
- if (value == NULL) { \
- Py_DECREF(flags); \
- return -1; \
- } \
- if (PyDict_SetItemString(flags, #name, value) < 0) { \
- Py_DECREF(flags); \
- Py_DECREF(value); \
- return -1; \
- } \
- Py_DECREF(value); \
- } while (0)
- #if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
- ADD_FLAG(HAVE_SEM_OPEN);
- #endif
- #ifdef HAVE_SEM_TIMEDWAIT
- ADD_FLAG(HAVE_SEM_TIMEDWAIT);
- #endif
- #ifdef HAVE_BROKEN_SEM_GETVALUE
- ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
- #endif
- #ifdef HAVE_BROKEN_SEM_UNLINK
- ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
- #endif
- if (PyModule_AddObject(module, "flags", flags) < 0) {
- Py_DECREF(flags);
- return -1;
- }
- return 0;
- }
- static PyModuleDef_Slot multiprocessing_slots[] = {
- {Py_mod_exec, multiprocessing_exec},
- {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
- {0, NULL}
- };
- static struct PyModuleDef multiprocessing_module = {
- PyModuleDef_HEAD_INIT,
- .m_name = "_multiprocessing",
- .m_size = 0,
- .m_methods = module_methods,
- .m_slots = multiprocessing_slots,
- };
- PyMODINIT_FUNC
- PyInit__multiprocessing(void)
- {
- return PyModuleDef_Init(&multiprocessing_module);
- }
|