stcp: ed25519 pubkey exchange in handshake, fix instance destroy segfault, fix chat_tcp_test
- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll - stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close - utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP), add deferred drain in both Phase J and L - stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39, exchange ed25519_pubkey in both handshake directions - etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb - chat_sync.c: fix lk->conn NULL dereference for TCP links - test_stcp.c: update stcp_server_create/stcp_client_connect callsites - tools/chat_tcp_test: change transport udp→tcp
This commit is contained in:
1 parent
a3783b5f55
commit
38c9f229bc
1272 files changed
+968388
-1
No files matched your search
@@ -0,0 +1,57 @@
|
||||
# memory_pool (Object Pool Allocator)
|
||||
|
||||
## 1. Назначение
|
||||
|
||||
Быстрый аллокатор объектов фиксированного размера. Вместо постоянных `malloc`/`free` хранит до 64 освобождённых объектов в linked list для повторного использования. Применяется для hot-path объектов, которые часто создаются и уничтожаются: пакеты, фрагменты, ACK-пакеты, структуры маршрутизации, TCP-сегменты lwIP и т.д.
|
||||
|
||||
Встроенная защита:
|
||||
- **Buffer overflow** — канарейка `0xDEADBEAF` после пользовательских данных проверяется при освобождении. При повреждении — бесконечный цикл (hang) для отладки.
|
||||
- **Double free** — однобайтный счётчик в метаданных; повторное освобождение детектируется и вызывает hang.
|
||||
- Вся диагностика пишется через `DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, ...)`.
|
||||
|
||||
Не потокобезопасен — каждый пул используется из одного потока (обычно в рамках одного u_async event loop).
|
||||
|
||||
## 2. Как пользоваться
|
||||
|
||||
```c
|
||||
#include "memory_pool.h"
|
||||
|
||||
// 1. Создать пул (обычно в init-функции инстанса):
|
||||
struct memory_pool* pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM), "pkt_pool");
|
||||
|
||||
// 2. Выделить объект (если есть свободный — вернёт из пула, иначе u_calloc):
|
||||
struct ETCP_DGRAM* dgram = memory_pool_alloc(pkt_pool);
|
||||
|
||||
// 3. Освободить объект (возвращается в пул, если там меньше 64 блоков):
|
||||
memory_pool_free(pkt_pool, dgram);
|
||||
|
||||
// 4. Получить статистику:
|
||||
size_t allocs, reuse;
|
||||
memory_pool_get_stats(pkt_pool, &allocs, &reuse);
|
||||
// reuse много → эффективно; reuse мало → пул слишком мал для нагрузки
|
||||
|
||||
// 5. Проверить, в пуле ли объект (0 — не в пуле, 1 — в пуле):
|
||||
if (memory_pool_is_freed(pkt_pool, obj)) { /* уже освобождён */ }
|
||||
|
||||
// 6. Уничтожить пул (при shutdown):
|
||||
memory_pool_destroy(pkt_pool);
|
||||
// реально освобождает все кэшированные блоки через u_free() и сам пул.
|
||||
```
|
||||
|
||||
**Важно:**
|
||||
- Если объекты пула используются как элементы `ll_queue`, в `object_size` нужно закладывать `sizeof(struct ll_entry)`. Например: `memory_pool_init(sizeof(struct ll_entry) + sizeof(struct dummynet_pkt), "pkt_pool")`.
|
||||
- `memory_pool_alloc` обнуляет объект перед возвратом (защита от утечки старых данных).
|
||||
- При заполнении пула (64 свободных блока) лишние `memory_pool_free` реально вызывают `u_free` — блок не кэшируется.
|
||||
- `memory_pool_destroy` проходит по всем свободным блокам и вызывает `u_free` для каждого, затем освобождает сам `struct memory_pool`.
|
||||
|
||||
## 3. API
|
||||
|
||||
| Функция/макрос | Описание |
|
||||
|---|---|
|
||||
| `memory_pool_init(object_size, name)` | Создаёт пул для объектов заданного размера. `name` — для диагностики. |
|
||||
| `memory_pool_alloc(pool)` | Выделяет объект: из кэша (если есть) или через `u_calloc`. Обнуляет перед возвратом. |
|
||||
| `memory_pool_free(pool, obj)` | Возвращает объект в пул (до 64) или вызывает `u_free`. Проверяет canary и double-free. |
|
||||
| `memory_pool_destroy(pool)` | Уничтожает пул: освобождает все кэшированные блоки и сам пул. |
|
||||
| `memory_pool_get_stats(pool, &allocs, &reuse)` | Статистика: общее число аллокаций и число повторных использований из кэша. |
|
||||
| `memory_pool_get_total_free_blocks()` | Глобальный счётчик свободных блоков во всех пулах (для диагностики). |
|
||||
| `memory_pool_is_freed(pool, obj)` | Проверяет, находится ли объект в свободном списке пула (уже освобождён). |
|
||||
Reference in new issue
Block a user