}
// Returns 0 on success or -1 if the buffer failed to grow.
-//
-// Steals a reference to item.
static int
RingBuf_Put(RingBuf *buf, PyObject *item)
{
// Buffer is full, grow it.
if (resize_ringbuf(buf, buf->items_cap * 2) < 0) {
PyErr_NoMemory();
- Py_DECREF(item);
return -1;
}
}
- buf->items[buf->put_idx] = item;
+ buf->items[buf->put_idx] = Py_NewRef(item);
buf->put_idx = (buf->put_idx + 1) % buf->items_cap;
buf->num_items++;
return 0;
{
HandoffData *data = (HandoffData*)arg;
PyObject **item = (PyObject**)park_arg;
- if (item == NULL) {
- // No threads were waiting
- data->handed_off = false;
- }
- else {
+ data->queue->has_threads_waiting = has_more_waiters;
+
+ data->handed_off = item != NULL;
+ if (data->handed_off) {
// There was at least one waiting thread, hand off the item
- *item = data->item;
- data->handed_off = true;
+ *item = Py_NewRef(data->item);
}
- data->queue->has_threads_waiting = has_more_waiters;
}
/*[clinic input]
int block, PyObject *timeout)
/*[clinic end generated code: output=4333136e88f90d8b input=a16dbb33363c0fa8]*/
{
- HandoffData data = {
- .handed_off = 0,
- .item = Py_NewRef(item),
- .queue = self,
- };
if (self->has_threads_waiting) {
+ HandoffData data = {
+ .handed_off = 0,
+ .item = item,
+ .queue = self,
+ };
// Try to hand the item off directly if there are threads waiting
_PyParkingLot_Unpark(&self->has_threads_waiting,
maybe_handoff_item, &data);
- }
- if (!data.handed_off) {
- if (RingBuf_Put(&self->buf, item) < 0) {
- return NULL;
+ if (data.handed_off) {
+ Py_RETURN_NONE;
}
}
+ if (RingBuf_Put(&self->buf, item) < 0) {
+ return NULL;
+ }
Py_RETURN_NONE;
}