ll_queue: отложенный первый запуск автозабора (callback_defer) + тест
queue_set_callback_defer(q, 1) переносит первый запуск callback из queue_data_put* в uasync_call_soon (очистка стека производителя). Повторные запуски (queue_resume_callback) и так всегда deferred.
This commit is contained in:
1 parent
cc2d2b5f78
commit
8aaac45020
4 files changed
+65
-12
No files matched your search
+22
-12
@@ -194,6 +194,19 @@ void queue_resume_callback(struct ll_queue* q) {
|
||||
}
|
||||
}
|
||||
|
||||
// Общий запуск коллбэка автозабора: immediate (default) или deferred через uasync_call_soon.
|
||||
// Deferred-режим очищает стек производителя перед обработкой первого элемента.
|
||||
static void queue_trigger_callback(struct ll_queue* q) {
|
||||
if (!q->head || q->callback_suspended || !q->callback) return;
|
||||
|
||||
if (q->callback_defer) {
|
||||
if (!q->resume_timeout_id)
|
||||
q->resume_timeout_id = uasync_call_soon(q->ua, q, queue_resume_timeout_cb);
|
||||
} else {
|
||||
q->callback(q, q->callback_arg);
|
||||
}
|
||||
}
|
||||
|
||||
void queue_set_size_limit(struct ll_queue* q, int lim) {
|
||||
if (!q) return;
|
||||
q->size_limit = lim;
|
||||
@@ -384,9 +397,7 @@ int queue_data_put(struct ll_queue* q, struct ll_entry* entry) {
|
||||
|
||||
// НЕ вызываем add_to_hash
|
||||
|
||||
if (q->count == 1 && !q->callback_suspended && q->callback) {
|
||||
q->callback(q, q->callback_arg);
|
||||
}
|
||||
if (q->count == 1) queue_trigger_callback(q);
|
||||
|
||||
#ifdef QUEUE_DEBUG
|
||||
queue_check_consistency(q);
|
||||
@@ -433,9 +444,7 @@ int queue_data_put_with_index(struct ll_queue* q, struct ll_entry* entry) {
|
||||
|
||||
add_to_hash(q, entry);
|
||||
|
||||
if (q->count == 1 && !q->callback_suspended && q->callback) {
|
||||
q->callback(q, q->callback_arg);
|
||||
}
|
||||
if (q->count == 1) queue_trigger_callback(q);
|
||||
|
||||
#ifdef QUEUE_DEBUG
|
||||
queue_check_consistency(q);
|
||||
@@ -471,9 +480,7 @@ int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry) {
|
||||
entry->int_len = entry->len;
|
||||
q->total_bytes += entry->int_len;
|
||||
|
||||
if (q->count == 1 && !q->callback_suspended && q->callback) {
|
||||
q->callback(q, q->callback_arg);
|
||||
}
|
||||
if (q->count == 1) queue_trigger_callback(q);
|
||||
|
||||
#ifdef QUEUE_DEBUG
|
||||
queue_check_consistency(q);
|
||||
@@ -520,9 +527,7 @@ int queue_data_put_first_with_index(struct ll_queue* q, struct ll_entry* entry)
|
||||
|
||||
add_to_hash(q, entry);
|
||||
|
||||
if (q->count == 1 && !q->callback_suspended && q->callback) {
|
||||
q->callback(q, q->callback_arg);
|
||||
}
|
||||
if (q->count == 1) queue_trigger_callback(q);
|
||||
|
||||
#ifdef QUEUE_DEBUG
|
||||
queue_check_consistency(q);
|
||||
@@ -647,6 +652,11 @@ void queue_set_waiter_defer(struct ll_queue* q, int enable) {
|
||||
q->waiter_defer = enable;
|
||||
}
|
||||
|
||||
void queue_set_callback_defer(struct ll_queue* q, int enable) {
|
||||
if (!q) return;
|
||||
q->callback_defer = enable;
|
||||
}
|
||||
|
||||
void queue_set_empty_callback(struct ll_queue* q, queue_callback_fn cbk_fn, void* arg) {
|
||||
if (!q) return;
|
||||
void* old = q->empty_call_soon_id;
|
||||
|
||||
Reference in new issue
Block a user