Blob Blame Raw
From df4bc975a7cd4600e50aff5a4fdc9a777d414605 Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
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 <stdlib.h>
+#include <pthread.h>
 #include <assert.h>
 
 
@@ -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