Подробности
[В начало]
Проблема в реализации № D0024
Краткое описание
Вызов функции "g_thread_pool_free" с определенными входными параметрами приводит к сообщению об ошибке
Подробное описание
Вызов функции g_thread_pool_free со следующими входными параметрами: "immediate" = TRUE "wait" = FALSE приводит к сообщению об ошибке: "g_thread_pool_wakeup_and_stop_all: assertion `g_async_queue_length_unlocked (pool->queue) == -pool->num_threads' failed".
Раздел стандарта
Linux Standard Base Desktop Specification 3.1, Chapter 12. Libraries, 12.2 Interfaces for libglib-2.0; http://www.gtk.org/api/2.6/glib/glib-Thread-Pools.html#g-thread-pool-free
Способ воспроизведения
- В пул потоков добавляется 10 заданий.
- После завершения первого задания вызывается "g_thread_pool_free (pool, TRUE, FALSE)", что приводит к следующей ошибке: "g_thread_pool_wakeup_and_stop_all: assertion `g_async_queue_length_unlocked (pool->queue) == -pool->num_threads' failed".
Пример
#include <glib.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <errno.h> #include <time.h> #include <semaphore.h> #define VAR(function, name, tp_index) _##function##_TP_##tp_index##_##name #define FUNC(function, name, tp_index) __##function##_TP_##tp_index##_##name #define TP_FUNC(function, tp_index) _##function##_TP_##tp_index##_ #define TIMED_WAIT(condition, seconds)\ int __tw_expired=0; struct timeval __tv;gettimeofday(&__tv, NULL);\ long __st_sec=__tv.tv_sec;\ while(condition) {g_usleep(100);gettimeofday(&__tv, NULL);\ if((__tv.tv_sec - __st_sec)>seconds){ __tw_expired=1;break;}} #define TIMED_WAIT_EXPIRED __tw_expired #define TIMED_WAIT_2(condition, seconds)\ __tw_expired=0;gettimeofday(&__tv, NULL);__st_sec=__tv.tv_sec;\ while(condition) {g_usleep(100);gettimeofday(&__tv, NULL);\ if((__tv.tv_sec - __st_sec)>seconds) { __tw_expired=1;break;}} #define _DECLARE_G_SEMAPHORE(s_name) sem_t s_name; #define _G_SUNLOCK(s_name) sem_post(&s_name); #define _G_STIMED_WAIT(seconds, s_name, exp_var, tumeout_st)\ int exp_var=0;struct timespec tumeout_st;\ clock_gettime(CLOCK_REALTIME, &tumeout_st);tumeout_st.tv_sec += seconds;\ if(sem_timedwait(&s_name, &tumeout_st) != 0)\ {if(errno == ETIMEDOUT) exp_var=1;} #define _G_STIMED_WAIT_2(seconds, s_name, exp_var, tumeout_st)\ exp_var=0;clock_gettime(CLOCK_REALTIME, &tumeout_st);\ tumeout_st.tv_sec += seconds;\ if(sem_timedwait(&s_name, &tumeout_st) != 0){if(errno == ETIMEDOUT) \ exp_var=1;} #define _G_STIMED_WAIT_EXPIRED(exp_var) exp_var #define DECLARE_G_SEMAPHORE _DECLARE_G_SEMAPHORE(_g_sem_) #define G_SUNLOCK _G_SUNLOCK(_g_sem_) #define G_STIMED_WAIT(seconds) \ _G_STIMED_WAIT(seconds, _g_sem_, __stw_expired, __stimeout) #define G_STIMED_WAIT_2(seconds) \ _G_STIMED_WAIT_2(seconds, _g_sem_, __stw_expired, __stimeout) #define G_STIMED_WAIT_EXPIRED \ _G_STIMED_WAIT_EXPIRED(__stw_expired) #define DECLARE_G_SEMAPHORE_EX _DECLARE_G_SEMAPHORE(_g_sem_2) #define G_SUNLOCK_EX _G_SUNLOCK(_g_sem_2) #define G_STIMED_WAIT_EX(seconds) \ _G_STIMED_WAIT(seconds, _g_sem_2, __stw_expired_2, __stimeout_2) #define G_STIMED_WAIT_2_EX(seconds) \ _G_STIMED_WAIT_2(seconds, _g_sem_2, __stw_expired_2, __stimeout_2) #define G_STIMED_WAIT_EXPIRED_EX \ _G_STIMED_WAIT_EXPIRED(__stw_expired_2) #define DECLARE_G_SEMAPHORE_EX_2 _DECLARE_G_SEMAPHORE(_g_sem_3) #define G_SUNLOCK_EX_2 _G_SUNLOCK(_g_sem_3) #define G_STIMED_WAIT_EX_2(seconds) \ _G_STIMED_WAIT(seconds, _g_sem_3, __stw_expired_3, __stimeout_3) #define G_STIMED_WAIT_2_EX_2(seconds) \ _G_STIMED_WAIT_2(seconds, _g_sem_3, __stw_expired_3, __stimeout_3) #define G_STIMED_WAIT_EXPIRED_EX_2 \ _G_STIMED_WAIT_EXPIRED(__stw_expired_3) DECLARE_G_SEMAPHORE DECLARE_G_SEMAPHORE_EX DECLARE_G_SEMAPHORE_EX_2 #define IMMEDIATE TRUE #define WAIT FALSE int glob_count = 0; GStaticMutex func_mutex = G_STATIC_MUTEX_INIT; void initGlobalSemaphores() { sem_init(&_g_sem_, 0, 0); sem_init(&_g_sem_2, 0, 0); sem_init(&_g_sem_3, 0, 0); } void func_free (gpointer data, gpointer user_data) { g_static_mutex_lock (&func_mutex); int count = glob_count; g_static_mutex_unlock (&func_mutex); if (count == 1) { G_SUNLOCK; G_STIMED_WAIT_EX (3); } g_static_mutex_lock (&func_mutex); count = ++glob_count; g_static_mutex_unlock (&func_mutex); if (count == 1) { G_SUNLOCK; } } int main () { g_thread_init (NULL); GThreadPool *pool = NULL; char *_data = "data"; int thread_count = 10; initGlobalSemaphores (); g_static_mutex_lock (&func_mutex); glob_count = 0; g_static_mutex_unlock (&func_mutex); pool = g_thread_pool_new (func_free, "unprocessed pool", 1, FALSE, NULL); int i; for ( i = 0; i < thread_count; i++) { g_thread_pool_push (pool, _data, NULL); } G_STIMED_WAIT (3); G_STIMED_WAIT_2 (3); g_thread_pool_free (pool, IMMEDIATE, WAIT); return 0; }
Компонент
gtk-glib 2.6.2 - 2.12.4(excl.)
Статус
Исправлено в gtk-glib - 2.12.4
[В начало]
»