blob: 77e6c854068c0f29b6429e3c881a0ea3e17e3841 [file] [log] [blame]
Benjamin Petersonfa268032008-06-13 19:28:21 +00001/*
2 * Extension module used by multiprocessing package
3 *
4 * multiprocessing.c
5 *
Richard Oudkerk3e268aa2012-04-30 12:13:55 +01006 * Copyright (c) 2006-2008, R Oudkerk
7 * Licensed to PSF under a Contributor Agreement.
Benjamin Petersonfa268032008-06-13 19:28:21 +00008 */
9
10#include "multiprocessing.h"
11
Zackery Spytz545b54d2020-07-12 10:11:11 -060012/*[python input]
13class HANDLE_converter(CConverter):
14 type = "HANDLE"
15 format_unit = '"F_HANDLE"'
16
17[python start generated code]*/
18/*[python end generated code: output=da39a3ee5e6b4b0d input=9fad6080b79ace91]*/
19
20/*[clinic input]
21module _multiprocessing
22[clinic start generated code]*/
23/*[clinic end generated code: output=da39a3ee5e6b4b0d input=01e0745f380ac6e3]*/
24
25#include "clinic/multiprocessing.c.h"
Benjamin Peterson965ce872009-04-05 21:24:58 +000026
Benjamin Petersonfa268032008-06-13 19:28:21 +000027/*
28 * Function which raises exceptions based on error codes
29 */
30
31PyObject *
Richard Oudkerk8fb9f4c2012-10-07 18:08:47 +010032_PyMp_SetError(PyObject *Type, int num)
Benjamin Petersonfa268032008-06-13 19:28:21 +000033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000034 switch (num) {
Benjamin Petersonfa268032008-06-13 19:28:21 +000035#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000036 case MP_STANDARD_ERROR:
37 if (Type == NULL)
Andrew Svetlov2606a6f2012-12-19 14:33:35 +020038 Type = PyExc_OSError;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000039 PyErr_SetExcFromWindowsErr(Type, 0);
40 break;
41 case MP_SOCKET_ERROR:
42 if (Type == NULL)
Andrew Svetlov2606a6f2012-12-19 14:33:35 +020043 Type = PyExc_OSError;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000044 PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
45 break;
Benjamin Petersonfa268032008-06-13 19:28:21 +000046#else /* !MS_WINDOWS */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 case MP_STANDARD_ERROR:
48 case MP_SOCKET_ERROR:
49 if (Type == NULL)
50 Type = PyExc_OSError;
51 PyErr_SetFromErrno(Type);
52 break;
Benjamin Petersonfa268032008-06-13 19:28:21 +000053#endif /* !MS_WINDOWS */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000054 case MP_MEMORY_ERROR:
55 PyErr_NoMemory();
56 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000057 case MP_EXCEPTION_HAS_BEEN_SET:
58 break;
59 default:
60 PyErr_Format(PyExc_RuntimeError,
doko@ubuntu.com9df891c2013-05-15 18:06:56 +020061 "unknown error number %d", num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 }
63 return NULL;
Benjamin Petersonfa268032008-06-13 19:28:21 +000064}
65
Antoine Pitrou23bba4c2012-04-18 20:51:15 +020066#ifdef MS_WINDOWS
Zackery Spytz545b54d2020-07-12 10:11:11 -060067/*[clinic input]
68_multiprocessing.closesocket
Antoine Pitrou23bba4c2012-04-18 20:51:15 +020069
Zackery Spytz545b54d2020-07-12 10:11:11 -060070 handle: HANDLE
71 /
72
73[clinic start generated code]*/
74
75static PyObject *
76_multiprocessing_closesocket_impl(PyObject *module, HANDLE handle)
77/*[clinic end generated code: output=214f359f900966f4 input=8a20706dd386c6cc]*/
78{
79 int ret;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +020080
81 Py_BEGIN_ALLOW_THREADS
82 ret = closesocket((SOCKET) handle);
83 Py_END_ALLOW_THREADS
84
85 if (ret)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +030086 return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrou23bba4c2012-04-18 20:51:15 +020087 Py_RETURN_NONE;
88}
89
Zackery Spytz545b54d2020-07-12 10:11:11 -060090/*[clinic input]
91_multiprocessing.recv
Antoine Pitrou23bba4c2012-04-18 20:51:15 +020092
Zackery Spytz545b54d2020-07-12 10:11:11 -060093 handle: HANDLE
94 size: int
95 /
96
97[clinic start generated code]*/
98
99static PyObject *
100_multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size)
101/*[clinic end generated code: output=92322781ba9ff598 input=6a5b0834372cee5b]*/
102{
103 int nread;
104 PyObject *buf;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200105
106 buf = PyBytes_FromStringAndSize(NULL, size);
107 if (!buf)
108 return NULL;
109
110 Py_BEGIN_ALLOW_THREADS
111 nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0);
112 Py_END_ALLOW_THREADS
113
114 if (nread < 0) {
115 Py_DECREF(buf);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300116 return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200117 }
118 _PyBytes_Resize(&buf, nread);
119 return buf;
120}
121
Zackery Spytz545b54d2020-07-12 10:11:11 -0600122/*[clinic input]
123_multiprocessing.send
124
125 handle: HANDLE
126 buf: Py_buffer
127 /
128
129[clinic start generated code]*/
130
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200131static PyObject *
Zackery Spytz545b54d2020-07-12 10:11:11 -0600132_multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf)
133/*[clinic end generated code: output=52d7df0519c596cb input=41dce742f98d2210]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200134{
Richard Oudkerkb988ee02013-09-07 17:40:45 +0100135 int ret, length;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200136
Zackery Spytz545b54d2020-07-12 10:11:11 -0600137 length = (int)Py_MIN(buf->len, INT_MAX);
Richard Oudkerkb988ee02013-09-07 17:40:45 +0100138
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200139 Py_BEGIN_ALLOW_THREADS
Zackery Spytz545b54d2020-07-12 10:11:11 -0600140 ret = send((SOCKET) handle, buf->buf, length, 0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200141 Py_END_ALLOW_THREADS
142
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200143 if (ret < 0)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300144 return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200145 return PyLong_FromLong(ret);
146}
147
148#endif
Benjamin Petersonfa268032008-06-13 19:28:21 +0000149
Zackery Spytz545b54d2020-07-12 10:11:11 -0600150/*[clinic input]
151_multiprocessing.sem_unlink
152
153 name: str
154 /
155
156[clinic start generated code]*/
157
158static PyObject *
159_multiprocessing_sem_unlink_impl(PyObject *module, const char *name)
160/*[clinic end generated code: output=fcbfeb1ed255e647 input=bf939aff9564f1d5]*/
161{
162 return _PyMp_sem_unlink(name);
163}
164
Benjamin Petersonfa268032008-06-13 19:28:21 +0000165/*
166 * Function table
167 */
168
169static PyMethodDef module_methods[] = {
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200170#ifdef MS_WINDOWS
Zackery Spytz545b54d2020-07-12 10:11:11 -0600171 _MULTIPROCESSING_CLOSESOCKET_METHODDEF
172 _MULTIPROCESSING_RECV_METHODDEF
173 _MULTIPROCESSING_SEND_METHODDEF
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200174#endif
Berker Peksag1a269d02016-05-07 21:13:50 +0300175#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)
Zackery Spytz545b54d2020-07-12 10:11:11 -0600176 _MULTIPROCESSING_SEM_UNLINK_METHODDEF
Richard Oudkerke0e65812014-07-28 23:01:02 +0100177#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 {NULL}
Benjamin Petersonfa268032008-06-13 19:28:21 +0000179};
180
181
182/*
183 * Initialize
184 */
185
186static struct PyModuleDef multiprocessing_module = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 PyModuleDef_HEAD_INIT,
188 "_multiprocessing",
189 NULL,
190 -1,
191 module_methods,
192 NULL,
193 NULL,
194 NULL,
195 NULL
Benjamin Petersonfa268032008-06-13 19:28:21 +0000196};
197
198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199PyMODINIT_FUNC
Benjamin Petersonfa268032008-06-13 19:28:21 +0000200PyInit__multiprocessing(void)
201{
Amaury Forgeot d'Arc7e447c82011-12-17 10:23:14 +0100202 PyObject *module, *temp, *value = NULL;
Benjamin Petersonfa268032008-06-13 19:28:21 +0000203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 /* Initialize module */
205 module = PyModule_Create(&multiprocessing_module);
206 if (!module)
207 return NULL;
Benjamin Petersonfa268032008-06-13 19:28:21 +0000208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209#if defined(MS_WINDOWS) || \
Mark Dickinsona614f042009-11-28 12:48:43 +0000210 (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED))
Richard Oudkerk8fb9f4c2012-10-07 18:08:47 +0100211 /* Add _PyMp_SemLock type to module */
212 if (PyType_Ready(&_PyMp_SemLockType) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 return NULL;
Richard Oudkerk8fb9f4c2012-10-07 18:08:47 +0100214 Py_INCREF(&_PyMp_SemLockType);
Gregory P. Smith68e01352010-10-17 02:14:36 +0000215 {
216 PyObject *py_sem_value_max;
217 /* Some systems define SEM_VALUE_MAX as an unsigned value that
Victor Stinner408bfa62016-12-05 18:00:42 +0100218 * causes it to be negative when used as an int (NetBSD).
219 *
220 * Issue #28152: Use (0) instead of 0 to fix a warning on dead code
221 * when using clang -Wunreachable-code. */
222 if ((int)(SEM_VALUE_MAX) < (0))
Gregory P. Smith68e01352010-10-17 02:14:36 +0000223 py_sem_value_max = PyLong_FromLong(INT_MAX);
224 else
225 py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX);
226 if (py_sem_value_max == NULL)
227 return NULL;
Richard Oudkerk8fb9f4c2012-10-07 18:08:47 +0100228 PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX",
Gregory P. Smith68e01352010-10-17 02:14:36 +0000229 py_sem_value_max);
230 }
Richard Oudkerk8fb9f4c2012-10-07 18:08:47 +0100231 PyModule_AddObject(module, "SemLock", (PyObject*)&_PyMp_SemLockType);
Benjamin Petersonfa268032008-06-13 19:28:21 +0000232#endif
233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 /* Add configuration macros */
235 temp = PyDict_New();
236 if (!temp)
237 return NULL;
Benjamin Petersonfa268032008-06-13 19:28:21 +0000238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239#define ADD_FLAG(name) \
240 value = Py_BuildValue("i", name); \
241 if (value == NULL) { Py_DECREF(temp); return NULL; } \
242 if (PyDict_SetItemString(temp, #name, value) < 0) { \
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200243 Py_DECREF(temp); Py_DECREF(value); return NULL; } \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 Py_DECREF(value)
245
Mark Dickinsona614f042009-11-28 12:48:43 +0000246#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 ADD_FLAG(HAVE_SEM_OPEN);
Benjamin Petersonfa268032008-06-13 19:28:21 +0000248#endif
249#ifdef HAVE_SEM_TIMEDWAIT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 ADD_FLAG(HAVE_SEM_TIMEDWAIT);
Benjamin Petersonfa268032008-06-13 19:28:21 +0000251#endif
Benjamin Petersonfa268032008-06-13 19:28:21 +0000252#ifdef HAVE_BROKEN_SEM_GETVALUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
Benjamin Petersonfa268032008-06-13 19:28:21 +0000254#endif
255#ifdef HAVE_BROKEN_SEM_UNLINK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
Benjamin Petersonfa268032008-06-13 19:28:21 +0000257#endif
258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 if (PyModule_AddObject(module, "flags", temp) < 0)
260 return NULL;
Benjamin Petersonfa268032008-06-13 19:28:21 +0000261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 return module;
Benjamin Petersonfa268032008-06-13 19:28:21 +0000263}