diff options
| author | thegeorg <[email protected]> | 2024-02-19 02:38:52 +0300 | 
|---|---|---|
| committer | thegeorg <[email protected]> | 2024-02-19 02:50:43 +0300 | 
| commit | d96fa07134c06472bfee6718b5cfd1679196fc99 (patch) | |
| tree | 31ec344fa9d3ff8dc038692516b6438dfbdb8a2d /contrib/tools/python3/Modules/_multiprocessing | |
| parent | 452cf9e068aef7110e35e654c5d47eb80111ef89 (diff) | |
Sync contrib/tools/python3 layout with upstream
* Move src/ subdir contents to the top of the layout
* Rename self-written lib -> lib2 to avoid CaseFolding warning from the VCS
* Regenerate contrib/libs/python proxy-headers accordingly
4ccc62ac1511abcf0fed14ccade38e984e088f1e
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 00000000000..885cd5c2fff --- /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 00000000000..df2aa29cfe6 --- /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 00000000000..35347169bc1 --- /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 00000000000..8f9daa5c3de --- /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 00000000000..dfc2a8e0799 --- /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 00000000000..88c93fe3137 --- /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 00000000000..c7df82dfe2d --- /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  | 
