(root)/
Python-3.11.7/
Modules/
_multiprocessing/
multiprocessing.c
       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  [python start generated code]*/
      18  /*[python end generated code: output=da39a3ee5e6b4b0d input=9fad6080b79ace91]*/
      19  
      20  /*[clinic input]
      21  module _multiprocessing
      22  [clinic start generated code]*/
      23  /*[clinic end generated code: output=da39a3ee5e6b4b0d input=01e0745f380ac6e3]*/
      24  
      25  #include "clinic/multiprocessing.c.h"
      26  
      27  /*
      28   * Function which raises exceptions based on error codes
      29   */
      30  
      31  PyObject *
      32  _PyMp_SetError(PyObject *Type, int num)
      33  {
      34      switch (num) {
      35  #ifdef MS_WINDOWS
      36      case MP_STANDARD_ERROR:
      37          if (Type == NULL)
      38              Type = PyExc_OSError;
      39          PyErr_SetExcFromWindowsErr(Type, 0);
      40          break;
      41      case MP_SOCKET_ERROR:
      42          if (Type == NULL)
      43              Type = PyExc_OSError;
      44          PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
      45          break;
      46  #else /* !MS_WINDOWS */
      47      case MP_STANDARD_ERROR:
      48      case MP_SOCKET_ERROR:
      49          if (Type == NULL)
      50              Type = PyExc_OSError;
      51          PyErr_SetFromErrno(Type);
      52          break;
      53  #endif /* !MS_WINDOWS */
      54      case MP_MEMORY_ERROR:
      55          PyErr_NoMemory();
      56          break;
      57      case MP_EXCEPTION_HAS_BEEN_SET:
      58          break;
      59      default:
      60          PyErr_Format(PyExc_RuntimeError,
      61                       "unknown error number %d", num);
      62      }
      63      return NULL;
      64  }
      65  
      66  #ifdef MS_WINDOWS
      67  /*[clinic input]
      68  _multiprocessing.closesocket
      69  
      70      handle: HANDLE
      71      /
      72  
      73  [clinic start generated code]*/
      74  
      75  static PyObject *
      76  _multiprocessing_closesocket_impl(PyObject *module, HANDLE handle)
      77  /*[clinic end generated code: output=214f359f900966f4 input=8a20706dd386c6cc]*/
      78  {
      79      int ret;
      80  
      81      Py_BEGIN_ALLOW_THREADS
      82      ret = closesocket((SOCKET) handle);
      83      Py_END_ALLOW_THREADS
      84  
      85      if (ret)
      86          return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
      87      Py_RETURN_NONE;
      88  }
      89  
      90  /*[clinic input]
      91  _multiprocessing.recv
      92  
      93      handle: HANDLE
      94      size: int
      95      /
      96  
      97  [clinic start generated code]*/
      98  
      99  static 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;
     105  
     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);
     116          return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
     117      }
     118      _PyBytes_Resize(&buf, nread);
     119      return buf;
     120  }
     121  
     122  /*[clinic input]
     123  _multiprocessing.send
     124  
     125      handle: HANDLE
     126      buf: Py_buffer
     127      /
     128  
     129  [clinic start generated code]*/
     130  
     131  static PyObject *
     132  _multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf)
     133  /*[clinic end generated code: output=52d7df0519c596cb input=41dce742f98d2210]*/
     134  {
     135      int ret, length;
     136  
     137      length = (int)Py_MIN(buf->len, INT_MAX);
     138  
     139      Py_BEGIN_ALLOW_THREADS
     140      ret = send((SOCKET) handle, buf->buf, length, 0);
     141      Py_END_ALLOW_THREADS
     142  
     143      if (ret < 0)
     144          return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
     145      return PyLong_FromLong(ret);
     146  }
     147  
     148  #endif
     149  
     150  /*[clinic input]
     151  _multiprocessing.sem_unlink
     152  
     153      name: str
     154      /
     155  
     156  [clinic start generated code]*/
     157  
     158  static 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  
     165  /*
     166   * Function table
     167   */
     168  
     169  static PyMethodDef module_methods[] = {
     170  #ifdef MS_WINDOWS
     171      _MULTIPROCESSING_CLOSESOCKET_METHODDEF
     172      _MULTIPROCESSING_RECV_METHODDEF
     173      _MULTIPROCESSING_SEND_METHODDEF
     174  #endif
     175  #if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)
     176      _MULTIPROCESSING_SEM_UNLINK_METHODDEF
     177  #endif
     178      {NULL}
     179  };
     180  
     181  
     182  /*
     183   * Initialize
     184   */
     185  
     186  static int
     187  multiprocessing_exec(PyObject *module)
     188  {
     189  #ifdef HAVE_MP_SEMAPHORE
     190  
     191      /* Add _PyMp_SemLock type to module */
     192      if (PyModule_AddType(module, &_PyMp_SemLockType) < 0) {
     193          return -1;
     194      }
     195  
     196      {
     197          PyObject *py_sem_value_max;
     198          /* Some systems define SEM_VALUE_MAX as an unsigned value that
     199           * causes it to be negative when used as an int (NetBSD).
     200           *
     201           * Issue #28152: Use (0) instead of 0 to fix a warning on dead code
     202           * when using clang -Wunreachable-code. */
     203          if ((int)(SEM_VALUE_MAX) < (0))
     204              py_sem_value_max = PyLong_FromLong(INT_MAX);
     205          else
     206              py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX);
     207  
     208          if (py_sem_value_max == NULL) {
     209              return -1;
     210          }
     211          if (PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX",
     212                               py_sem_value_max) < 0) {
     213              Py_DECREF(py_sem_value_max);
     214              return -1;
     215          }
     216          Py_DECREF(py_sem_value_max);
     217      }
     218  
     219  #endif
     220  
     221      /* Add configuration macros */
     222      PyObject *flags = PyDict_New();
     223      if (!flags) {
     224          return -1;
     225      }
     226  
     227  #define ADD_FLAG(name)                                          \
     228      do {                                                        \
     229          PyObject *value = PyLong_FromLong(name);                \
     230          if (value == NULL) {                                    \
     231              Py_DECREF(flags);                                   \
     232              return -1;                                          \
     233          }                                                       \
     234          if (PyDict_SetItemString(flags, #name, value) < 0) {    \
     235              Py_DECREF(flags);                                   \
     236              Py_DECREF(value);                                   \
     237              return -1;                                          \
     238          }                                                       \
     239          Py_DECREF(value);                                       \
     240      } while (0)
     241  
     242  #if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
     243      ADD_FLAG(HAVE_SEM_OPEN);
     244  #endif
     245  #ifdef HAVE_SEM_TIMEDWAIT
     246      ADD_FLAG(HAVE_SEM_TIMEDWAIT);
     247  #endif
     248  #ifdef HAVE_BROKEN_SEM_GETVALUE
     249      ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
     250  #endif
     251  #ifdef HAVE_BROKEN_SEM_UNLINK
     252      ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
     253  #endif
     254  
     255      if (PyModule_AddObject(module, "flags", flags) < 0) {
     256          Py_DECREF(flags);
     257          return -1;
     258      }
     259  
     260      return 0;
     261  }
     262  
     263  static PyModuleDef_Slot multiprocessing_slots[] = {
     264      {Py_mod_exec, multiprocessing_exec},
     265      {0, NULL}
     266  };
     267  
     268  static struct PyModuleDef multiprocessing_module = {
     269      PyModuleDef_HEAD_INIT,
     270      .m_name = "_multiprocessing",
     271      .m_methods = module_methods,
     272      .m_slots = multiprocessing_slots,
     273  };
     274  
     275  PyMODINIT_FUNC
     276  PyInit__multiprocessing(void)
     277  {
     278      return PyModuleDef_Init(&multiprocessing_module);
     279  }