проверки thread в ll_queue
This commit is contained in:
1 parent
1811764f6d
commit
5dfd1ea5fe
5 files changed
+85
-6
No files matched your search
@@ -8,6 +8,41 @@
|
||||
#include "debug_config.h"
|
||||
#include "mem.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
// ==================== Thread safety check ====================
|
||||
#ifdef QUEUE_THREAD_CHECK
|
||||
static inline void queue_check_thread(struct ll_queue* q) {
|
||||
if (!q) return;
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD current = GetCurrentThreadId();
|
||||
if (q->owner_thread != current) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': thread mismatch! owner=%lu current=%lu",
|
||||
q->name ? q->name : "unknown",
|
||||
(unsigned long)q->owner_thread,
|
||||
(unsigned long)current);
|
||||
printf("ERROR: Queue '%s' accessed from wrong thread!\n", q->name ? q->name : "unknown");
|
||||
abort();
|
||||
}
|
||||
#else
|
||||
pthread_t current = pthread_self();
|
||||
if (!pthread_equal(q->owner_thread, current)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': thread mismatch! owner=%lu current=%lu",
|
||||
q->name ? q->name : "unknown",
|
||||
(unsigned long)q->owner_thread,
|
||||
(unsigned long)current);
|
||||
printf("ERROR: Queue '%s' accessed from wrong thread!\n", q->name ? q->name : "unknown");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Предварительные объявления внутренних функций
|
||||
static void queue_resume_timeout_cb(void* arg);
|
||||
static void check_waiters(struct ll_queue* q);
|
||||
@@ -27,6 +62,14 @@ struct ll_queue* queue_new(struct UASYNC* ua, size_t hash_size, char* name) {
|
||||
q->size_limit = -1; // Без ограничения по умолчанию
|
||||
q->hash_size = hash_size;
|
||||
|
||||
#ifdef QUEUE_THREAD_CHECK
|
||||
#ifdef _WIN32
|
||||
q->owner_thread = GetCurrentThreadId();
|
||||
#else
|
||||
q->owner_thread = pthread_self();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Создать хеш-таблицу если нужно
|
||||
if (hash_size > 0) {
|
||||
q->hash_table = u_calloc(hash_size, sizeof(struct ll_entry*));
|
||||
@@ -227,6 +270,12 @@ static void check_waiters(struct ll_queue* q) {
|
||||
int queue_data_put(struct ll_queue* q, struct ll_entry* entry, uint32_t id) {
|
||||
if (!q || !entry) return -1;
|
||||
|
||||
queue_check_thread(q);
|
||||
|
||||
#ifdef QUEUE_DEBUG
|
||||
queue_check_consistency(q);// !!!! for debug - BEFORE callback
|
||||
#endif
|
||||
|
||||
entry->id = id;
|
||||
|
||||
// Проверить лимит размера
|
||||
@@ -278,6 +327,8 @@ int queue_data_put(struct ll_queue* q, struct ll_entry* entry, uint32_t id) {
|
||||
int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry, uint32_t id) {
|
||||
if (!q || !entry) return -1;
|
||||
|
||||
queue_check_thread(q);
|
||||
|
||||
entry->id = id;
|
||||
|
||||
// Проверить лимит размера
|
||||
@@ -330,6 +381,8 @@ int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry, uint32_t id
|
||||
struct ll_entry* queue_data_get(struct ll_queue* q) {
|
||||
if (!q || !q->head) return NULL;
|
||||
|
||||
queue_check_thread(q);
|
||||
|
||||
struct ll_entry* entry = q->head;
|
||||
|
||||
q->head = entry->next;
|
||||
@@ -459,6 +512,8 @@ struct ll_entry* queue_find_data_by_id(struct ll_queue* q, uint32_t id) {
|
||||
int queue_remove_data(struct ll_queue* q, struct ll_entry* entry) {
|
||||
if (!q || !entry) return -1;
|
||||
|
||||
queue_check_thread(q);
|
||||
|
||||
// Удалить из двусвязного списка
|
||||
if (entry->prev) {
|
||||
entry->prev->next = entry->next;
|
||||
|
||||
@@ -5,7 +5,14 @@
|
||||
#include <stdint.h> // для uint64_t
|
||||
#include "memory_pool.h" // для struct memory_pool
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define QUEUE_DEBUG 1
|
||||
#define QUEUE_THREAD_CHECK 1 // 0 to disable
|
||||
|
||||
/**
|
||||
* @file ll_queue.h
|
||||
@@ -45,6 +52,7 @@ struct ll_queue;
|
||||
* Поле dgram — отдельный блок (malloc / пул / внешняя память).
|
||||
*/
|
||||
struct ll_entry {
|
||||
char* name;
|
||||
struct ll_entry* next; ///< Следующий элемент в очереди
|
||||
struct ll_entry* prev; ///< Предыдущий элемент в очереди
|
||||
uint16_t size; ///< Размер пользовательского буфера data[] (байт)
|
||||
@@ -115,6 +123,14 @@ struct ll_queue {
|
||||
|
||||
struct ll_entry** hash_table; ///< Хеш-таблица для поиска по id (если hash_size > 0)
|
||||
size_t hash_size; ///< Размер хеш-таблицы
|
||||
|
||||
#ifdef QUEUE_THREAD_CHECK
|
||||
#ifdef _WIN32
|
||||
DWORD owner_thread;
|
||||
#else
|
||||
pthread_t owner_thread;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ==================== Создание / уничтожение ==================== */
|
||||
|
||||
Reference in new issue
Block a user