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:
1 parent
331d43c6f7
commit
2a259191b9
3 files changed
+35
-7
No files matched your search
+23
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user