LCOV - code coverage report
Current view: | top level - Modules/_multiprocessing - multiprocessing.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 18 | 43 | 41.9 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 2 | 4 | 50.0 %
|  |  | Branches: | 10 | 26 | 38.5 %

               Branch data     Line data    Source code
           1                 :            : /*
           2                 :            :  * Extension module used by multiprocessing package
           3                 :            :  *
           4                 :            :  * multiprocessing.c
           5                 :            :  *
           6                 :            :  * Copyright (c) 2006-2008, R Oudkerk
           7                 :            :  * Licensed to PSF under a Contributor Agreement.
           8                 :            :  */
           9                 :            :
          10                 :            : #include "multiprocessing.h"
          11                 :            :
          12                 :            : /*[python input]
          13                 :            : class HANDLE_converter(CConverter):
          14                 :            :     type = "HANDLE"
          15                 :            :     format_unit = '"F_HANDLE"'
          16                 :            :
          17                 :            :     def parse_arg(self, argname, displayname):
          18                 :            :         return """
          19                 :            :             {paramname} = PyLong_AsVoidPtr({argname});
          20                 :            :             if (!{paramname} && PyErr_Occurred()) {{{{
          21                 :            :                 goto exit;
          22                 :            :             }}}}
          23                 :            :             """.format(argname=argname, paramname=self.parser_name)
          24                 :            :
          25                 :            : [python start generated code]*/
          26                 :            : /*[python end generated code: output=da39a3ee5e6b4b0d input=3e537d244034affb]*/
          27                 :            :
          28                 :            : /*[clinic input]
          29                 :            : module _multiprocessing
          30                 :            : [clinic start generated code]*/
          31                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=01e0745f380ac6e3]*/
          32                 :            :
          33                 :            : #include "clinic/multiprocessing.c.h"
          34                 :            :
          35                 :            : /*
          36                 :            :  * Function which raises exceptions based on error codes
          37                 :            :  */
          38                 :            :
          39                 :            : PyObject *
          40                 :          0 : _PyMp_SetError(PyObject *Type, int num)
          41                 :            : {
          42   [ #  #  #  # ]:          0 :     switch (num) {
          43                 :            : #ifdef MS_WINDOWS
          44                 :            :     case MP_STANDARD_ERROR:
          45                 :            :         if (Type == NULL)
          46                 :            :             Type = PyExc_OSError;
          47                 :            :         PyErr_SetExcFromWindowsErr(Type, 0);
          48                 :            :         break;
          49                 :            :     case MP_SOCKET_ERROR:
          50                 :            :         if (Type == NULL)
          51                 :            :             Type = PyExc_OSError;
          52                 :            :         PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
          53                 :            :         break;
          54                 :            : #else /* !MS_WINDOWS */
          55                 :          0 :     case MP_STANDARD_ERROR:
          56                 :            :     case MP_SOCKET_ERROR:
          57         [ #  # ]:          0 :         if (Type == NULL)
          58                 :          0 :             Type = PyExc_OSError;
          59                 :          0 :         PyErr_SetFromErrno(Type);
          60                 :          0 :         break;
          61                 :            : #endif /* !MS_WINDOWS */
          62                 :          0 :     case MP_MEMORY_ERROR:
          63                 :          0 :         PyErr_NoMemory();
          64                 :          0 :         break;
          65                 :          0 :     case MP_EXCEPTION_HAS_BEEN_SET:
          66                 :          0 :         break;
          67                 :          0 :     default:
          68                 :          0 :         PyErr_Format(PyExc_RuntimeError,
          69                 :            :                      "unknown error number %d", num);
          70                 :            :     }
          71                 :          0 :     return NULL;
          72                 :            : }
          73                 :            :
          74                 :            : #ifdef MS_WINDOWS
          75                 :            : /*[clinic input]
          76                 :            : _multiprocessing.closesocket
          77                 :            :
          78                 :            :     handle: HANDLE
          79                 :            :     /
          80                 :            :
          81                 :            : [clinic start generated code]*/
          82                 :            :
          83                 :            : static PyObject *
          84                 :            : _multiprocessing_closesocket_impl(PyObject *module, HANDLE handle)
          85                 :            : /*[clinic end generated code: output=214f359f900966f4 input=8a20706dd386c6cc]*/
          86                 :            : {
          87                 :            :     int ret;
          88                 :            :
          89                 :            :     Py_BEGIN_ALLOW_THREADS
          90                 :            :     ret = closesocket((SOCKET) handle);
          91                 :            :     Py_END_ALLOW_THREADS
          92                 :            :
          93                 :            :     if (ret)
          94                 :            :         return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
          95                 :            :     Py_RETURN_NONE;
          96                 :            : }
          97                 :            :
          98                 :            : /*[clinic input]
          99                 :            : _multiprocessing.recv
         100                 :            :
         101                 :            :     handle: HANDLE
         102                 :            :     size: int
         103                 :            :     /
         104                 :            :
         105                 :            : [clinic start generated code]*/
         106                 :            :
         107                 :            : static PyObject *
         108                 :            : _multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size)
         109                 :            : /*[clinic end generated code: output=92322781ba9ff598 input=6a5b0834372cee5b]*/
         110                 :            : {
         111                 :            :     int nread;
         112                 :            :     PyObject *buf;
         113                 :            :
         114                 :            :     buf = PyBytes_FromStringAndSize(NULL, size);
         115                 :            :     if (!buf)
         116                 :            :         return NULL;
         117                 :            :
         118                 :            :     Py_BEGIN_ALLOW_THREADS
         119                 :            :     nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0);
         120                 :            :     Py_END_ALLOW_THREADS
         121                 :            :
         122                 :            :     if (nread < 0) {
         123                 :            :         Py_DECREF(buf);
         124                 :            :         return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
         125                 :            :     }
         126                 :            :     _PyBytes_Resize(&buf, nread);
         127                 :            :     return buf;
         128                 :            : }
         129                 :            :
         130                 :            : /*[clinic input]
         131                 :            : _multiprocessing.send
         132                 :            :
         133                 :            :     handle: HANDLE
         134                 :            :     buf: Py_buffer
         135                 :            :     /
         136                 :            :
         137                 :            : [clinic start generated code]*/
         138                 :            :
         139                 :            : static PyObject *
         140                 :            : _multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf)
         141                 :            : /*[clinic end generated code: output=52d7df0519c596cb input=41dce742f98d2210]*/
         142                 :            : {
         143                 :            :     int ret, length;
         144                 :            :
         145                 :            :     length = (int)Py_MIN(buf->len, INT_MAX);
         146                 :            :
         147                 :            :     Py_BEGIN_ALLOW_THREADS
         148                 :            :     ret = send((SOCKET) handle, buf->buf, length, 0);
         149                 :            :     Py_END_ALLOW_THREADS
         150                 :            :
         151                 :            :     if (ret < 0)
         152                 :            :         return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
         153                 :            :     return PyLong_FromLong(ret);
         154                 :            : }
         155                 :            :
         156                 :            : #endif
         157                 :            :
         158                 :            : /*[clinic input]
         159                 :            : _multiprocessing.sem_unlink
         160                 :            :
         161                 :            :     name: str
         162                 :            :     /
         163                 :            :
         164                 :            : [clinic start generated code]*/
         165                 :            :
         166                 :            : static PyObject *
         167                 :          0 : _multiprocessing_sem_unlink_impl(PyObject *module, const char *name)
         168                 :            : /*[clinic end generated code: output=fcbfeb1ed255e647 input=bf939aff9564f1d5]*/
         169                 :            : {
         170                 :          0 :     return _PyMp_sem_unlink(name);
         171                 :            : }
         172                 :            :
         173                 :            : /*
         174                 :            :  * Function table
         175                 :            :  */
         176                 :            :
         177                 :            : static PyMethodDef module_methods[] = {
         178                 :            : #ifdef MS_WINDOWS
         179                 :            :     _MULTIPROCESSING_CLOSESOCKET_METHODDEF
         180                 :            :     _MULTIPROCESSING_RECV_METHODDEF
         181                 :            :     _MULTIPROCESSING_SEND_METHODDEF
         182                 :            : #endif
         183                 :            : #if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)
         184                 :            :     _MULTIPROCESSING_SEM_UNLINK_METHODDEF
         185                 :            : #endif
         186                 :            :     {NULL}
         187                 :            : };
         188                 :            :
         189                 :            :
         190                 :            : /*
         191                 :            :  * Initialize
         192                 :            :  */
         193                 :            :
         194                 :            : static int
         195                 :          1 : multiprocessing_exec(PyObject *module)
         196                 :            : {
         197                 :            : #ifdef HAVE_MP_SEMAPHORE
         198                 :            :
         199                 :          1 :     PyTypeObject *semlock_type = (PyTypeObject *)PyType_FromModuleAndSpec(
         200                 :            :                 module, &_PyMp_SemLockType_spec, NULL);
         201                 :            :
         202         [ -  + ]:          1 :     if (semlock_type == NULL) {
         203                 :          0 :         return -1;
         204                 :            :     }
         205                 :          1 :     int rc = PyModule_AddType(module, semlock_type);
         206                 :          1 :     Py_DECREF(semlock_type);
         207         [ -  + ]:          1 :     if (rc < 0) {
         208                 :          0 :         return -1;
         209                 :            :     }
         210                 :            :
         211                 :            :     PyObject *py_sem_value_max;
         212                 :            :     /* Some systems define SEM_VALUE_MAX as an unsigned value that
         213                 :            :      * causes it to be negative when used as an int (NetBSD).
         214                 :            :      *
         215                 :            :      * Issue #28152: Use (0) instead of 0 to fix a warning on dead code
         216                 :            :      * when using clang -Wunreachable-code. */
         217                 :            :     if ((int)(SEM_VALUE_MAX) < (0)) {
         218                 :            :         py_sem_value_max = PyLong_FromLong(INT_MAX);
         219                 :            :     }
         220                 :            :     else {
         221                 :          1 :         py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX);
         222                 :            :     }
         223         [ -  + ]:          1 :     if (py_sem_value_max == NULL) {
         224                 :          0 :         return -1;
         225                 :            :     }
         226         [ -  + ]:          1 :     if (PyDict_SetItemString(semlock_type->tp_dict, "SEM_VALUE_MAX",
         227                 :            :                          py_sem_value_max) < 0) {
         228                 :          0 :         Py_DECREF(py_sem_value_max);
         229                 :          0 :         return -1;
         230                 :            :     }
         231                 :          1 :     Py_DECREF(py_sem_value_max);
         232                 :            :
         233                 :            : #endif
         234                 :            :
         235                 :            :     /* Add configuration macros */
         236                 :          1 :     PyObject *flags = PyDict_New();
         237         [ -  + ]:          1 :     if (!flags) {
         238                 :          0 :         return -1;
         239                 :            :     }
         240                 :            :
         241                 :            : #define ADD_FLAG(name)                                          \
         242                 :            :     do {                                                        \
         243                 :            :         PyObject *value = PyLong_FromLong(name);                \
         244                 :            :         if (value == NULL) {                                    \
         245                 :            :             Py_DECREF(flags);                                   \
         246                 :            :             return -1;                                          \
         247                 :            :         }                                                       \
         248                 :            :         if (PyDict_SetItemString(flags, #name, value) < 0) {    \
         249                 :            :             Py_DECREF(flags);                                   \
         250                 :            :             Py_DECREF(value);                                   \
         251                 :            :             return -1;                                          \
         252                 :            :         }                                                       \
         253                 :            :         Py_DECREF(value);                                       \
         254                 :            :     } while (0)
         255                 :            :
         256                 :            : #if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
         257   [ -  +  -  + ]:          1 :     ADD_FLAG(HAVE_SEM_OPEN);
         258                 :            : #endif
         259                 :            : #ifdef HAVE_SEM_TIMEDWAIT
         260   [ -  +  -  + ]:          1 :     ADD_FLAG(HAVE_SEM_TIMEDWAIT);
         261                 :            : #endif
         262                 :            : #ifdef HAVE_BROKEN_SEM_GETVALUE
         263                 :            :     ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
         264                 :            : #endif
         265                 :            : #ifdef HAVE_BROKEN_SEM_UNLINK
         266                 :            :     ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
         267                 :            : #endif
         268                 :            :
         269         [ -  + ]:          1 :     if (PyModule_AddObject(module, "flags", flags) < 0) {
         270                 :          0 :         Py_DECREF(flags);
         271                 :          0 :         return -1;
         272                 :            :     }
         273                 :            :
         274                 :          1 :     return 0;
         275                 :            : }
         276                 :            :
         277                 :            : static PyModuleDef_Slot multiprocessing_slots[] = {
         278                 :            :     {Py_mod_exec, multiprocessing_exec},
         279                 :            :     {0, NULL}
         280                 :            : };
         281                 :            :
         282                 :            : static struct PyModuleDef multiprocessing_module = {
         283                 :            :     PyModuleDef_HEAD_INIT,
         284                 :            :     .m_name = "_multiprocessing",
         285                 :            :     .m_size = 0,
         286                 :            :     .m_methods = module_methods,
         287                 :            :     .m_slots = multiprocessing_slots,
         288                 :            : };
         289                 :            :
         290                 :            : PyMODINIT_FUNC
         291                 :          1 : PyInit__multiprocessing(void)
         292                 :            : {
         293                 :          1 :     return PyModuleDef_Init(&multiprocessing_module);
         294                 :            : }

Generated by: LCOV version 1.14