17db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE_BUILTIN
27db96d56Sopenharmony_ci#  define Py_BUILD_CORE_MODULE 1
37db96d56Sopenharmony_ci#endif
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_ci#include "Python.h"
67db96d56Sopenharmony_ci#include "pycore_moduleobject.h"  // _PyModule_GetState()
77db96d56Sopenharmony_ci#include "structmember.h"         // PyMemberDef
87db96d56Sopenharmony_ci#include <stddef.h>               // offsetof()
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_citypedef struct {
117db96d56Sopenharmony_ci    PyTypeObject *SimpleQueueType;
127db96d56Sopenharmony_ci    PyObject *EmptyError;
137db96d56Sopenharmony_ci} simplequeue_state;
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_cistatic simplequeue_state *
167db96d56Sopenharmony_cisimplequeue_get_state(PyObject *module)
177db96d56Sopenharmony_ci{
187db96d56Sopenharmony_ci    simplequeue_state *state = _PyModule_GetState(module);
197db96d56Sopenharmony_ci    assert(state);
207db96d56Sopenharmony_ci    return state;
217db96d56Sopenharmony_ci}
227db96d56Sopenharmony_cistatic struct PyModuleDef queuemodule;
237db96d56Sopenharmony_ci#define simplequeue_get_state_by_type(type) \
247db96d56Sopenharmony_ci    (simplequeue_get_state(PyType_GetModuleByDef(type, &queuemodule)))
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_citypedef struct {
277db96d56Sopenharmony_ci    PyObject_HEAD
287db96d56Sopenharmony_ci    PyThread_type_lock lock;
297db96d56Sopenharmony_ci    int locked;
307db96d56Sopenharmony_ci    PyObject *lst;
317db96d56Sopenharmony_ci    Py_ssize_t lst_pos;
327db96d56Sopenharmony_ci    PyObject *weakreflist;
337db96d56Sopenharmony_ci} simplequeueobject;
347db96d56Sopenharmony_ci
357db96d56Sopenharmony_ci/*[clinic input]
367db96d56Sopenharmony_cimodule _queue
377db96d56Sopenharmony_ciclass _queue.SimpleQueue "simplequeueobject *" "simplequeue_get_state_by_type(type)->SimpleQueueType"
387db96d56Sopenharmony_ci[clinic start generated code]*/
397db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=0a4023fe4d198c8d]*/
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_cistatic int
427db96d56Sopenharmony_cisimplequeue_clear(simplequeueobject *self)
437db96d56Sopenharmony_ci{
447db96d56Sopenharmony_ci    Py_CLEAR(self->lst);
457db96d56Sopenharmony_ci    return 0;
467db96d56Sopenharmony_ci}
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_cistatic void
497db96d56Sopenharmony_cisimplequeue_dealloc(simplequeueobject *self)
507db96d56Sopenharmony_ci{
517db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(self);
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci    PyObject_GC_UnTrack(self);
547db96d56Sopenharmony_ci    if (self->lock != NULL) {
557db96d56Sopenharmony_ci        /* Unlock the lock so it's safe to free it */
567db96d56Sopenharmony_ci        if (self->locked > 0)
577db96d56Sopenharmony_ci            PyThread_release_lock(self->lock);
587db96d56Sopenharmony_ci        PyThread_free_lock(self->lock);
597db96d56Sopenharmony_ci    }
607db96d56Sopenharmony_ci    (void)simplequeue_clear(self);
617db96d56Sopenharmony_ci    if (self->weakreflist != NULL)
627db96d56Sopenharmony_ci        PyObject_ClearWeakRefs((PyObject *) self);
637db96d56Sopenharmony_ci    Py_TYPE(self)->tp_free(self);
647db96d56Sopenharmony_ci    Py_DECREF(tp);
657db96d56Sopenharmony_ci}
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_cistatic int
687db96d56Sopenharmony_cisimplequeue_traverse(simplequeueobject *self, visitproc visit, void *arg)
697db96d56Sopenharmony_ci{
707db96d56Sopenharmony_ci    Py_VISIT(self->lst);
717db96d56Sopenharmony_ci    Py_VISIT(Py_TYPE(self));
727db96d56Sopenharmony_ci    return 0;
737db96d56Sopenharmony_ci}
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ci/*[clinic input]
767db96d56Sopenharmony_ci@classmethod
777db96d56Sopenharmony_ci_queue.SimpleQueue.__new__ as simplequeue_new
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_ciSimple, unbounded, reentrant FIFO queue.
807db96d56Sopenharmony_ci[clinic start generated code]*/
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_cistatic PyObject *
837db96d56Sopenharmony_cisimplequeue_new_impl(PyTypeObject *type)
847db96d56Sopenharmony_ci/*[clinic end generated code: output=ba97740608ba31cd input=a0674a1643e3e2fb]*/
857db96d56Sopenharmony_ci{
867db96d56Sopenharmony_ci    simplequeueobject *self;
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ci    self = (simplequeueobject *) type->tp_alloc(type, 0);
897db96d56Sopenharmony_ci    if (self != NULL) {
907db96d56Sopenharmony_ci        self->weakreflist = NULL;
917db96d56Sopenharmony_ci        self->lst = PyList_New(0);
927db96d56Sopenharmony_ci        self->lock = PyThread_allocate_lock();
937db96d56Sopenharmony_ci        self->lst_pos = 0;
947db96d56Sopenharmony_ci        if (self->lock == NULL) {
957db96d56Sopenharmony_ci            Py_DECREF(self);
967db96d56Sopenharmony_ci            PyErr_SetString(PyExc_MemoryError, "can't allocate lock");
977db96d56Sopenharmony_ci            return NULL;
987db96d56Sopenharmony_ci        }
997db96d56Sopenharmony_ci        if (self->lst == NULL) {
1007db96d56Sopenharmony_ci            Py_DECREF(self);
1017db96d56Sopenharmony_ci            return NULL;
1027db96d56Sopenharmony_ci        }
1037db96d56Sopenharmony_ci    }
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_ci    return (PyObject *) self;
1067db96d56Sopenharmony_ci}
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_ci/*[clinic input]
1097db96d56Sopenharmony_ci_queue.SimpleQueue.put
1107db96d56Sopenharmony_ci    item: object
1117db96d56Sopenharmony_ci    block: bool = True
1127db96d56Sopenharmony_ci    timeout: object = None
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_ciPut the item on the queue.
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ciThe optional 'block' and 'timeout' arguments are ignored, as this method
1177db96d56Sopenharmony_cinever blocks.  They are provided for compatibility with the Queue class.
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci[clinic start generated code]*/
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_cistatic PyObject *
1227db96d56Sopenharmony_ci_queue_SimpleQueue_put_impl(simplequeueobject *self, PyObject *item,
1237db96d56Sopenharmony_ci                            int block, PyObject *timeout)
1247db96d56Sopenharmony_ci/*[clinic end generated code: output=4333136e88f90d8b input=6e601fa707a782d5]*/
1257db96d56Sopenharmony_ci{
1267db96d56Sopenharmony_ci    /* BEGIN GIL-protected critical section */
1277db96d56Sopenharmony_ci    if (PyList_Append(self->lst, item) < 0)
1287db96d56Sopenharmony_ci        return NULL;
1297db96d56Sopenharmony_ci    if (self->locked) {
1307db96d56Sopenharmony_ci        /* A get() may be waiting, wake it up */
1317db96d56Sopenharmony_ci        self->locked = 0;
1327db96d56Sopenharmony_ci        PyThread_release_lock(self->lock);
1337db96d56Sopenharmony_ci    }
1347db96d56Sopenharmony_ci    /* END GIL-protected critical section */
1357db96d56Sopenharmony_ci    Py_RETURN_NONE;
1367db96d56Sopenharmony_ci}
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci/*[clinic input]
1397db96d56Sopenharmony_ci_queue.SimpleQueue.put_nowait
1407db96d56Sopenharmony_ci    item: object
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_ciPut an item into the queue without blocking.
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_ciThis is exactly equivalent to `put(item)` and is only provided
1457db96d56Sopenharmony_cifor compatibility with the Queue class.
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ci[clinic start generated code]*/
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_cistatic PyObject *
1507db96d56Sopenharmony_ci_queue_SimpleQueue_put_nowait_impl(simplequeueobject *self, PyObject *item)
1517db96d56Sopenharmony_ci/*[clinic end generated code: output=0990536715efb1f1 input=36b1ea96756b2ece]*/
1527db96d56Sopenharmony_ci{
1537db96d56Sopenharmony_ci    return _queue_SimpleQueue_put_impl(self, item, 0, Py_None);
1547db96d56Sopenharmony_ci}
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_cistatic PyObject *
1577db96d56Sopenharmony_cisimplequeue_pop_item(simplequeueobject *self)
1587db96d56Sopenharmony_ci{
1597db96d56Sopenharmony_ci    Py_ssize_t count, n;
1607db96d56Sopenharmony_ci    PyObject *item;
1617db96d56Sopenharmony_ci
1627db96d56Sopenharmony_ci    n = PyList_GET_SIZE(self->lst);
1637db96d56Sopenharmony_ci    assert(self->lst_pos < n);
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci    item = PyList_GET_ITEM(self->lst, self->lst_pos);
1667db96d56Sopenharmony_ci    Py_INCREF(Py_None);
1677db96d56Sopenharmony_ci    PyList_SET_ITEM(self->lst, self->lst_pos, Py_None);
1687db96d56Sopenharmony_ci    self->lst_pos += 1;
1697db96d56Sopenharmony_ci    count = n - self->lst_pos;
1707db96d56Sopenharmony_ci    if (self->lst_pos > count) {
1717db96d56Sopenharmony_ci        /* The list is more than 50% empty, reclaim space at the beginning */
1727db96d56Sopenharmony_ci        if (PyList_SetSlice(self->lst, 0, self->lst_pos, NULL)) {
1737db96d56Sopenharmony_ci            /* Undo pop */
1747db96d56Sopenharmony_ci            self->lst_pos -= 1;
1757db96d56Sopenharmony_ci            PyList_SET_ITEM(self->lst, self->lst_pos, item);
1767db96d56Sopenharmony_ci            return NULL;
1777db96d56Sopenharmony_ci        }
1787db96d56Sopenharmony_ci        self->lst_pos = 0;
1797db96d56Sopenharmony_ci    }
1807db96d56Sopenharmony_ci    return item;
1817db96d56Sopenharmony_ci}
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ci/*[clinic input]
1847db96d56Sopenharmony_ci_queue.SimpleQueue.get
1857db96d56Sopenharmony_ci
1867db96d56Sopenharmony_ci    cls: defining_class
1877db96d56Sopenharmony_ci    /
1887db96d56Sopenharmony_ci    block: bool = True
1897db96d56Sopenharmony_ci    timeout as timeout_obj: object = None
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ciRemove and return an item from the queue.
1927db96d56Sopenharmony_ci
1937db96d56Sopenharmony_ciIf optional args 'block' is true and 'timeout' is None (the default),
1947db96d56Sopenharmony_ciblock if necessary until an item is available. If 'timeout' is
1957db96d56Sopenharmony_cia non-negative number, it blocks at most 'timeout' seconds and raises
1967db96d56Sopenharmony_cithe Empty exception if no item was available within that time.
1977db96d56Sopenharmony_ciOtherwise ('block' is false), return an item if one is immediately
1987db96d56Sopenharmony_ciavailable, else raise the Empty exception ('timeout' is ignored
1997db96d56Sopenharmony_ciin that case).
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci[clinic start generated code]*/
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_cistatic PyObject *
2047db96d56Sopenharmony_ci_queue_SimpleQueue_get_impl(simplequeueobject *self, PyTypeObject *cls,
2057db96d56Sopenharmony_ci                            int block, PyObject *timeout_obj)
2067db96d56Sopenharmony_ci/*[clinic end generated code: output=5c2cca914cd1e55b input=5b4047bfbc645ec1]*/
2077db96d56Sopenharmony_ci{
2087db96d56Sopenharmony_ci    _PyTime_t endtime = 0;
2097db96d56Sopenharmony_ci    _PyTime_t timeout;
2107db96d56Sopenharmony_ci    PyObject *item;
2117db96d56Sopenharmony_ci    PyLockStatus r;
2127db96d56Sopenharmony_ci    PY_TIMEOUT_T microseconds;
2137db96d56Sopenharmony_ci
2147db96d56Sopenharmony_ci    if (block == 0) {
2157db96d56Sopenharmony_ci        /* Non-blocking */
2167db96d56Sopenharmony_ci        microseconds = 0;
2177db96d56Sopenharmony_ci    }
2187db96d56Sopenharmony_ci    else if (timeout_obj != Py_None) {
2197db96d56Sopenharmony_ci        /* With timeout */
2207db96d56Sopenharmony_ci        if (_PyTime_FromSecondsObject(&timeout,
2217db96d56Sopenharmony_ci                                      timeout_obj, _PyTime_ROUND_CEILING) < 0) {
2227db96d56Sopenharmony_ci            return NULL;
2237db96d56Sopenharmony_ci        }
2247db96d56Sopenharmony_ci        if (timeout < 0) {
2257db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError,
2267db96d56Sopenharmony_ci                            "'timeout' must be a non-negative number");
2277db96d56Sopenharmony_ci            return NULL;
2287db96d56Sopenharmony_ci        }
2297db96d56Sopenharmony_ci        microseconds = _PyTime_AsMicroseconds(timeout,
2307db96d56Sopenharmony_ci                                              _PyTime_ROUND_CEILING);
2317db96d56Sopenharmony_ci        if (microseconds > PY_TIMEOUT_MAX) {
2327db96d56Sopenharmony_ci            PyErr_SetString(PyExc_OverflowError,
2337db96d56Sopenharmony_ci                            "timeout value is too large");
2347db96d56Sopenharmony_ci            return NULL;
2357db96d56Sopenharmony_ci        }
2367db96d56Sopenharmony_ci        endtime = _PyDeadline_Init(timeout);
2377db96d56Sopenharmony_ci    }
2387db96d56Sopenharmony_ci    else {
2397db96d56Sopenharmony_ci        /* Infinitely blocking */
2407db96d56Sopenharmony_ci        microseconds = -1;
2417db96d56Sopenharmony_ci    }
2427db96d56Sopenharmony_ci
2437db96d56Sopenharmony_ci    /* put() signals the queue to be non-empty by releasing the lock.
2447db96d56Sopenharmony_ci     * So we simply try to acquire the lock in a loop, until the condition
2457db96d56Sopenharmony_ci     * (queue non-empty) becomes true.
2467db96d56Sopenharmony_ci     */
2477db96d56Sopenharmony_ci    while (self->lst_pos == PyList_GET_SIZE(self->lst)) {
2487db96d56Sopenharmony_ci        /* First a simple non-blocking try without releasing the GIL */
2497db96d56Sopenharmony_ci        r = PyThread_acquire_lock_timed(self->lock, 0, 0);
2507db96d56Sopenharmony_ci        if (r == PY_LOCK_FAILURE && microseconds != 0) {
2517db96d56Sopenharmony_ci            Py_BEGIN_ALLOW_THREADS
2527db96d56Sopenharmony_ci            r = PyThread_acquire_lock_timed(self->lock, microseconds, 1);
2537db96d56Sopenharmony_ci            Py_END_ALLOW_THREADS
2547db96d56Sopenharmony_ci        }
2557db96d56Sopenharmony_ci
2567db96d56Sopenharmony_ci        if (r == PY_LOCK_INTR && Py_MakePendingCalls() < 0) {
2577db96d56Sopenharmony_ci            return NULL;
2587db96d56Sopenharmony_ci        }
2597db96d56Sopenharmony_ci        if (r == PY_LOCK_FAILURE) {
2607db96d56Sopenharmony_ci            PyObject *module = PyType_GetModule(cls);
2617db96d56Sopenharmony_ci            simplequeue_state *state = simplequeue_get_state(module);
2627db96d56Sopenharmony_ci            /* Timed out */
2637db96d56Sopenharmony_ci            PyErr_SetNone(state->EmptyError);
2647db96d56Sopenharmony_ci            return NULL;
2657db96d56Sopenharmony_ci        }
2667db96d56Sopenharmony_ci        self->locked = 1;
2677db96d56Sopenharmony_ci
2687db96d56Sopenharmony_ci        /* Adjust timeout for next iteration (if any) */
2697db96d56Sopenharmony_ci        if (microseconds > 0) {
2707db96d56Sopenharmony_ci            timeout = _PyDeadline_Get(endtime);
2717db96d56Sopenharmony_ci            microseconds = _PyTime_AsMicroseconds(timeout,
2727db96d56Sopenharmony_ci                                                  _PyTime_ROUND_CEILING);
2737db96d56Sopenharmony_ci        }
2747db96d56Sopenharmony_ci    }
2757db96d56Sopenharmony_ci
2767db96d56Sopenharmony_ci    /* BEGIN GIL-protected critical section */
2777db96d56Sopenharmony_ci    assert(self->lst_pos < PyList_GET_SIZE(self->lst));
2787db96d56Sopenharmony_ci    item = simplequeue_pop_item(self);
2797db96d56Sopenharmony_ci    if (self->locked) {
2807db96d56Sopenharmony_ci        PyThread_release_lock(self->lock);
2817db96d56Sopenharmony_ci        self->locked = 0;
2827db96d56Sopenharmony_ci    }
2837db96d56Sopenharmony_ci    /* END GIL-protected critical section */
2847db96d56Sopenharmony_ci
2857db96d56Sopenharmony_ci    return item;
2867db96d56Sopenharmony_ci}
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci/*[clinic input]
2897db96d56Sopenharmony_ci_queue.SimpleQueue.get_nowait
2907db96d56Sopenharmony_ci
2917db96d56Sopenharmony_ci    cls: defining_class
2927db96d56Sopenharmony_ci    /
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ciRemove and return an item from the queue without blocking.
2957db96d56Sopenharmony_ci
2967db96d56Sopenharmony_ciOnly get an item if one is immediately available. Otherwise
2977db96d56Sopenharmony_ciraise the Empty exception.
2987db96d56Sopenharmony_ci[clinic start generated code]*/
2997db96d56Sopenharmony_ci
3007db96d56Sopenharmony_cistatic PyObject *
3017db96d56Sopenharmony_ci_queue_SimpleQueue_get_nowait_impl(simplequeueobject *self,
3027db96d56Sopenharmony_ci                                   PyTypeObject *cls)
3037db96d56Sopenharmony_ci/*[clinic end generated code: output=620c58e2750f8b8a input=842f732bf04216d3]*/
3047db96d56Sopenharmony_ci{
3057db96d56Sopenharmony_ci    return _queue_SimpleQueue_get_impl(self, cls, 0, Py_None);
3067db96d56Sopenharmony_ci}
3077db96d56Sopenharmony_ci
3087db96d56Sopenharmony_ci/*[clinic input]
3097db96d56Sopenharmony_ci_queue.SimpleQueue.empty -> bool
3107db96d56Sopenharmony_ci
3117db96d56Sopenharmony_ciReturn True if the queue is empty, False otherwise (not reliable!).
3127db96d56Sopenharmony_ci[clinic start generated code]*/
3137db96d56Sopenharmony_ci
3147db96d56Sopenharmony_cistatic int
3157db96d56Sopenharmony_ci_queue_SimpleQueue_empty_impl(simplequeueobject *self)
3167db96d56Sopenharmony_ci/*[clinic end generated code: output=1a02a1b87c0ef838 input=1a98431c45fd66f9]*/
3177db96d56Sopenharmony_ci{
3187db96d56Sopenharmony_ci    return self->lst_pos == PyList_GET_SIZE(self->lst);
3197db96d56Sopenharmony_ci}
3207db96d56Sopenharmony_ci
3217db96d56Sopenharmony_ci/*[clinic input]
3227db96d56Sopenharmony_ci_queue.SimpleQueue.qsize -> Py_ssize_t
3237db96d56Sopenharmony_ci
3247db96d56Sopenharmony_ciReturn the approximate size of the queue (not reliable!).
3257db96d56Sopenharmony_ci[clinic start generated code]*/
3267db96d56Sopenharmony_ci
3277db96d56Sopenharmony_cistatic Py_ssize_t
3287db96d56Sopenharmony_ci_queue_SimpleQueue_qsize_impl(simplequeueobject *self)
3297db96d56Sopenharmony_ci/*[clinic end generated code: output=f9dcd9d0a90e121e input=7a74852b407868a1]*/
3307db96d56Sopenharmony_ci{
3317db96d56Sopenharmony_ci    return PyList_GET_SIZE(self->lst) - self->lst_pos;
3327db96d56Sopenharmony_ci}
3337db96d56Sopenharmony_ci
3347db96d56Sopenharmony_cistatic int
3357db96d56Sopenharmony_ciqueue_traverse(PyObject *m, visitproc visit, void *arg)
3367db96d56Sopenharmony_ci{
3377db96d56Sopenharmony_ci    simplequeue_state *state = simplequeue_get_state(m);
3387db96d56Sopenharmony_ci    Py_VISIT(state->SimpleQueueType);
3397db96d56Sopenharmony_ci    Py_VISIT(state->EmptyError);
3407db96d56Sopenharmony_ci    return 0;
3417db96d56Sopenharmony_ci}
3427db96d56Sopenharmony_ci
3437db96d56Sopenharmony_cistatic int
3447db96d56Sopenharmony_ciqueue_clear(PyObject *m)
3457db96d56Sopenharmony_ci{
3467db96d56Sopenharmony_ci    simplequeue_state *state = simplequeue_get_state(m);
3477db96d56Sopenharmony_ci    Py_CLEAR(state->SimpleQueueType);
3487db96d56Sopenharmony_ci    Py_CLEAR(state->EmptyError);
3497db96d56Sopenharmony_ci    return 0;
3507db96d56Sopenharmony_ci}
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_cistatic void
3537db96d56Sopenharmony_ciqueue_free(void *m)
3547db96d56Sopenharmony_ci{
3557db96d56Sopenharmony_ci    queue_clear((PyObject *)m);
3567db96d56Sopenharmony_ci}
3577db96d56Sopenharmony_ci
3587db96d56Sopenharmony_ci#include "clinic/_queuemodule.c.h"
3597db96d56Sopenharmony_ci
3607db96d56Sopenharmony_ci
3617db96d56Sopenharmony_cistatic PyMethodDef simplequeue_methods[] = {
3627db96d56Sopenharmony_ci    _QUEUE_SIMPLEQUEUE_EMPTY_METHODDEF
3637db96d56Sopenharmony_ci    _QUEUE_SIMPLEQUEUE_GET_METHODDEF
3647db96d56Sopenharmony_ci    _QUEUE_SIMPLEQUEUE_GET_NOWAIT_METHODDEF
3657db96d56Sopenharmony_ci    _QUEUE_SIMPLEQUEUE_PUT_METHODDEF
3667db96d56Sopenharmony_ci    _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF
3677db96d56Sopenharmony_ci    _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF
3687db96d56Sopenharmony_ci    {"__class_getitem__",    Py_GenericAlias,
3697db96d56Sopenharmony_ci    METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
3707db96d56Sopenharmony_ci    {NULL,           NULL}              /* sentinel */
3717db96d56Sopenharmony_ci};
3727db96d56Sopenharmony_ci
3737db96d56Sopenharmony_cistatic struct PyMemberDef simplequeue_members[] = {
3747db96d56Sopenharmony_ci    {"__weaklistoffset__", T_PYSSIZET, offsetof(simplequeueobject, weakreflist), READONLY},
3757db96d56Sopenharmony_ci    {NULL},
3767db96d56Sopenharmony_ci};
3777db96d56Sopenharmony_ci
3787db96d56Sopenharmony_cistatic PyType_Slot simplequeue_slots[] = {
3797db96d56Sopenharmony_ci    {Py_tp_dealloc, simplequeue_dealloc},
3807db96d56Sopenharmony_ci    {Py_tp_doc, (void *)simplequeue_new__doc__},
3817db96d56Sopenharmony_ci    {Py_tp_traverse, simplequeue_traverse},
3827db96d56Sopenharmony_ci    {Py_tp_clear, simplequeue_clear},
3837db96d56Sopenharmony_ci    {Py_tp_members, simplequeue_members},
3847db96d56Sopenharmony_ci    {Py_tp_methods, simplequeue_methods},
3857db96d56Sopenharmony_ci    {Py_tp_new, simplequeue_new},
3867db96d56Sopenharmony_ci    {0, NULL},
3877db96d56Sopenharmony_ci};
3887db96d56Sopenharmony_ci
3897db96d56Sopenharmony_cistatic PyType_Spec simplequeue_spec = {
3907db96d56Sopenharmony_ci    .name = "_queue.SimpleQueue",
3917db96d56Sopenharmony_ci    .basicsize = sizeof(simplequeueobject),
3927db96d56Sopenharmony_ci    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
3937db96d56Sopenharmony_ci              Py_TPFLAGS_IMMUTABLETYPE),
3947db96d56Sopenharmony_ci    .slots = simplequeue_slots,
3957db96d56Sopenharmony_ci};
3967db96d56Sopenharmony_ci
3977db96d56Sopenharmony_ci
3987db96d56Sopenharmony_ci/* Initialization function */
3997db96d56Sopenharmony_ci
4007db96d56Sopenharmony_ciPyDoc_STRVAR(queue_module_doc,
4017db96d56Sopenharmony_ci"C implementation of the Python queue module.\n\
4027db96d56Sopenharmony_ciThis module is an implementation detail, please do not use it directly.");
4037db96d56Sopenharmony_ci
4047db96d56Sopenharmony_cistatic int
4057db96d56Sopenharmony_ciqueuemodule_exec(PyObject *module)
4067db96d56Sopenharmony_ci{
4077db96d56Sopenharmony_ci    simplequeue_state *state = simplequeue_get_state(module);
4087db96d56Sopenharmony_ci
4097db96d56Sopenharmony_ci    state->EmptyError = PyErr_NewExceptionWithDoc(
4107db96d56Sopenharmony_ci        "_queue.Empty",
4117db96d56Sopenharmony_ci        "Exception raised by Queue.get(block=0)/get_nowait().",
4127db96d56Sopenharmony_ci        NULL, NULL);
4137db96d56Sopenharmony_ci    if (state->EmptyError == NULL) {
4147db96d56Sopenharmony_ci        return -1;
4157db96d56Sopenharmony_ci    }
4167db96d56Sopenharmony_ci    if (PyModule_AddObjectRef(module, "Empty", state->EmptyError) < 0) {
4177db96d56Sopenharmony_ci        return -1;
4187db96d56Sopenharmony_ci    }
4197db96d56Sopenharmony_ci
4207db96d56Sopenharmony_ci    state->SimpleQueueType = (PyTypeObject *)PyType_FromModuleAndSpec(
4217db96d56Sopenharmony_ci        module, &simplequeue_spec, NULL);
4227db96d56Sopenharmony_ci    if (state->SimpleQueueType == NULL) {
4237db96d56Sopenharmony_ci        return -1;
4247db96d56Sopenharmony_ci    }
4257db96d56Sopenharmony_ci    if (PyModule_AddType(module, state->SimpleQueueType) < 0) {
4267db96d56Sopenharmony_ci        return -1;
4277db96d56Sopenharmony_ci    }
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_ci    return 0;
4307db96d56Sopenharmony_ci}
4317db96d56Sopenharmony_ci
4327db96d56Sopenharmony_cistatic PyModuleDef_Slot queuemodule_slots[] = {
4337db96d56Sopenharmony_ci    {Py_mod_exec, queuemodule_exec},
4347db96d56Sopenharmony_ci    {0, NULL}
4357db96d56Sopenharmony_ci};
4367db96d56Sopenharmony_ci
4377db96d56Sopenharmony_ci
4387db96d56Sopenharmony_cistatic struct PyModuleDef queuemodule = {
4397db96d56Sopenharmony_ci    .m_base = PyModuleDef_HEAD_INIT,
4407db96d56Sopenharmony_ci    .m_name = "_queue",
4417db96d56Sopenharmony_ci    .m_doc = queue_module_doc,
4427db96d56Sopenharmony_ci    .m_size = sizeof(simplequeue_state),
4437db96d56Sopenharmony_ci    .m_slots = queuemodule_slots,
4447db96d56Sopenharmony_ci    .m_traverse = queue_traverse,
4457db96d56Sopenharmony_ci    .m_clear = queue_clear,
4467db96d56Sopenharmony_ci    .m_free = queue_free,
4477db96d56Sopenharmony_ci};
4487db96d56Sopenharmony_ci
4497db96d56Sopenharmony_ci
4507db96d56Sopenharmony_ciPyMODINIT_FUNC
4517db96d56Sopenharmony_ciPyInit__queue(void)
4527db96d56Sopenharmony_ci{
4537db96d56Sopenharmony_ci   return PyModuleDef_Init(&queuemodule);
4547db96d56Sopenharmony_ci}
455