diff options
author | AlexSm <alex@ydb.tech> | 2024-03-05 10:40:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-05 12:40:59 +0300 |
commit | 1ac13c847b5358faba44dbb638a828e24369467b (patch) | |
tree | 07672b4dd3604ad3dee540a02c6494cb7d10dc3d /contrib/tools/python3/Modules/_multiprocessing | |
parent | ffcca3e7f7958ddc6487b91d3df8c01054bd0638 (diff) | |
download | ydb-1ac13c847b5358faba44dbb638a828e24369467b.tar.gz |
Library import 16 (#2433)
Co-authored-by: robot-piglet <robot-piglet@yandex-team.com>
Co-authored-by: deshevoy <deshevoy@yandex-team.com>
Co-authored-by: robot-contrib <robot-contrib@yandex-team.com>
Co-authored-by: thegeorg <thegeorg@yandex-team.com>
Co-authored-by: robot-ya-builder <robot-ya-builder@yandex-team.com>
Co-authored-by: svidyuk <svidyuk@yandex-team.com>
Co-authored-by: shadchin <shadchin@yandex-team.com>
Co-authored-by: robot-ratatosk <robot-ratatosk@yandex-team.com>
Co-authored-by: innokentii <innokentii@yandex-team.com>
Co-authored-by: arkady-e1ppa <arkady-e1ppa@yandex-team.com>
Co-authored-by: snermolaev <snermolaev@yandex-team.com>
Co-authored-by: dimdim11 <dimdim11@yandex-team.com>
Co-authored-by: kickbutt <kickbutt@yandex-team.com>
Co-authored-by: abdullinsaid <abdullinsaid@yandex-team.com>
Co-authored-by: korsunandrei <korsunandrei@yandex-team.com>
Co-authored-by: petrk <petrk@yandex-team.com>
Co-authored-by: miroslav2 <miroslav2@yandex-team.com>
Co-authored-by: serjflint <serjflint@yandex-team.com>
Co-authored-by: akhropov <akhropov@yandex-team.com>
Co-authored-by: prettyboy <prettyboy@yandex-team.com>
Co-authored-by: ilikepugs <ilikepugs@yandex-team.com>
Co-authored-by: hiddenpath <hiddenpath@yandex-team.com>
Co-authored-by: mikhnenko <mikhnenko@yandex-team.com>
Co-authored-by: spreis <spreis@yandex-team.com>
Co-authored-by: andreyshspb <andreyshspb@yandex-team.com>
Co-authored-by: dimaandreev <dimaandreev@yandex-team.com>
Co-authored-by: rashid <rashid@yandex-team.com>
Co-authored-by: robot-ydb-importer <robot-ydb-importer@yandex-team.com>
Co-authored-by: r-vetrov <r-vetrov@yandex-team.com>
Co-authored-by: ypodlesov <ypodlesov@yandex-team.com>
Co-authored-by: zaverden <zaverden@yandex-team.com>
Co-authored-by: vpozdyayev <vpozdyayev@yandex-team.com>
Co-authored-by: robot-cozmo <robot-cozmo@yandex-team.com>
Co-authored-by: v-korovin <v-korovin@yandex-team.com>
Co-authored-by: arikon <arikon@yandex-team.com>
Co-authored-by: khoden <khoden@yandex-team.com>
Co-authored-by: psydmm <psydmm@yandex-team.com>
Co-authored-by: robot-javacom <robot-javacom@yandex-team.com>
Co-authored-by: dtorilov <dtorilov@yandex-team.com>
Co-authored-by: sennikovmv <sennikovmv@yandex-team.com>
Co-authored-by: hcpp <hcpp@ydb.tech>
Diffstat (limited to 'contrib/tools/python3/Modules/_multiprocessing')
7 files changed, 2210 insertions, 0 deletions
diff --git a/contrib/tools/python3/Modules/_multiprocessing/clinic/multiprocessing.c.h b/contrib/tools/python3/Modules/_multiprocessing/clinic/multiprocessing.c.h new file mode 100644 index 0000000000..885cd5c2ff --- /dev/null +++ b/contrib/tools/python3/Modules/_multiprocessing/clinic/multiprocessing.c.h @@ -0,0 +1,175 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_closesocket__doc__, +"closesocket($module, handle, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_CLOSESOCKET_METHODDEF \ + {"closesocket", (PyCFunction)_multiprocessing_closesocket, METH_O, _multiprocessing_closesocket__doc__}, + +static PyObject * +_multiprocessing_closesocket_impl(PyObject *module, HANDLE handle); + +static PyObject * +_multiprocessing_closesocket(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE handle; + + handle = PyLong_AsVoidPtr(arg); + if (!handle && PyErr_Occurred()) { + goto exit; + } + return_value = _multiprocessing_closesocket_impl(module, handle); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_recv__doc__, +"recv($module, handle, size, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_RECV_METHODDEF \ + {"recv", _PyCFunction_CAST(_multiprocessing_recv), METH_FASTCALL, _multiprocessing_recv__doc__}, + +static PyObject * +_multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size); + +static PyObject * +_multiprocessing_recv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + int size; + + if (!_PyArg_CheckPositional("recv", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + size = _PyLong_AsInt(args[1]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _multiprocessing_recv_impl(module, handle, size); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_send__doc__, +"send($module, handle, buf, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_SEND_METHODDEF \ + {"send", _PyCFunction_CAST(_multiprocessing_send), METH_FASTCALL, _multiprocessing_send__doc__}, + +static PyObject * +_multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf); + +static PyObject * +_multiprocessing_send(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + Py_buffer buf = {NULL, NULL}; + + if (!_PyArg_CheckPositional("send", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &buf, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&buf, 'C')) { + _PyArg_BadArgument("send", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + return_value = _multiprocessing_send_impl(module, handle, &buf); + +exit: + /* Cleanup for buf */ + if (buf.obj) { + PyBuffer_Release(&buf); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +PyDoc_STRVAR(_multiprocessing_sem_unlink__doc__, +"sem_unlink($module, name, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_SEM_UNLINK_METHODDEF \ + {"sem_unlink", (PyCFunction)_multiprocessing_sem_unlink, METH_O, _multiprocessing_sem_unlink__doc__}, + +static PyObject * +_multiprocessing_sem_unlink_impl(PyObject *module, const char *name); + +static PyObject * +_multiprocessing_sem_unlink(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("sem_unlink", "argument", "str", arg); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(arg, &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _multiprocessing_sem_unlink_impl(module, name); + +exit: + return return_value; +} + +#ifndef _MULTIPROCESSING_CLOSESOCKET_METHODDEF + #define _MULTIPROCESSING_CLOSESOCKET_METHODDEF +#endif /* !defined(_MULTIPROCESSING_CLOSESOCKET_METHODDEF) */ + +#ifndef _MULTIPROCESSING_RECV_METHODDEF + #define _MULTIPROCESSING_RECV_METHODDEF +#endif /* !defined(_MULTIPROCESSING_RECV_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEND_METHODDEF + #define _MULTIPROCESSING_SEND_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEND_METHODDEF) */ +/*[clinic end generated code: output=4a6afc67c1f5ec85 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/Modules/_multiprocessing/clinic/posixshmem.c.h b/contrib/tools/python3/Modules/_multiprocessing/clinic/posixshmem.c.h new file mode 100644 index 0000000000..df2aa29cfe --- /dev/null +++ b/contrib/tools/python3/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -0,0 +1,175 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +#if defined(HAVE_SHM_OPEN) + +PyDoc_STRVAR(_posixshmem_shm_open__doc__, +"shm_open($module, /, path, flags, mode=511)\n" +"--\n" +"\n" +"Open a shared memory object. Returns a file descriptor (integer)."); + +#define _POSIXSHMEM_SHM_OPEN_METHODDEF \ + {"shm_open", _PyCFunction_CAST(_posixshmem_shm_open), METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_open__doc__}, + +static int +_posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags, + int mode); + +static PyObject * +_posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", "flags", "mode", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "shm_open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *path; + int flags; + int mode = 511; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("shm_open", "argument 'path'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + path = args[0]; + flags = _PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + mode = _PyLong_AsInt(args[2]); + if (mode == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + _return_value = _posixshmem_shm_open_impl(module, path, flags, mode); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SHM_OPEN) */ + +#if defined(HAVE_SHM_UNLINK) + +PyDoc_STRVAR(_posixshmem_shm_unlink__doc__, +"shm_unlink($module, /, path)\n" +"--\n" +"\n" +"Remove a shared memory object (similar to unlink()).\n" +"\n" +"Remove a shared memory object name, and, once all processes have unmapped\n" +"the object, de-allocates and destroys the contents of the associated memory\n" +"region."); + +#define _POSIXSHMEM_SHM_UNLINK_METHODDEF \ + {"shm_unlink", _PyCFunction_CAST(_posixshmem_shm_unlink), METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_unlink__doc__}, + +static PyObject * +_posixshmem_shm_unlink_impl(PyObject *module, PyObject *path); + +static PyObject * +_posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "shm_unlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("shm_unlink", "argument 'path'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + path = args[0]; + return_value = _posixshmem_shm_unlink_impl(module, path); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SHM_UNLINK) */ + +#ifndef _POSIXSHMEM_SHM_OPEN_METHODDEF + #define _POSIXSHMEM_SHM_OPEN_METHODDEF +#endif /* !defined(_POSIXSHMEM_SHM_OPEN_METHODDEF) */ + +#ifndef _POSIXSHMEM_SHM_UNLINK_METHODDEF + #define _POSIXSHMEM_SHM_UNLINK_METHODDEF +#endif /* !defined(_POSIXSHMEM_SHM_UNLINK_METHODDEF) */ +/*[clinic end generated code: output=3f6fee283d5fd0e9 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/Modules/_multiprocessing/clinic/semaphore.c.h b/contrib/tools/python3/Modules/_multiprocessing/clinic/semaphore.c.h new file mode 100644 index 0000000000..35347169bc --- /dev/null +++ b/contrib/tools/python3/Modules/_multiprocessing/clinic/semaphore.c.h @@ -0,0 +1,545 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +#if defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, +"acquire($self, /, block=True, timeout=None)\n" +"--\n" +"\n" +"Acquire the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF \ + {"acquire", _PyCFunction_CAST(_multiprocessing_SemLock_acquire), METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, + +static PyObject * +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj); + +static PyObject * +_multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"block", "timeout", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "acquire", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int blocking = 1; + PyObject *timeout_obj = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + blocking = PyObject_IsTrue(args[0]); + if (blocking < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + timeout_obj = args[1]; +skip_optional_pos: + return_value = _multiprocessing_SemLock_acquire_impl(self, blocking, timeout_obj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) */ + +#if defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_release__doc__, +"release($self, /)\n" +"--\n" +"\n" +"Release the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF \ + {"release", (PyCFunction)_multiprocessing_SemLock_release, METH_NOARGS, _multiprocessing_SemLock_release__doc__}, + +static PyObject * +_multiprocessing_SemLock_release_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock_release(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock_release_impl(self); +} + +#endif /* defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) */ + +#if defined(HAVE_MP_SEMAPHORE) && !defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, +"acquire($self, /, block=True, timeout=None)\n" +"--\n" +"\n" +"Acquire the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF \ + {"acquire", _PyCFunction_CAST(_multiprocessing_SemLock_acquire), METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, + +static PyObject * +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj); + +static PyObject * +_multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"block", "timeout", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "acquire", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int blocking = 1; + PyObject *timeout_obj = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + blocking = PyObject_IsTrue(args[0]); + if (blocking < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + timeout_obj = args[1]; +skip_optional_pos: + return_value = _multiprocessing_SemLock_acquire_impl(self, blocking, timeout_obj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_MP_SEMAPHORE) && !defined(MS_WINDOWS) */ + +#if defined(HAVE_MP_SEMAPHORE) && !defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_release__doc__, +"release($self, /)\n" +"--\n" +"\n" +"Release the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF \ + {"release", (PyCFunction)_multiprocessing_SemLock_release, METH_NOARGS, _multiprocessing_SemLock_release__doc__}, + +static PyObject * +_multiprocessing_SemLock_release_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock_release(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock_release_impl(self); +} + +#endif /* defined(HAVE_MP_SEMAPHORE) && !defined(MS_WINDOWS) */ + +#if defined(HAVE_MP_SEMAPHORE) + +static PyObject * +_multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, + int maxvalue, const char *name, int unlink); + +static PyObject * +_multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(kind), &_Py_ID(value), &_Py_ID(maxvalue), &_Py_ID(name), &_Py_ID(unlink), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"kind", "value", "maxvalue", "name", "unlink", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "SemLock", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + int kind; + int value; + int maxvalue; + const char *name; + int unlink; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 5, 5, 0, argsbuf); + if (!fastargs) { + goto exit; + } + kind = _PyLong_AsInt(fastargs[0]); + if (kind == -1 && PyErr_Occurred()) { + goto exit; + } + value = _PyLong_AsInt(fastargs[1]); + if (value == -1 && PyErr_Occurred()) { + goto exit; + } + maxvalue = _PyLong_AsInt(fastargs[2]); + if (maxvalue == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyUnicode_Check(fastargs[3])) { + _PyArg_BadArgument("SemLock", "argument 'name'", "str", fastargs[3]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(fastargs[3], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + unlink = PyObject_IsTrue(fastargs[4]); + if (unlink < 0) { + goto exit; + } + return_value = _multiprocessing_SemLock_impl(type, kind, value, maxvalue, name, unlink); + +exit: + return return_value; +} + +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + +PyDoc_STRVAR(_multiprocessing_SemLock__rebuild__doc__, +"_rebuild($type, handle, kind, maxvalue, name, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF \ + {"_rebuild", _PyCFunction_CAST(_multiprocessing_SemLock__rebuild), METH_FASTCALL|METH_CLASS, _multiprocessing_SemLock__rebuild__doc__}, + +static PyObject * +_multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, + int kind, int maxvalue, + const char *name); + +static PyObject * +_multiprocessing_SemLock__rebuild(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + SEM_HANDLE handle; + int kind; + int maxvalue; + const char *name; + + if (!_PyArg_ParseStack(args, nargs, ""F_SEM_HANDLE"iiz:_rebuild", + &handle, &kind, &maxvalue, &name)) { + goto exit; + } + return_value = _multiprocessing_SemLock__rebuild_impl(type, handle, kind, maxvalue, name); + +exit: + return return_value; +} + +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + +PyDoc_STRVAR(_multiprocessing_SemLock__count__doc__, +"_count($self, /)\n" +"--\n" +"\n" +"Num of `acquire()`s minus num of `release()`s for this process."); + +#define _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF \ + {"_count", (PyCFunction)_multiprocessing_SemLock__count, METH_NOARGS, _multiprocessing_SemLock__count__doc__}, + +static PyObject * +_multiprocessing_SemLock__count_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__count(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__count_impl(self); +} + +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + +PyDoc_STRVAR(_multiprocessing_SemLock__is_mine__doc__, +"_is_mine($self, /)\n" +"--\n" +"\n" +"Whether the lock is owned by this thread."); + +#define _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF \ + {"_is_mine", (PyCFunction)_multiprocessing_SemLock__is_mine, METH_NOARGS, _multiprocessing_SemLock__is_mine__doc__}, + +static PyObject * +_multiprocessing_SemLock__is_mine_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__is_mine(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__is_mine_impl(self); +} + +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + +PyDoc_STRVAR(_multiprocessing_SemLock__get_value__doc__, +"_get_value($self, /)\n" +"--\n" +"\n" +"Get the value of the semaphore."); + +#define _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF \ + {"_get_value", (PyCFunction)_multiprocessing_SemLock__get_value, METH_NOARGS, _multiprocessing_SemLock__get_value__doc__}, + +static PyObject * +_multiprocessing_SemLock__get_value_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__get_value(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__get_value_impl(self); +} + +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + +PyDoc_STRVAR(_multiprocessing_SemLock__is_zero__doc__, +"_is_zero($self, /)\n" +"--\n" +"\n" +"Return whether semaphore has value zero."); + +#define _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF \ + {"_is_zero", (PyCFunction)_multiprocessing_SemLock__is_zero, METH_NOARGS, _multiprocessing_SemLock__is_zero__doc__}, + +static PyObject * +_multiprocessing_SemLock__is_zero_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__is_zero(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__is_zero_impl(self); +} + +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + +PyDoc_STRVAR(_multiprocessing_SemLock__after_fork__doc__, +"_after_fork($self, /)\n" +"--\n" +"\n" +"Rezero the net acquisition count after fork()."); + +#define _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF \ + {"_after_fork", (PyCFunction)_multiprocessing_SemLock__after_fork, METH_NOARGS, _multiprocessing_SemLock__after_fork__doc__}, + +static PyObject * +_multiprocessing_SemLock__after_fork_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__after_fork(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__after_fork_impl(self); +} + +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + +PyDoc_STRVAR(_multiprocessing_SemLock___enter____doc__, +"__enter__($self, /)\n" +"--\n" +"\n" +"Enter the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF \ + {"__enter__", (PyCFunction)_multiprocessing_SemLock___enter__, METH_NOARGS, _multiprocessing_SemLock___enter____doc__}, + +static PyObject * +_multiprocessing_SemLock___enter___impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock___enter__(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock___enter___impl(self); +} + +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + +PyDoc_STRVAR(_multiprocessing_SemLock___exit____doc__, +"__exit__($self, exc_type=None, exc_value=None, exc_tb=None, /)\n" +"--\n" +"\n" +"Exit the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF \ + {"__exit__", _PyCFunction_CAST(_multiprocessing_SemLock___exit__), METH_FASTCALL, _multiprocessing_SemLock___exit____doc__}, + +static PyObject * +_multiprocessing_SemLock___exit___impl(SemLockObject *self, + PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +_multiprocessing_SemLock___exit__(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc_type = Py_None; + PyObject *exc_value = Py_None; + PyObject *exc_tb = Py_None; + + if (!_PyArg_CheckPositional("__exit__", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + exc_type = args[0]; + if (nargs < 2) { + goto skip_optional; + } + exc_value = args[1]; + if (nargs < 3) { + goto skip_optional; + } + exc_tb = args[2]; +skip_optional: + return_value = _multiprocessing_SemLock___exit___impl(self, exc_type, exc_value, exc_tb); + +exit: + return return_value; +} + +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#ifndef _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF + #define _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF + #define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF) */ +/*[clinic end generated code: output=dae57a702cc01512 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/Modules/_multiprocessing/multiprocessing.c b/contrib/tools/python3/Modules/_multiprocessing/multiprocessing.c new file mode 100644 index 0000000000..8f9daa5c3d --- /dev/null +++ b/contrib/tools/python3/Modules/_multiprocessing/multiprocessing.c @@ -0,0 +1,295 @@ +/* + * Extension module used by multiprocessing package + * + * multiprocessing.c + * + * Copyright (c) 2006-2008, R Oudkerk + * Licensed to PSF under a Contributor Agreement. + */ + +#include "multiprocessing.h" + +/*[python input] +class HANDLE_converter(CConverter): + type = "HANDLE" + format_unit = '"F_HANDLE"' + + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3e537d244034affb]*/ + +/*[clinic input] +module _multiprocessing +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=01e0745f380ac6e3]*/ + +#include "clinic/multiprocessing.c.h" + +/* + * Function which raises exceptions based on error codes + */ + +PyObject * +_PyMp_SetError(PyObject *Type, int num) +{ + switch (num) { +#ifdef MS_WINDOWS + case MP_STANDARD_ERROR: + if (Type == NULL) + Type = PyExc_OSError; + PyErr_SetExcFromWindowsErr(Type, 0); + break; + case MP_SOCKET_ERROR: + if (Type == NULL) + Type = PyExc_OSError; + PyErr_SetExcFromWindowsErr(Type, WSAGetLastError()); + break; +#else /* !MS_WINDOWS */ + case MP_STANDARD_ERROR: + case MP_SOCKET_ERROR: + if (Type == NULL) + Type = PyExc_OSError; + PyErr_SetFromErrno(Type); + break; +#endif /* !MS_WINDOWS */ + case MP_MEMORY_ERROR: + PyErr_NoMemory(); + break; + case MP_EXCEPTION_HAS_BEEN_SET: + break; + default: + PyErr_Format(PyExc_RuntimeError, + "unknown error number %d", num); + } + return NULL; +} + +#ifdef MS_WINDOWS +/*[clinic input] +_multiprocessing.closesocket + + handle: HANDLE + / + +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_closesocket_impl(PyObject *module, HANDLE handle) +/*[clinic end generated code: output=214f359f900966f4 input=8a20706dd386c6cc]*/ +{ + int ret; + + Py_BEGIN_ALLOW_THREADS + ret = closesocket((SOCKET) handle); + Py_END_ALLOW_THREADS + + if (ret) + return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + Py_RETURN_NONE; +} + +/*[clinic input] +_multiprocessing.recv + + handle: HANDLE + size: int + / + +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size) +/*[clinic end generated code: output=92322781ba9ff598 input=6a5b0834372cee5b]*/ +{ + int nread; + PyObject *buf; + + buf = PyBytes_FromStringAndSize(NULL, size); + if (!buf) + return NULL; + + Py_BEGIN_ALLOW_THREADS + nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0); + Py_END_ALLOW_THREADS + + if (nread < 0) { + Py_DECREF(buf); + return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + } + _PyBytes_Resize(&buf, nread); + return buf; +} + +/*[clinic input] +_multiprocessing.send + + handle: HANDLE + buf: Py_buffer + / + +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf) +/*[clinic end generated code: output=52d7df0519c596cb input=41dce742f98d2210]*/ +{ + int ret, length; + + length = (int)Py_MIN(buf->len, INT_MAX); + + Py_BEGIN_ALLOW_THREADS + ret = send((SOCKET) handle, buf->buf, length, 0); + Py_END_ALLOW_THREADS + + if (ret < 0) + return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + return PyLong_FromLong(ret); +} + +#endif + +/*[clinic input] +_multiprocessing.sem_unlink + + name: str + / + +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_sem_unlink_impl(PyObject *module, const char *name) +/*[clinic end generated code: output=fcbfeb1ed255e647 input=bf939aff9564f1d5]*/ +{ + return _PyMp_sem_unlink(name); +} + +/* + * Function table + */ + +static PyMethodDef module_methods[] = { +#ifdef MS_WINDOWS + _MULTIPROCESSING_CLOSESOCKET_METHODDEF + _MULTIPROCESSING_RECV_METHODDEF + _MULTIPROCESSING_SEND_METHODDEF +#endif +#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__) + _MULTIPROCESSING_SEM_UNLINK_METHODDEF +#endif + {NULL} +}; + + +/* + * Initialize + */ + +static int +multiprocessing_exec(PyObject *module) +{ +#ifdef HAVE_MP_SEMAPHORE + + PyTypeObject *semlock_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &_PyMp_SemLockType_spec, NULL); + + if (semlock_type == NULL) { + return -1; + } + int rc = PyModule_AddType(module, semlock_type); + Py_DECREF(semlock_type); + if (rc < 0) { + return -1; + } + + PyObject *py_sem_value_max; + /* Some systems define SEM_VALUE_MAX as an unsigned value that + * causes it to be negative when used as an int (NetBSD). + * + * Issue #28152: Use (0) instead of 0 to fix a warning on dead code + * when using clang -Wunreachable-code. */ + if ((int)(SEM_VALUE_MAX) < (0)) { + py_sem_value_max = PyLong_FromLong(INT_MAX); + } + else { + py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); + } + if (py_sem_value_max == NULL) { + return -1; + } + if (PyDict_SetItemString(semlock_type->tp_dict, "SEM_VALUE_MAX", + py_sem_value_max) < 0) { + Py_DECREF(py_sem_value_max); + return -1; + } + Py_DECREF(py_sem_value_max); + +#endif + + /* Add configuration macros */ + PyObject *flags = PyDict_New(); + if (!flags) { + return -1; + } + +#define ADD_FLAG(name) \ + do { \ + PyObject *value = PyLong_FromLong(name); \ + if (value == NULL) { \ + Py_DECREF(flags); \ + return -1; \ + } \ + if (PyDict_SetItemString(flags, #name, value) < 0) { \ + Py_DECREF(flags); \ + Py_DECREF(value); \ + return -1; \ + } \ + Py_DECREF(value); \ + } while (0) + +#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) + ADD_FLAG(HAVE_SEM_OPEN); +#endif +#ifdef HAVE_SEM_TIMEDWAIT + ADD_FLAG(HAVE_SEM_TIMEDWAIT); +#endif +#ifdef HAVE_BROKEN_SEM_GETVALUE + ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE); +#endif +#ifdef HAVE_BROKEN_SEM_UNLINK + ADD_FLAG(HAVE_BROKEN_SEM_UNLINK); +#endif + + if (PyModule_AddObject(module, "flags", flags) < 0) { + Py_DECREF(flags); + return -1; + } + + return 0; +} + +static PyModuleDef_Slot multiprocessing_slots[] = { + {Py_mod_exec, multiprocessing_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + +static struct PyModuleDef multiprocessing_module = { + PyModuleDef_HEAD_INIT, + .m_name = "_multiprocessing", + .m_size = 0, + .m_methods = module_methods, + .m_slots = multiprocessing_slots, +}; + +PyMODINIT_FUNC +PyInit__multiprocessing(void) +{ + return PyModuleDef_Init(&multiprocessing_module); +} diff --git a/contrib/tools/python3/Modules/_multiprocessing/multiprocessing.h b/contrib/tools/python3/Modules/_multiprocessing/multiprocessing.h new file mode 100644 index 0000000000..dfc2a8e079 --- /dev/null +++ b/contrib/tools/python3/Modules/_multiprocessing/multiprocessing.h @@ -0,0 +1,97 @@ +#ifndef MULTIPROCESSING_H +#define MULTIPROCESSING_H + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "structmember.h" +#include "pythread.h" + +/* + * Platform includes and definitions + */ + +#ifdef MS_WINDOWS +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include <windows.h> +# include <winsock2.h> +# include <process.h> /* getpid() */ +# ifdef Py_DEBUG +# include <crtdbg.h> +# endif +# define SEM_HANDLE HANDLE +# define SEM_VALUE_MAX LONG_MAX +# define HAVE_MP_SEMAPHORE +#else +# include <fcntl.h> /* O_CREAT and O_EXCL */ +# if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) +# define HAVE_MP_SEMAPHORE +# include <semaphore.h> + typedef sem_t *SEM_HANDLE; +# endif +#endif + +/* + * Issue 3110 - Solaris does not define SEM_VALUE_MAX + */ +#ifndef SEM_VALUE_MAX + #if defined(HAVE_SYSCONF) && defined(_SC_SEM_VALUE_MAX) + # define SEM_VALUE_MAX sysconf(_SC_SEM_VALUE_MAX) + #elif defined(_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _SEM_VALUE_MAX + #elif defined(_POSIX_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _POSIX_SEM_VALUE_MAX + #else + # define SEM_VALUE_MAX INT_MAX + #endif +#endif + + +/* + * Format codes + */ + +#if SIZEOF_VOID_P == SIZEOF_LONG +# define F_POINTER "k" +# define T_POINTER T_ULONG +#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG +# define F_POINTER "K" +# define T_POINTER T_ULONGLONG +#else +# error "can't find format code for unsigned integer of same size as void*" +#endif + +#ifdef MS_WINDOWS +# define F_HANDLE F_POINTER +# define T_HANDLE T_POINTER +# define F_SEM_HANDLE F_HANDLE +# define T_SEM_HANDLE T_HANDLE +#else +# define F_HANDLE "i" +# define T_HANDLE T_INT +# define F_SEM_HANDLE F_POINTER +# define T_SEM_HANDLE T_POINTER +#endif + +/* + * Error codes which can be returned by functions called without GIL + */ + +#define MP_SUCCESS (0) +#define MP_STANDARD_ERROR (-1) +#define MP_MEMORY_ERROR (-1001) +#define MP_SOCKET_ERROR (-1002) +#define MP_EXCEPTION_HAS_BEEN_SET (-1003) + +PyObject *_PyMp_SetError(PyObject *Type, int num); + +/* + * Externs - not all will really exist on all platforms + */ + +extern PyType_Spec _PyMp_SemLockType_spec; +extern PyObject *_PyMp_sem_unlink(const char *name); + +#endif /* MULTIPROCESSING_H */ diff --git a/contrib/tools/python3/Modules/_multiprocessing/posixshmem.c b/contrib/tools/python3/Modules/_multiprocessing/posixshmem.c new file mode 100644 index 0000000000..88c93fe313 --- /dev/null +++ b/contrib/tools/python3/Modules/_multiprocessing/posixshmem.c @@ -0,0 +1,133 @@ +/* +posixshmem - A Python extension that provides shm_open() and shm_unlink() +*/ + +#define PY_SSIZE_T_CLEAN + +#include <Python.h> + +// for shm_open() and shm_unlink() +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif + +/*[clinic input] +module _posixshmem +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a416734e49164bf8]*/ + +/* + * + * Module-level functions & meta stuff + * + */ + +#ifdef HAVE_SHM_OPEN +/*[clinic input] +_posixshmem.shm_open -> int + path: unicode + flags: int + mode: int = 0o777 + +# "shm_open(path, flags, mode=0o777)\n\n\ + +Open a shared memory object. Returns a file descriptor (integer). + +[clinic start generated code]*/ + +static int +_posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags, + int mode) +/*[clinic end generated code: output=8d110171a4fa20df input=e83b58fa802fac25]*/ +{ + int fd; + int async_err = 0; + const char *name = PyUnicode_AsUTF8(path); + if (name == NULL) { + return -1; + } + do { + Py_BEGIN_ALLOW_THREADS + fd = shm_open(name, flags, mode); + Py_END_ALLOW_THREADS + } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (fd < 0) { + if (!async_err) + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); + return -1; + } + + return fd; +} +#endif /* HAVE_SHM_OPEN */ + +#ifdef HAVE_SHM_UNLINK +/*[clinic input] +_posixshmem.shm_unlink + path: unicode + +Remove a shared memory object (similar to unlink()). + +Remove a shared memory object name, and, once all processes have unmapped +the object, de-allocates and destroys the contents of the associated memory +region. + +[clinic start generated code]*/ + +static PyObject * +_posixshmem_shm_unlink_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=42f8b23d134b9ff5 input=8dc0f87143e3b300]*/ +{ + int rv; + int async_err = 0; + const char *name = PyUnicode_AsUTF8(path); + if (name == NULL) { + return NULL; + } + do { + Py_BEGIN_ALLOW_THREADS + rv = shm_unlink(name); + Py_END_ALLOW_THREADS + } while (rv < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (rv < 0) { + if (!async_err) + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); + return NULL; + } + + Py_RETURN_NONE; +} +#endif /* HAVE_SHM_UNLINK */ + +#include "clinic/posixshmem.c.h" + +static PyMethodDef module_methods[ ] = { + _POSIXSHMEM_SHM_OPEN_METHODDEF + _POSIXSHMEM_SHM_UNLINK_METHODDEF + {NULL} /* Sentinel */ +}; + + +static PyModuleDef_Slot module_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + + +static struct PyModuleDef _posixshmemmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_posixshmem", + .m_doc = "POSIX shared memory module", + .m_size = 0, + .m_methods = module_methods, + .m_slots = module_slots, +}; + +/* Module init function */ +PyMODINIT_FUNC +PyInit__posixshmem(void) +{ + return PyModuleDef_Init(&_posixshmemmodule); +} diff --git a/contrib/tools/python3/Modules/_multiprocessing/semaphore.c b/contrib/tools/python3/Modules/_multiprocessing/semaphore.c new file mode 100644 index 0000000000..c7df82dfe2 --- /dev/null +++ b/contrib/tools/python3/Modules/_multiprocessing/semaphore.c @@ -0,0 +1,790 @@ +/* + * A type which wraps a semaphore + * + * semaphore.c + * + * Copyright (c) 2006-2008, R Oudkerk + * Licensed to PSF under a Contributor Agreement. + */ + +#include "multiprocessing.h" + +#ifdef HAVE_MP_SEMAPHORE + +enum { RECURSIVE_MUTEX, SEMAPHORE }; + +typedef struct { + PyObject_HEAD + SEM_HANDLE handle; + unsigned long last_tid; + int count; + int maxvalue; + int kind; + char *name; +} SemLockObject; + +/*[python input] +class SEM_HANDLE_converter(CConverter): + type = "SEM_HANDLE" + format_unit = '"F_SEM_HANDLE"' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3e0ad43e482d8716]*/ + +/*[clinic input] +module _multiprocessing +class _multiprocessing.SemLock "SemLockObject *" "&_PyMp_SemLockType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=935fb41b7d032599]*/ + +#include "clinic/semaphore.c.h" + +#define ISMINE(o) (o->count > 0 && PyThread_get_thread_ident() == o->last_tid) + + +#ifdef MS_WINDOWS + +/* + * Windows definitions + */ + +#define SEM_FAILED NULL + +#define SEM_CLEAR_ERROR() SetLastError(0) +#define SEM_GET_LAST_ERROR() GetLastError() +#define SEM_CREATE(name, val, max) CreateSemaphore(NULL, val, max, NULL) +#define SEM_CLOSE(sem) (CloseHandle(sem) ? 0 : -1) +#define SEM_GETVALUE(sem, pval) _GetSemaphoreValue(sem, pval) +#define SEM_UNLINK(name) 0 + +static int +_GetSemaphoreValue(HANDLE handle, long *value) +{ + long previous; + + switch (WaitForSingleObjectEx(handle, 0, FALSE)) { + case WAIT_OBJECT_0: + if (!ReleaseSemaphore(handle, 1, &previous)) + return MP_STANDARD_ERROR; + *value = previous + 1; + return 0; + case WAIT_TIMEOUT: + *value = 0; + return 0; + default: + return MP_STANDARD_ERROR; + } +} + +/*[clinic input] +_multiprocessing.SemLock.acquire + + block as blocking: bool = True + timeout as timeout_obj: object = None + +Acquire the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj) +/*[clinic end generated code: output=f9998f0b6b0b0872 input=e5b45f5cbb775166]*/ +{ + double timeout; + DWORD res, full_msecs, nhandles; + HANDLE handles[2], sigint_event; + + /* calculate timeout */ + if (!blocking) { + full_msecs = 0; + } else if (timeout_obj == Py_None) { + full_msecs = INFINITE; + } else { + timeout = PyFloat_AsDouble(timeout_obj); + if (PyErr_Occurred()) + return NULL; + timeout *= 1000.0; /* convert to millisecs */ + if (timeout < 0.0) { + timeout = 0.0; + } else if (timeout >= 0.5 * INFINITE) { /* 25 days */ + PyErr_SetString(PyExc_OverflowError, + "timeout is too large"); + return NULL; + } + full_msecs = (DWORD)(timeout + 0.5); + } + + /* check whether we already own the lock */ + if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { + ++self->count; + Py_RETURN_TRUE; + } + + /* check whether we can acquire without releasing the GIL and blocking */ + if (WaitForSingleObjectEx(self->handle, 0, FALSE) == WAIT_OBJECT_0) { + self->last_tid = GetCurrentThreadId(); + ++self->count; + Py_RETURN_TRUE; + } + + /* prepare list of handles */ + nhandles = 0; + handles[nhandles++] = self->handle; + if (_PyOS_IsMainThread()) { + sigint_event = _PyOS_SigintEvent(); + assert(sigint_event != NULL); + handles[nhandles++] = sigint_event; + } + else { + sigint_event = NULL; + } + + /* do the wait */ + Py_BEGIN_ALLOW_THREADS + if (sigint_event != NULL) + ResetEvent(sigint_event); + res = WaitForMultipleObjectsEx(nhandles, handles, FALSE, full_msecs, FALSE); + Py_END_ALLOW_THREADS + + /* handle result */ + switch (res) { + case WAIT_TIMEOUT: + Py_RETURN_FALSE; + case WAIT_OBJECT_0 + 0: + self->last_tid = GetCurrentThreadId(); + ++self->count; + Py_RETURN_TRUE; + case WAIT_OBJECT_0 + 1: + errno = EINTR; + return PyErr_SetFromErrno(PyExc_OSError); + case WAIT_FAILED: + return PyErr_SetFromWindowsErr(0); + default: + PyErr_Format(PyExc_RuntimeError, "WaitForSingleObject() or " + "WaitForMultipleObjects() gave unrecognized " + "value %u", res); + return NULL; + } +} + +/*[clinic input] +_multiprocessing.SemLock.release + +Release the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock_release_impl(SemLockObject *self) +/*[clinic end generated code: output=b22f53ba96b0d1db input=ba7e63a961885d3d]*/ +{ + if (self->kind == RECURSIVE_MUTEX) { + if (!ISMINE(self)) { + PyErr_SetString(PyExc_AssertionError, "attempt to " + "release recursive lock not owned " + "by thread"); + return NULL; + } + if (self->count > 1) { + --self->count; + Py_RETURN_NONE; + } + assert(self->count == 1); + } + + if (!ReleaseSemaphore(self->handle, 1, NULL)) { + if (GetLastError() == ERROR_TOO_MANY_POSTS) { + PyErr_SetString(PyExc_ValueError, "semaphore or lock " + "released too many times"); + return NULL; + } else { + return PyErr_SetFromWindowsErr(0); + } + } + + --self->count; + Py_RETURN_NONE; +} + +#else /* !MS_WINDOWS */ + +/* + * Unix definitions + */ + +#define SEM_CLEAR_ERROR() +#define SEM_GET_LAST_ERROR() 0 +#define SEM_CREATE(name, val, max) sem_open(name, O_CREAT | O_EXCL, 0600, val) +#define SEM_CLOSE(sem) sem_close(sem) +#define SEM_GETVALUE(sem, pval) sem_getvalue(sem, pval) +#define SEM_UNLINK(name) sem_unlink(name) + +/* OS X 10.4 defines SEM_FAILED as -1 instead of (sem_t *)-1; this gives + compiler warnings, and (potentially) undefined behaviour. */ +#ifdef __APPLE__ +# undef SEM_FAILED +# define SEM_FAILED ((sem_t *)-1) +#endif + +#ifndef HAVE_SEM_UNLINK +# define sem_unlink(name) 0 +#endif + +#ifndef HAVE_SEM_TIMEDWAIT +# define sem_timedwait(sem,deadline) sem_timedwait_save(sem,deadline,_save) + +static int +sem_timedwait_save(sem_t *sem, struct timespec *deadline, PyThreadState *_save) +{ + int res; + unsigned long delay, difference; + struct timeval now, tvdeadline, tvdelay; + + errno = 0; + tvdeadline.tv_sec = deadline->tv_sec; + tvdeadline.tv_usec = deadline->tv_nsec / 1000; + + for (delay = 0 ; ; delay += 1000) { + /* poll */ + if (sem_trywait(sem) == 0) + return 0; + else if (errno != EAGAIN) + return MP_STANDARD_ERROR; + + /* get current time */ + if (gettimeofday(&now, NULL) < 0) + return MP_STANDARD_ERROR; + + /* check for timeout */ + if (tvdeadline.tv_sec < now.tv_sec || + (tvdeadline.tv_sec == now.tv_sec && + tvdeadline.tv_usec <= now.tv_usec)) { + errno = ETIMEDOUT; + return MP_STANDARD_ERROR; + } + + /* calculate how much time is left */ + difference = (tvdeadline.tv_sec - now.tv_sec) * 1000000 + + (tvdeadline.tv_usec - now.tv_usec); + + /* check delay not too long -- maximum is 20 msecs */ + if (delay > 20000) + delay = 20000; + if (delay > difference) + delay = difference; + + /* sleep */ + tvdelay.tv_sec = delay / 1000000; + tvdelay.tv_usec = delay % 1000000; + if (select(0, NULL, NULL, NULL, &tvdelay) < 0) + return MP_STANDARD_ERROR; + + /* check for signals */ + Py_BLOCK_THREADS + res = PyErr_CheckSignals(); + Py_UNBLOCK_THREADS + + if (res) { + errno = EINTR; + return MP_EXCEPTION_HAS_BEEN_SET; + } + } +} + +#endif /* !HAVE_SEM_TIMEDWAIT */ + +/*[clinic input] +_multiprocessing.SemLock.acquire + + block as blocking: bool = True + timeout as timeout_obj: object = None + +Acquire the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj) +/*[clinic end generated code: output=f9998f0b6b0b0872 input=e5b45f5cbb775166]*/ +{ + int res, err = 0; + struct timespec deadline = {0}; + + if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { + ++self->count; + Py_RETURN_TRUE; + } + + int use_deadline = (timeout_obj != Py_None); + if (use_deadline) { + double timeout = PyFloat_AsDouble(timeout_obj); + if (PyErr_Occurred()) { + return NULL; + } + if (timeout < 0.0) { + timeout = 0.0; + } + + struct timeval now; + if (gettimeofday(&now, NULL) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + long sec = (long) timeout; + long nsec = (long) (1e9 * (timeout - sec) + 0.5); + deadline.tv_sec = now.tv_sec + sec; + deadline.tv_nsec = now.tv_usec * 1000 + nsec; + deadline.tv_sec += (deadline.tv_nsec / 1000000000); + deadline.tv_nsec %= 1000000000; + } + + /* Check whether we can acquire without releasing the GIL and blocking */ + do { + res = sem_trywait(self->handle); + err = errno; + } while (res < 0 && errno == EINTR && !PyErr_CheckSignals()); + errno = err; + + if (res < 0 && errno == EAGAIN && blocking) { + /* Couldn't acquire immediately, need to block */ + do { + Py_BEGIN_ALLOW_THREADS + if (!use_deadline) { + res = sem_wait(self->handle); + } + else { + res = sem_timedwait(self->handle, &deadline); + } + Py_END_ALLOW_THREADS + err = errno; + if (res == MP_EXCEPTION_HAS_BEEN_SET) + break; + } while (res < 0 && errno == EINTR && !PyErr_CheckSignals()); + } + + if (res < 0) { + errno = err; + if (errno == EAGAIN || errno == ETIMEDOUT) + Py_RETURN_FALSE; + else if (errno == EINTR) + return NULL; + else + return PyErr_SetFromErrno(PyExc_OSError); + } + + ++self->count; + self->last_tid = PyThread_get_thread_ident(); + + Py_RETURN_TRUE; +} + +/*[clinic input] +_multiprocessing.SemLock.release + +Release the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock_release_impl(SemLockObject *self) +/*[clinic end generated code: output=b22f53ba96b0d1db input=ba7e63a961885d3d]*/ +{ + if (self->kind == RECURSIVE_MUTEX) { + if (!ISMINE(self)) { + PyErr_SetString(PyExc_AssertionError, "attempt to " + "release recursive lock not owned " + "by thread"); + return NULL; + } + if (self->count > 1) { + --self->count; + Py_RETURN_NONE; + } + assert(self->count == 1); + } else { +#ifdef HAVE_BROKEN_SEM_GETVALUE + /* We will only check properly the maxvalue == 1 case */ + if (self->maxvalue == 1) { + /* make sure that already locked */ + if (sem_trywait(self->handle) < 0) { + if (errno != EAGAIN) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + /* it is already locked as expected */ + } else { + /* it was not locked so undo wait and raise */ + if (sem_post(self->handle) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + PyErr_SetString(PyExc_ValueError, "semaphore " + "or lock released too many " + "times"); + return NULL; + } + } +#else + int sval; + + /* This check is not an absolute guarantee that the semaphore + does not rise above maxvalue. */ + if (sem_getvalue(self->handle, &sval) < 0) { + return PyErr_SetFromErrno(PyExc_OSError); + } else if (sval >= self->maxvalue) { + PyErr_SetString(PyExc_ValueError, "semaphore or lock " + "released too many times"); + return NULL; + } +#endif + } + + if (sem_post(self->handle) < 0) + return PyErr_SetFromErrno(PyExc_OSError); + + --self->count; + Py_RETURN_NONE; +} + +#endif /* !MS_WINDOWS */ + +/* + * All platforms + */ + +static PyObject * +newsemlockobject(PyTypeObject *type, SEM_HANDLE handle, int kind, int maxvalue, + char *name) +{ + SemLockObject *self = (SemLockObject *)type->tp_alloc(type, 0); + if (!self) + return NULL; + self->handle = handle; + self->kind = kind; + self->count = 0; + self->last_tid = 0; + self->maxvalue = maxvalue; + self->name = name; + return (PyObject*)self; +} + +/*[clinic input] +@classmethod +_multiprocessing.SemLock.__new__ + + kind: int + value: int + maxvalue: int + name: str + unlink: bool + +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, + int maxvalue, const char *name, int unlink) +/*[clinic end generated code: output=30727e38f5f7577a input=fdaeb69814471c5b]*/ +{ + SEM_HANDLE handle = SEM_FAILED; + PyObject *result; + char *name_copy = NULL; + + if (kind != RECURSIVE_MUTEX && kind != SEMAPHORE) { + PyErr_SetString(PyExc_ValueError, "unrecognized kind"); + return NULL; + } + + if (!unlink) { + name_copy = PyMem_Malloc(strlen(name) + 1); + if (name_copy == NULL) { + return PyErr_NoMemory(); + } + strcpy(name_copy, name); + } + + SEM_CLEAR_ERROR(); + handle = SEM_CREATE(name, value, maxvalue); + /* On Windows we should fail if GetLastError()==ERROR_ALREADY_EXISTS */ + if (handle == SEM_FAILED || SEM_GET_LAST_ERROR() != 0) + goto failure; + + if (unlink && SEM_UNLINK(name) < 0) + goto failure; + + result = newsemlockobject(type, handle, kind, maxvalue, name_copy); + if (!result) + goto failure; + + return result; + + failure: + if (!PyErr_Occurred()) { + _PyMp_SetError(NULL, MP_STANDARD_ERROR); + } + if (handle != SEM_FAILED) + SEM_CLOSE(handle); + PyMem_Free(name_copy); + return NULL; +} + +/*[clinic input] +@classmethod +_multiprocessing.SemLock._rebuild + + handle: SEM_HANDLE + kind: int + maxvalue: int + name: str(accept={str, NoneType}) + / + +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, + int kind, int maxvalue, + const char *name) +/*[clinic end generated code: output=2aaee14f063f3bd9 input=f7040492ac6d9962]*/ +{ + char *name_copy = NULL; + + if (name != NULL) { + name_copy = PyMem_Malloc(strlen(name) + 1); + if (name_copy == NULL) + return PyErr_NoMemory(); + strcpy(name_copy, name); + } + +#ifndef MS_WINDOWS + if (name != NULL) { + handle = sem_open(name, 0); + if (handle == SEM_FAILED) { + PyErr_SetFromErrno(PyExc_OSError); + PyMem_Free(name_copy); + return NULL; + } + } +#endif + + return newsemlockobject(type, handle, kind, maxvalue, name_copy); +} + +static void +semlock_dealloc(SemLockObject* self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + if (self->handle != SEM_FAILED) + SEM_CLOSE(self->handle); + PyMem_Free(self->name); + tp->tp_free(self); + Py_DECREF(tp); +} + +/*[clinic input] +_multiprocessing.SemLock._count + +Num of `acquire()`s minus num of `release()`s for this process. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock__count_impl(SemLockObject *self) +/*[clinic end generated code: output=5ba8213900e517bb input=36fc59b1cd1025ab]*/ +{ + return PyLong_FromLong((long)self->count); +} + +/*[clinic input] +_multiprocessing.SemLock._is_mine + +Whether the lock is owned by this thread. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock__is_mine_impl(SemLockObject *self) +/*[clinic end generated code: output=92dc98863f4303be input=a96664cb2f0093ba]*/ +{ + /* only makes sense for a lock */ + return PyBool_FromLong(ISMINE(self)); +} + +/*[clinic input] +_multiprocessing.SemLock._get_value + +Get the value of the semaphore. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock__get_value_impl(SemLockObject *self) +/*[clinic end generated code: output=64bc1b89bda05e36 input=cb10f9a769836203]*/ +{ +#ifdef HAVE_BROKEN_SEM_GETVALUE + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; +#else + int sval; + if (SEM_GETVALUE(self->handle, &sval) < 0) + return _PyMp_SetError(NULL, MP_STANDARD_ERROR); + /* some posix implementations use negative numbers to indicate + the number of waiting threads */ + if (sval < 0) + sval = 0; + return PyLong_FromLong((long)sval); +#endif +} + +/*[clinic input] +_multiprocessing.SemLock._is_zero + +Return whether semaphore has value zero. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock__is_zero_impl(SemLockObject *self) +/*[clinic end generated code: output=815d4c878c806ed7 input=294a446418d31347]*/ +{ +#ifdef HAVE_BROKEN_SEM_GETVALUE + if (sem_trywait(self->handle) < 0) { + if (errno == EAGAIN) + Py_RETURN_TRUE; + return _PyMp_SetError(NULL, MP_STANDARD_ERROR); + } else { + if (sem_post(self->handle) < 0) + return _PyMp_SetError(NULL, MP_STANDARD_ERROR); + Py_RETURN_FALSE; + } +#else + int sval; + if (SEM_GETVALUE(self->handle, &sval) < 0) + return _PyMp_SetError(NULL, MP_STANDARD_ERROR); + return PyBool_FromLong((long)sval == 0); +#endif +} + +/*[clinic input] +_multiprocessing.SemLock._after_fork + +Rezero the net acquisition count after fork(). +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock__after_fork_impl(SemLockObject *self) +/*[clinic end generated code: output=718bb27914c6a6c1 input=190991008a76621e]*/ +{ + self->count = 0; + Py_RETURN_NONE; +} + +/*[clinic input] +_multiprocessing.SemLock.__enter__ + +Enter the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock___enter___impl(SemLockObject *self) +/*[clinic end generated code: output=beeb2f07c858511f input=c5e27d594284690b]*/ +{ + return _multiprocessing_SemLock_acquire_impl(self, 1, Py_None); +} + +/*[clinic input] +_multiprocessing.SemLock.__exit__ + + exc_type: object = None + exc_value: object = None + exc_tb: object = None + / + +Exit the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock___exit___impl(SemLockObject *self, + PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb) +/*[clinic end generated code: output=3b37c1a9f8b91a03 input=7d644b64a89903f8]*/ +{ + return _multiprocessing_SemLock_release_impl(self); +} + +static int +semlock_traverse(SemLockObject *s, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(s)); + return 0; +} + +/* + * Semaphore methods + */ + +static PyMethodDef semlock_methods[] = { + _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF + _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF + _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF + _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF + _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF + _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF + _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF + _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF + _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF + _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF + {NULL} +}; + +/* + * Member table + */ + +static PyMemberDef semlock_members[] = { + {"handle", T_SEM_HANDLE, offsetof(SemLockObject, handle), READONLY, + ""}, + {"kind", T_INT, offsetof(SemLockObject, kind), READONLY, + ""}, + {"maxvalue", T_INT, offsetof(SemLockObject, maxvalue), READONLY, + ""}, + {"name", T_STRING, offsetof(SemLockObject, name), READONLY, + ""}, + {NULL} +}; + +/* + * Semaphore type + */ + +static PyType_Slot _PyMp_SemLockType_slots[] = { + {Py_tp_dealloc, semlock_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_setattro, PyObject_GenericSetAttr}, + {Py_tp_methods, semlock_methods}, + {Py_tp_members, semlock_members}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, _multiprocessing_SemLock}, + {Py_tp_traverse, semlock_traverse}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_doc, (void *)PyDoc_STR("Semaphore/Mutex type")}, + {0, 0}, +}; + +PyType_Spec _PyMp_SemLockType_spec = { + .name = "_multiprocessing.SemLock", + .basicsize = sizeof(SemLockObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = _PyMp_SemLockType_slots, +}; + +/* + * Function to unlink semaphore names + */ + +PyObject * +_PyMp_sem_unlink(const char *name) +{ + if (SEM_UNLINK(name) < 0) { + _PyMp_SetError(NULL, MP_STANDARD_ERROR); + return NULL; + } + + Py_RETURN_NONE; +} + +#endif // HAVE_MP_SEMAPHORE |