проверки thread в ll_queue

This commit is contained in:
jeka committed 2026-03-06 22:45:00 +03:00
1 parent 1811764f6d
commit 5dfd1ea5fe
5 files changed
+85 -6

No files matched your search

+55
View File
@@ -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;