You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

130 lines
4.7 KiB

#ifndef LL_QUEUE_H
#define LL_QUEUE_H
#include <stddef.h>
#include <stdint.h>
#include "memory_pool.h"
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#else
#include <pthread.h>
#endif
#define QUEUE_DEBUG 1
//#define QUEUE_THREAD_CHECK 1
// Forward declaration
struct ll_queue;
/**
* @struct ll_entry
* @brief Элемент очереди (переменного размера).
*
* Память: [struct ll_entry + data[size]].
* Индекс для поиска (произвольной длины) хранится в data[index_offset].
* Хеш (uint64_t) вычисляется по последним 8 байтам индекса.
*/
struct ll_entry {
char* name;
struct ll_entry* next;
struct ll_entry* prev;
uint16_t size; ///< Размер data[]
uint16_t len;
uint16_t memlen;
uint16_t int_len;
uint8_t* dgram;
void (*dgram_free_fn)(uint8_t* data);
struct memory_pool* dgram_pool;
struct memory_pool* pool;
/* === НОВОЕ: поддержка индекса произвольной длины === */
uint16_t index_offset; ///< Смещение индекса в data[]
uint16_t index_size; ///< Длина индекса (0 = без индекса)
uint64_t index_hash; ///< Хеш по последним 8 байтам индекса
struct ll_entry* hash_next;
uint8_t data[0]; ///< Гибкий массив
};
/* ... (остальные typedef'ы без изменений) ... */
struct ll_queue {
char* name;
struct ll_entry* head;
struct ll_entry* tail;
int count;
size_t total_bytes;
int size_limit;
queue_callback_fn callback;
void* callback_arg;
int callback_suspended;
void* resume_timeout_id;
struct UASYNC* ua;
struct queue_waiter waiter;
struct ll_entry** hash_table;
size_t hash_size;
#ifdef QUEUE_THREAD_CHECK
#ifdef _WIN32
DWORD owner_thread;
#else
pthread_t owner_thread;
#endif
#endif
};
/* ==================== Создание / уничтожение ==================== */
struct ll_queue* queue_new(struct UASYNC* ua, size_t hash_size, char* name);
void queue_free(struct ll_queue* q);
/* ==================== Конфигурация ==================== */
void queue_set_size_limit(struct ll_queue* q, int lim);
/* ==================== Автозабор элементов ==================== */
void queue_set_callback(struct ll_queue* q, queue_callback_fn cbk_fn, void* arg);
void queue_resume_callback(struct ll_queue* q);
/* ==================== Пороговое ожидание ==================== */
struct queue_waiter* queue_wait_threshold(struct ll_queue* q, int max_packets, size_t max_bytes,
queue_threshold_callback_fn callback, void* arg);
void queue_cancel_wait(struct ll_queue* q, struct queue_waiter* waiter);
/* ==================== Работа с данными ==================== */
/* Упрощённая версия (без индекса) */
int queue_data_put(struct ll_queue* q, struct ll_entry* entry);
int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry);
/* Версия с хешем по индексу произвольной длины */
int queue_data_put_with_index(struct ll_queue* q, struct ll_entry* entry,
uint16_t index_offset, uint16_t index_size);
int queue_data_put_first_with_index(struct ll_queue* q, struct ll_entry* entry,
uint16_t index_offset, uint16_t index_size);
struct ll_entry* queue_data_get(struct ll_queue* q);
int queue_entry_count(struct ll_queue* q);
/* ==================== Управление памятью ==================== */
struct ll_entry* ll_alloc_lldgram(uint16_t len);
struct ll_entry* queue_entry_new(size_t data_size);
struct ll_entry* queue_entry_new_from_pool(struct memory_pool* pool);
void queue_entry_free(struct ll_entry* entry);
void queue_dgram_free(struct ll_entry* entry);
/* ==================== Поиск и удаление ==================== */
/**
* @brief Поиск по индексу произвольной длины.
* @note Хеш вычисляется по последним 8 байтам индекса.
*/
struct ll_entry* queue_find_data_by_index(struct ll_queue* q,
const void* index_key,
uint16_t index_size);
int queue_remove_data(struct ll_queue* q, struct ll_entry* entry);
/* ==================== Утилиты ==================== */
static inline size_t queue_total_bytes(struct ll_queue* q) {
return q ? q->total_bytes : 0;
}
int queue_check_consistency(struct ll_queue* q);
#endif // LL_QUEUE_H