17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci * Extension module used by multiprocessing package 37db96d56Sopenharmony_ci * 47db96d56Sopenharmony_ci * multiprocessing.c 57db96d56Sopenharmony_ci * 67db96d56Sopenharmony_ci * Copyright (c) 2006-2008, R Oudkerk 77db96d56Sopenharmony_ci * Licensed to PSF under a Contributor Agreement. 87db96d56Sopenharmony_ci */ 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci#include "multiprocessing.h" 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci/*[python input] 137db96d56Sopenharmony_ciclass HANDLE_converter(CConverter): 147db96d56Sopenharmony_ci type = "HANDLE" 157db96d56Sopenharmony_ci format_unit = '"F_HANDLE"' 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci[python start generated code]*/ 187db96d56Sopenharmony_ci/*[python end generated code: output=da39a3ee5e6b4b0d input=9fad6080b79ace91]*/ 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ci/*[clinic input] 217db96d56Sopenharmony_cimodule _multiprocessing 227db96d56Sopenharmony_ci[clinic start generated code]*/ 237db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=01e0745f380ac6e3]*/ 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci#include "clinic/multiprocessing.c.h" 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci/* 287db96d56Sopenharmony_ci * Function which raises exceptions based on error codes 297db96d56Sopenharmony_ci */ 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ciPyObject * 327db96d56Sopenharmony_ci_PyMp_SetError(PyObject *Type, int num) 337db96d56Sopenharmony_ci{ 347db96d56Sopenharmony_ci switch (num) { 357db96d56Sopenharmony_ci#ifdef MS_WINDOWS 367db96d56Sopenharmony_ci case MP_STANDARD_ERROR: 377db96d56Sopenharmony_ci if (Type == NULL) 387db96d56Sopenharmony_ci Type = PyExc_OSError; 397db96d56Sopenharmony_ci PyErr_SetExcFromWindowsErr(Type, 0); 407db96d56Sopenharmony_ci break; 417db96d56Sopenharmony_ci case MP_SOCKET_ERROR: 427db96d56Sopenharmony_ci if (Type == NULL) 437db96d56Sopenharmony_ci Type = PyExc_OSError; 447db96d56Sopenharmony_ci PyErr_SetExcFromWindowsErr(Type, WSAGetLastError()); 457db96d56Sopenharmony_ci break; 467db96d56Sopenharmony_ci#else /* !MS_WINDOWS */ 477db96d56Sopenharmony_ci case MP_STANDARD_ERROR: 487db96d56Sopenharmony_ci case MP_SOCKET_ERROR: 497db96d56Sopenharmony_ci if (Type == NULL) 507db96d56Sopenharmony_ci Type = PyExc_OSError; 517db96d56Sopenharmony_ci PyErr_SetFromErrno(Type); 527db96d56Sopenharmony_ci break; 537db96d56Sopenharmony_ci#endif /* !MS_WINDOWS */ 547db96d56Sopenharmony_ci case MP_MEMORY_ERROR: 557db96d56Sopenharmony_ci PyErr_NoMemory(); 567db96d56Sopenharmony_ci break; 577db96d56Sopenharmony_ci case MP_EXCEPTION_HAS_BEEN_SET: 587db96d56Sopenharmony_ci break; 597db96d56Sopenharmony_ci default: 607db96d56Sopenharmony_ci PyErr_Format(PyExc_RuntimeError, 617db96d56Sopenharmony_ci "unknown error number %d", num); 627db96d56Sopenharmony_ci } 637db96d56Sopenharmony_ci return NULL; 647db96d56Sopenharmony_ci} 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci#ifdef MS_WINDOWS 677db96d56Sopenharmony_ci/*[clinic input] 687db96d56Sopenharmony_ci_multiprocessing.closesocket 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci handle: HANDLE 717db96d56Sopenharmony_ci / 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci[clinic start generated code]*/ 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_cistatic PyObject * 767db96d56Sopenharmony_ci_multiprocessing_closesocket_impl(PyObject *module, HANDLE handle) 777db96d56Sopenharmony_ci/*[clinic end generated code: output=214f359f900966f4 input=8a20706dd386c6cc]*/ 787db96d56Sopenharmony_ci{ 797db96d56Sopenharmony_ci int ret; 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 827db96d56Sopenharmony_ci ret = closesocket((SOCKET) handle); 837db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci if (ret) 867db96d56Sopenharmony_ci return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); 877db96d56Sopenharmony_ci Py_RETURN_NONE; 887db96d56Sopenharmony_ci} 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci/*[clinic input] 917db96d56Sopenharmony_ci_multiprocessing.recv 927db96d56Sopenharmony_ci 937db96d56Sopenharmony_ci handle: HANDLE 947db96d56Sopenharmony_ci size: int 957db96d56Sopenharmony_ci / 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci[clinic start generated code]*/ 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_cistatic PyObject * 1007db96d56Sopenharmony_ci_multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size) 1017db96d56Sopenharmony_ci/*[clinic end generated code: output=92322781ba9ff598 input=6a5b0834372cee5b]*/ 1027db96d56Sopenharmony_ci{ 1037db96d56Sopenharmony_ci int nread; 1047db96d56Sopenharmony_ci PyObject *buf; 1057db96d56Sopenharmony_ci 1067db96d56Sopenharmony_ci buf = PyBytes_FromStringAndSize(NULL, size); 1077db96d56Sopenharmony_ci if (!buf) 1087db96d56Sopenharmony_ci return NULL; 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 1117db96d56Sopenharmony_ci nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0); 1127db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci if (nread < 0) { 1157db96d56Sopenharmony_ci Py_DECREF(buf); 1167db96d56Sopenharmony_ci return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); 1177db96d56Sopenharmony_ci } 1187db96d56Sopenharmony_ci _PyBytes_Resize(&buf, nread); 1197db96d56Sopenharmony_ci return buf; 1207db96d56Sopenharmony_ci} 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ci/*[clinic input] 1237db96d56Sopenharmony_ci_multiprocessing.send 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ci handle: HANDLE 1267db96d56Sopenharmony_ci buf: Py_buffer 1277db96d56Sopenharmony_ci / 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci[clinic start generated code]*/ 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_cistatic PyObject * 1327db96d56Sopenharmony_ci_multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf) 1337db96d56Sopenharmony_ci/*[clinic end generated code: output=52d7df0519c596cb input=41dce742f98d2210]*/ 1347db96d56Sopenharmony_ci{ 1357db96d56Sopenharmony_ci int ret, length; 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci length = (int)Py_MIN(buf->len, INT_MAX); 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 1407db96d56Sopenharmony_ci ret = send((SOCKET) handle, buf->buf, length, 0); 1417db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ci if (ret < 0) 1447db96d56Sopenharmony_ci return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); 1457db96d56Sopenharmony_ci return PyLong_FromLong(ret); 1467db96d56Sopenharmony_ci} 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ci#endif 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_ci/*[clinic input] 1517db96d56Sopenharmony_ci_multiprocessing.sem_unlink 1527db96d56Sopenharmony_ci 1537db96d56Sopenharmony_ci name: str 1547db96d56Sopenharmony_ci / 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ci[clinic start generated code]*/ 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_cistatic PyObject * 1597db96d56Sopenharmony_ci_multiprocessing_sem_unlink_impl(PyObject *module, const char *name) 1607db96d56Sopenharmony_ci/*[clinic end generated code: output=fcbfeb1ed255e647 input=bf939aff9564f1d5]*/ 1617db96d56Sopenharmony_ci{ 1627db96d56Sopenharmony_ci return _PyMp_sem_unlink(name); 1637db96d56Sopenharmony_ci} 1647db96d56Sopenharmony_ci 1657db96d56Sopenharmony_ci/* 1667db96d56Sopenharmony_ci * Function table 1677db96d56Sopenharmony_ci */ 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_cistatic PyMethodDef module_methods[] = { 1707db96d56Sopenharmony_ci#ifdef MS_WINDOWS 1717db96d56Sopenharmony_ci _MULTIPROCESSING_CLOSESOCKET_METHODDEF 1727db96d56Sopenharmony_ci _MULTIPROCESSING_RECV_METHODDEF 1737db96d56Sopenharmony_ci _MULTIPROCESSING_SEND_METHODDEF 1747db96d56Sopenharmony_ci#endif 1757db96d56Sopenharmony_ci#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__) 1767db96d56Sopenharmony_ci _MULTIPROCESSING_SEM_UNLINK_METHODDEF 1777db96d56Sopenharmony_ci#endif 1787db96d56Sopenharmony_ci {NULL} 1797db96d56Sopenharmony_ci}; 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_ci/* 1837db96d56Sopenharmony_ci * Initialize 1847db96d56Sopenharmony_ci */ 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_cistatic int 1877db96d56Sopenharmony_cimultiprocessing_exec(PyObject *module) 1887db96d56Sopenharmony_ci{ 1897db96d56Sopenharmony_ci#ifdef HAVE_MP_SEMAPHORE 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_ci /* Add _PyMp_SemLock type to module */ 1927db96d56Sopenharmony_ci if (PyModule_AddType(module, &_PyMp_SemLockType) < 0) { 1937db96d56Sopenharmony_ci return -1; 1947db96d56Sopenharmony_ci } 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_ci { 1977db96d56Sopenharmony_ci PyObject *py_sem_value_max; 1987db96d56Sopenharmony_ci /* Some systems define SEM_VALUE_MAX as an unsigned value that 1997db96d56Sopenharmony_ci * causes it to be negative when used as an int (NetBSD). 2007db96d56Sopenharmony_ci * 2017db96d56Sopenharmony_ci * Issue #28152: Use (0) instead of 0 to fix a warning on dead code 2027db96d56Sopenharmony_ci * when using clang -Wunreachable-code. */ 2037db96d56Sopenharmony_ci if ((int)(SEM_VALUE_MAX) < (0)) 2047db96d56Sopenharmony_ci py_sem_value_max = PyLong_FromLong(INT_MAX); 2057db96d56Sopenharmony_ci else 2067db96d56Sopenharmony_ci py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); 2077db96d56Sopenharmony_ci 2087db96d56Sopenharmony_ci if (py_sem_value_max == NULL) { 2097db96d56Sopenharmony_ci return -1; 2107db96d56Sopenharmony_ci } 2117db96d56Sopenharmony_ci if (PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX", 2127db96d56Sopenharmony_ci py_sem_value_max) < 0) { 2137db96d56Sopenharmony_ci Py_DECREF(py_sem_value_max); 2147db96d56Sopenharmony_ci return -1; 2157db96d56Sopenharmony_ci } 2167db96d56Sopenharmony_ci Py_DECREF(py_sem_value_max); 2177db96d56Sopenharmony_ci } 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_ci#endif 2207db96d56Sopenharmony_ci 2217db96d56Sopenharmony_ci /* Add configuration macros */ 2227db96d56Sopenharmony_ci PyObject *flags = PyDict_New(); 2237db96d56Sopenharmony_ci if (!flags) { 2247db96d56Sopenharmony_ci return -1; 2257db96d56Sopenharmony_ci } 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ci#define ADD_FLAG(name) \ 2287db96d56Sopenharmony_ci do { \ 2297db96d56Sopenharmony_ci PyObject *value = PyLong_FromLong(name); \ 2307db96d56Sopenharmony_ci if (value == NULL) { \ 2317db96d56Sopenharmony_ci Py_DECREF(flags); \ 2327db96d56Sopenharmony_ci return -1; \ 2337db96d56Sopenharmony_ci } \ 2347db96d56Sopenharmony_ci if (PyDict_SetItemString(flags, #name, value) < 0) { \ 2357db96d56Sopenharmony_ci Py_DECREF(flags); \ 2367db96d56Sopenharmony_ci Py_DECREF(value); \ 2377db96d56Sopenharmony_ci return -1; \ 2387db96d56Sopenharmony_ci } \ 2397db96d56Sopenharmony_ci Py_DECREF(value); \ 2407db96d56Sopenharmony_ci } while (0) 2417db96d56Sopenharmony_ci 2427db96d56Sopenharmony_ci#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) 2437db96d56Sopenharmony_ci ADD_FLAG(HAVE_SEM_OPEN); 2447db96d56Sopenharmony_ci#endif 2457db96d56Sopenharmony_ci#ifdef HAVE_SEM_TIMEDWAIT 2467db96d56Sopenharmony_ci ADD_FLAG(HAVE_SEM_TIMEDWAIT); 2477db96d56Sopenharmony_ci#endif 2487db96d56Sopenharmony_ci#ifdef HAVE_BROKEN_SEM_GETVALUE 2497db96d56Sopenharmony_ci ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE); 2507db96d56Sopenharmony_ci#endif 2517db96d56Sopenharmony_ci#ifdef HAVE_BROKEN_SEM_UNLINK 2527db96d56Sopenharmony_ci ADD_FLAG(HAVE_BROKEN_SEM_UNLINK); 2537db96d56Sopenharmony_ci#endif 2547db96d56Sopenharmony_ci 2557db96d56Sopenharmony_ci if (PyModule_AddObject(module, "flags", flags) < 0) { 2567db96d56Sopenharmony_ci Py_DECREF(flags); 2577db96d56Sopenharmony_ci return -1; 2587db96d56Sopenharmony_ci } 2597db96d56Sopenharmony_ci 2607db96d56Sopenharmony_ci return 0; 2617db96d56Sopenharmony_ci} 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_cistatic PyModuleDef_Slot multiprocessing_slots[] = { 2647db96d56Sopenharmony_ci {Py_mod_exec, multiprocessing_exec}, 2657db96d56Sopenharmony_ci {0, NULL} 2667db96d56Sopenharmony_ci}; 2677db96d56Sopenharmony_ci 2687db96d56Sopenharmony_cistatic struct PyModuleDef multiprocessing_module = { 2697db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 2707db96d56Sopenharmony_ci .m_name = "_multiprocessing", 2717db96d56Sopenharmony_ci .m_methods = module_methods, 2727db96d56Sopenharmony_ci .m_slots = multiprocessing_slots, 2737db96d56Sopenharmony_ci}; 2747db96d56Sopenharmony_ci 2757db96d56Sopenharmony_ciPyMODINIT_FUNC 2767db96d56Sopenharmony_ciPyInit__multiprocessing(void) 2777db96d56Sopenharmony_ci{ 2787db96d56Sopenharmony_ci return PyModuleDef_Init(&multiprocessing_module); 2797db96d56Sopenharmony_ci} 280