Подробности
[В начало]
Проблема в реализации № 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
[В начало]
»