From df4bc975a7cd4600e50aff5a4fdc9a777d414605 Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Tue, 5 Nov 2013 13:45:42 +0100 Subject: [PATCH 02/39] Encapsulate all jthread_map calls inside critical section Every single thread has to remember that an exception was already reported in order to prevent multiple reports for a single exception. The reported exceptions are stored in a list and each thread has own list of reported exceptions. These lists are stored in a global map. Refrences: commit 4144d9dade18645642f4360a9a4cd2fd318b4de4, issue #11 ThreadStart, ThreadEnd and Exception callbacks are called from different threads but all of the access the thread to reported exception map. Therefore access to internal data must be serialized through lock-protected critical section. Related to rhbz#1026208 Related to rhbz#1051483 --- src/jthread_map.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/jthread_map.c b/src/jthread_map.c index 7b70953..29c5c29 100644 --- a/src/jthread_map.c +++ b/src/jthread_map.c @@ -20,6 +20,7 @@ #include "jthrowable_circular_buf.h" #include +#include #include @@ -42,6 +43,7 @@ typedef struct jthread_map_item { struct jthread_map { T_jthreadMapItem *items[MAP_SIZE]; ///< map elements + pthread_mutex_t mutex; }; @@ -54,6 +56,8 @@ T_jthreadMap *jthread_map_new() fprintf(stderr, __FILE__ ":" STRINGIZE(__LINE__) ": calloc() error\n"); } + pthread_mutex_init(&map->mutex, /*use default attributes*/NULL); + return map; } @@ -66,6 +70,7 @@ void jthread_map_free(T_jthreadMap *map) return; } + pthread_mutex_destroy(&map->mutex); free(map); } @@ -104,6 +109,8 @@ void jthread_map_push(T_jthreadMap *map, jlong tid, T_jthrowableCircularBuf *buf { assert(NULL != map); + pthread_mutex_lock(&map->mutex); + const long index = tid % MAP_SIZE; T_jthreadMapItem *last = NULL; T_jthreadMapItem *itm = map->items[index]; @@ -125,6 +132,8 @@ void jthread_map_push(T_jthreadMap *map, jlong tid, T_jthrowableCircularBuf *buf last->next = new; } } + + pthread_mutex_unlock(&map->mutex); } @@ -133,17 +142,23 @@ T_jthrowableCircularBuf *jthread_map_get(T_jthreadMap *map, jlong tid) { assert(NULL != map); + pthread_mutex_lock(&map->mutex); + const size_t index = tid % MAP_SIZE; + T_jthrowableCircularBuf *buffer = NULL; for (T_jthreadMapItem *itm = map->items[index]; NULL != itm; itm = itm->next) { if (itm->tid == tid) { - return itm->buffer; + buffer = itm->buffer; + break; } } - return NULL; + pthread_mutex_unlock(&map->mutex); + + return buffer; } @@ -152,6 +167,8 @@ T_jthrowableCircularBuf *jthread_map_pop(T_jthreadMap *map, jlong tid) { assert(NULL != map); + pthread_mutex_lock(&map->mutex); + const size_t index = tid % MAP_SIZE; T_jthrowableCircularBuf *buffer = NULL; if (NULL != map->items[index]) @@ -181,6 +198,8 @@ T_jthrowableCircularBuf *jthread_map_pop(T_jthreadMap *map, jlong tid) } } + pthread_mutex_unlock(&map->mutex); + return buffer; } -- 1.8.3.1