Add allocation-free queue discard for terminal stream resets
This commit is contained in:
1 parent
0989eff73d
commit
466a56b499
2 files changed
+32
-14
No files matched your search
+26
-14
@@ -129,15 +129,7 @@ struct ll_entry* ll_alloc_lldgram(uint16_t len) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
void queue_free(struct ll_queue* q) {
|
||||
if (!q) return;
|
||||
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "queue_free: freeing queue %p, head=%p, tail=%p, count=%d",
|
||||
q, q->head, q->tail, q->count);
|
||||
|
||||
// ВАЖНО: Не освобождаем элементы в очереди - они должны быть извлечены отдельно
|
||||
// Это упрощает архитектуру и предотвращает double-u_free
|
||||
|
||||
static void queue_cancel_notifications(struct ll_queue* q) {
|
||||
while (q->deferred_waiters) queue_waiter_cancel(q, q->deferred_waiters);
|
||||
// Освободить список waiters (сбросить handle->internal, отменить отложенные вызовы)
|
||||
struct queue_waiter* w = q->waiter_head;
|
||||
@@ -150,11 +142,6 @@ void queue_free(struct ll_queue* q) {
|
||||
q->waiter_head = NULL;
|
||||
q->waiter_tail = NULL;
|
||||
|
||||
// Освободить хеш-таблицу
|
||||
if (q->hash_table) {
|
||||
u_free(q->hash_table);
|
||||
}
|
||||
|
||||
// Отменить отложенное возобновление
|
||||
if (q->resume_timeout_id) {
|
||||
uasync_call_soon_cancel(q->ua, q->resume_timeout_id);
|
||||
@@ -170,6 +157,31 @@ void queue_free(struct ll_queue* q) {
|
||||
q->on_get_arg = NULL;
|
||||
if (q->on_get_call_soon_id) uasync_call_soon_cancel(q->ua, q->on_get_call_soon_id);
|
||||
q->on_get_call_soon_id = NULL; q->on_get_pending = 0;
|
||||
q->callback_suspended = 1;
|
||||
}
|
||||
|
||||
void queue_clear(struct ll_queue* q) {
|
||||
if (!q) return;
|
||||
#ifdef QUEUE_THREAD_CHECK
|
||||
queue_check_thread(q);
|
||||
#endif
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "[%s] discard queue: packets=%d bytes=%zu", q->name, q->count, q->total_bytes);
|
||||
queue_cancel_notifications(q);
|
||||
struct ll_entry* entry = q->head;
|
||||
q->head = q->tail = NULL; q->count = 0; q->total_bytes = 0;
|
||||
if (q->hash_table) memset(q->hash_table, 0, q->hash_size * sizeof(*q->hash_table));
|
||||
while (entry) {
|
||||
struct ll_entry* next = entry->next;
|
||||
entry->owner = NULL; entry->next = entry->prev = entry->hash_next = NULL;
|
||||
queue_dgram_free(entry); queue_entry_free(entry); entry = next;
|
||||
}
|
||||
}
|
||||
|
||||
void queue_free(struct ll_queue* q) {
|
||||
if (!q) return;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "queue_free: freeing queue %p, head=%p, count=%d", (void*)q, (void*)q->head, q->count);
|
||||
queue_cancel_notifications(q);
|
||||
if (q->hash_table) u_free(q->hash_table);
|
||||
if (q->head) DEBUG_WARN(DEBUG_CATEGORY_SYS, "[%s] freeing nonempty queue: count=%d; entries remain caller-owned", q->name, q->count);
|
||||
for (struct ll_entry* e = q->head; e; e = e->next) e->owner = NULL;
|
||||
|
||||
|
||||
Reference in new issue
Block a user