ยปCore Development>Code coverage>Modules/_multiprocessing/multiprocessing.c

Python code coverage for Modules/_multiprocessing/multiprocessing.c

#countcontent
1n/a/*
2n/a * Extension module used by multiprocessing package
3n/a *
4n/a * multiprocessing.c
5n/a *
6n/a * Copyright (c) 2006-2008, R Oudkerk
7n/a * Licensed to PSF under a Contributor Agreement.
8n/a */
9n/a
10n/a#include "multiprocessing.h"
11n/a
12n/a
13n/a/*
14n/a * Function which raises exceptions based on error codes
15n/a */
16n/a
17n/aPyObject *
18n/a_PyMp_SetError(PyObject *Type, int num)
19n/a{
20n/a switch (num) {
21n/a#ifdef MS_WINDOWS
22n/a case MP_STANDARD_ERROR:
23n/a if (Type == NULL)
24n/a Type = PyExc_OSError;
25n/a PyErr_SetExcFromWindowsErr(Type, 0);
26n/a break;
27n/a case MP_SOCKET_ERROR:
28n/a if (Type == NULL)
29n/a Type = PyExc_OSError;
30n/a PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
31n/a break;
32n/a#else /* !MS_WINDOWS */
33n/a case MP_STANDARD_ERROR:
34n/a case MP_SOCKET_ERROR:
35n/a if (Type == NULL)
36n/a Type = PyExc_OSError;
37n/a PyErr_SetFromErrno(Type);
38n/a break;
39n/a#endif /* !MS_WINDOWS */
40n/a case MP_MEMORY_ERROR:
41n/a PyErr_NoMemory();
42n/a break;
43n/a case MP_EXCEPTION_HAS_BEEN_SET:
44n/a break;
45n/a default:
46n/a PyErr_Format(PyExc_RuntimeError,
47n/a "unknown error number %d", num);
48n/a }
49n/a return NULL;
50n/a}
51n/a
52n/a#ifdef MS_WINDOWS
53n/astatic PyObject *
54n/amultiprocessing_closesocket(PyObject *self, PyObject *args)
55n/a{
56n/a HANDLE handle;
57n/a int ret;
58n/a
59n/a if (!PyArg_ParseTuple(args, F_HANDLE ":closesocket" , &handle))
60n/a return NULL;
61n/a
62n/a Py_BEGIN_ALLOW_THREADS
63n/a ret = closesocket((SOCKET) handle);
64n/a Py_END_ALLOW_THREADS
65n/a
66n/a if (ret)
67n/a return PyErr_SetExcFromWindowsErr(PyExc_IOError, WSAGetLastError());
68n/a Py_RETURN_NONE;
69n/a}
70n/a
71n/astatic PyObject *
72n/amultiprocessing_recv(PyObject *self, PyObject *args)
73n/a{
74n/a HANDLE handle;
75n/a int size, nread;
76n/a PyObject *buf;
77n/a
78n/a if (!PyArg_ParseTuple(args, F_HANDLE "i:recv" , &handle, &size))
79n/a return NULL;
80n/a
81n/a buf = PyBytes_FromStringAndSize(NULL, size);
82n/a if (!buf)
83n/a return NULL;
84n/a
85n/a Py_BEGIN_ALLOW_THREADS
86n/a nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0);
87n/a Py_END_ALLOW_THREADS
88n/a
89n/a if (nread < 0) {
90n/a Py_DECREF(buf);
91n/a return PyErr_SetExcFromWindowsErr(PyExc_IOError, WSAGetLastError());
92n/a }
93n/a _PyBytes_Resize(&buf, nread);
94n/a return buf;
95n/a}
96n/a
97n/astatic PyObject *
98n/amultiprocessing_send(PyObject *self, PyObject *args)
99n/a{
100n/a HANDLE handle;
101n/a Py_buffer buf;
102n/a int ret, length;
103n/a
104n/a if (!PyArg_ParseTuple(args, F_HANDLE "y*:send" , &handle, &buf))
105n/a return NULL;
106n/a
107n/a length = (int)Py_MIN(buf.len, INT_MAX);
108n/a
109n/a Py_BEGIN_ALLOW_THREADS
110n/a ret = send((SOCKET) handle, buf.buf, length, 0);
111n/a Py_END_ALLOW_THREADS
112n/a
113n/a PyBuffer_Release(&buf);
114n/a if (ret < 0)
115n/a return PyErr_SetExcFromWindowsErr(PyExc_IOError, WSAGetLastError());
116n/a return PyLong_FromLong(ret);
117n/a}
118n/a
119n/a#endif
120n/a
121n/a/*
122n/a * Function table
123n/a */
124n/a
125n/astatic PyMethodDef module_methods[] = {
126n/a#ifdef MS_WINDOWS
127n/a {"closesocket", multiprocessing_closesocket, METH_VARARGS, ""},
128n/a {"recv", multiprocessing_recv, METH_VARARGS, ""},
129n/a {"send", multiprocessing_send, METH_VARARGS, ""},
130n/a#endif
131n/a#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)
132n/a {"sem_unlink", _PyMp_sem_unlink, METH_VARARGS, ""},
133n/a#endif
134n/a {NULL}
135n/a};
136n/a
137n/a
138n/a/*
139n/a * Initialize
140n/a */
141n/a
142n/astatic struct PyModuleDef multiprocessing_module = {
143n/a PyModuleDef_HEAD_INIT,
144n/a "_multiprocessing",
145n/a NULL,
146n/a -1,
147n/a module_methods,
148n/a NULL,
149n/a NULL,
150n/a NULL,
151n/a NULL
152n/a};
153n/a
154n/a
155n/aPyMODINIT_FUNC
156n/aPyInit__multiprocessing(void)
157n/a{
158n/a PyObject *module, *temp, *value = NULL;
159n/a
160n/a /* Initialize module */
161n/a module = PyModule_Create(&multiprocessing_module);
162n/a if (!module)
163n/a return NULL;
164n/a
165n/a#if defined(MS_WINDOWS) || \
166n/a (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED))
167n/a /* Add _PyMp_SemLock type to module */
168n/a if (PyType_Ready(&_PyMp_SemLockType) < 0)
169n/a return NULL;
170n/a Py_INCREF(&_PyMp_SemLockType);
171n/a {
172n/a PyObject *py_sem_value_max;
173n/a /* Some systems define SEM_VALUE_MAX as an unsigned value that
174n/a * causes it to be negative when used as an int (NetBSD).
175n/a *
176n/a * Issue #28152: Use (0) instead of 0 to fix a warning on dead code
177n/a * when using clang -Wunreachable-code. */
178n/a if ((int)(SEM_VALUE_MAX) < (0))
179n/a py_sem_value_max = PyLong_FromLong(INT_MAX);
180n/a else
181n/a py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX);
182n/a if (py_sem_value_max == NULL)
183n/a return NULL;
184n/a PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX",
185n/a py_sem_value_max);
186n/a }
187n/a PyModule_AddObject(module, "SemLock", (PyObject*)&_PyMp_SemLockType);
188n/a#endif
189n/a
190n/a /* Add configuration macros */
191n/a temp = PyDict_New();
192n/a if (!temp)
193n/a return NULL;
194n/a
195n/a#define ADD_FLAG(name) \
196n/a value = Py_BuildValue("i", name); \
197n/a if (value == NULL) { Py_DECREF(temp); return NULL; } \
198n/a if (PyDict_SetItemString(temp, #name, value) < 0) { \
199n/a Py_DECREF(temp); Py_DECREF(value); return NULL; } \
200n/a Py_DECREF(value)
201n/a
202n/a#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
203n/a ADD_FLAG(HAVE_SEM_OPEN);
204n/a#endif
205n/a#ifdef HAVE_SEM_TIMEDWAIT
206n/a ADD_FLAG(HAVE_SEM_TIMEDWAIT);
207n/a#endif
208n/a#ifdef HAVE_BROKEN_SEM_GETVALUE
209n/a ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
210n/a#endif
211n/a#ifdef HAVE_BROKEN_SEM_UNLINK
212n/a ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
213n/a#endif
214n/a
215n/a if (PyModule_AddObject(module, "flags", temp) < 0)
216n/a return NULL;
217n/a
218n/a return module;
219n/a}