feat: queue_set_waiter_defer — immediate or call_soon callback mode

queue_waiter_handle stores defer_q/cb/arg, no extra malloc.
queue_set_waiter_defer(q, 1) enables call_soon dispatch for waiter callbacks.
bbr_integration uses it instead of manual send_waiter_cb wrapper.
This commit is contained in:
Evgeny committed 2026-06-03 02:18:46 +03:00
1 parent 331d43c6f7
commit 2a259191b9
3 files changed
+35 -7

No files matched your search

+23 -2
View File
@@ -60,6 +60,7 @@ struct ll_queue* queue_new(struct UASYNC* ua, size_t hash_size, uint16_t index_o
q->size_limit = -1; // Без ограничения по умолчанию
q->threshold_max_packets = 0; // По умолчанию: ждать пустой очереди
q->threshold_max_bytes = 0; // По умолчанию: не проверять байты
q->waiter_defer = 0;
q->hash_size = hash_size;
q->index_offset = index_offset;
q->index_size = index_size;
@@ -277,6 +278,21 @@ static uint32_t make_hash(const void* data, uint16_t len) {// алгоритм F
return hash;
}
static void waiter_defer_cb(void* arg) {
struct queue_waiter_handle* h = (struct queue_waiter_handle*)arg;
h->defer_cb(h->defer_q, h->defer_arg);
}
inline void queue_waiter_call(struct ll_queue* q, queue_threshold_callback_fn cb, void* arg,
struct queue_waiter_handle* h) {
if (q->waiter_defer) {
h->defer_q = q; h->defer_cb = cb; h->defer_arg = arg;
uasync_call_soon(q->ua, h, waiter_defer_cb);
} else {
cb(q, arg);
}
}
// Проверить и запустить первый ожидающий коллбэк (FIFO / round-robin)
static void check_waiters(struct ll_queue* q) {
if (!q || !q->waiter_head) return;
@@ -299,7 +315,7 @@ static void check_waiters(struct ll_queue* q) {
if (cb) {
DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "check_waiters: waking head waiter, count=%d<=%d, bytes=%zu<=%zu",
q->count, q->threshold_max_packets, q->total_bytes, q->threshold_max_bytes);
cb(q, arg);
queue_waiter_call(q, cb, arg, h);
}
}
@@ -592,6 +608,11 @@ void queue_set_threshold(struct ll_queue* q, int max_packets, size_t max_bytes)
q->threshold_max_bytes = max_bytes;
}
void queue_set_waiter_defer(struct ll_queue* q, int enable) {
if (!q) return;
q->waiter_defer = enable;
}
int queue_waiter_wait(struct ll_queue* q, struct queue_waiter_handle* h,
queue_threshold_callback_fn callback, void* arg) {
if (!q || !h) return -1;
@@ -600,7 +621,7 @@ int queue_waiter_wait(struct ll_queue* q, struct queue_waiter_handle* h,
if (q->count <= q->threshold_max_packets
&& (q->threshold_max_bytes == 0 || q->total_bytes <= q->threshold_max_bytes)) {
callback(q, arg);
queue_waiter_call(q, callback, arg, h);
return 1;
}