]> git.cworth.org Git - apitrace/commitdiff
Move mutex abstraction to os_thread.hpp.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Tue, 27 Dec 2011 20:00:47 +0000 (20:00 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Tue, 27 Dec 2011 20:10:05 +0000 (20:10 +0000)
common/os.hpp
common/os_posix.cpp
common/os_thread.hpp
common/os_win32.cpp
common/trace_writer_local.cpp
common/trace_writer_local.hpp

index 6a3b8c82f33840929b688de60ceb6f69fe9901b7..caf9dc3d2cc66e4243d819571beaf1082c7bd723 100644 (file)
 
 namespace os {
 
-void acquireMutex(void);
-
-void releaseMutex(void);
-
 void log(const char *format, ...)
 #ifdef __GNUC__
     __attribute__ ((format (printf, 1, 2)))
index 7dc2bb46a0d54400aee1a297e1064d10a01043f0..65c5404e3c0e64dd92c2184143474e05fe815b10 100644 (file)
@@ -32,7 +32,6 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <sys/wait.h>
-#include <pthread.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <signal.h>
 namespace os {
 
 
-static pthread_mutex_t 
-mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-void
-acquireMutex(void)
-{
-    pthread_mutex_lock(&mutex);
-}
-
-
-void
-releaseMutex(void)
-{
-    pthread_mutex_unlock(&mutex);
-}
-
-
 String
 getProcessName(void)
 {
index 7349255525276b47b36c3b5ba5aa7e3c4f4b6d81..b17563fa5428d2ac80a4b5d18adf916c6c69ac75 100644 (file)
@@ -32,6 +32,7 @@
 #ifndef _OS_THREAD_HPP_
 #define _OS_THREAD_HPP_
 
+
 #ifdef _WIN32
 #include <windows.h>
 #else
 namespace os {
 
 
+    class recursive_mutex
+    {
+    public:
+#ifdef _WIN32
+        typedef CRITICAL_SECTION native_handle_type;
+#else
+        typedef pthread_mutex_t native_handle_type;
+#endif
+
+        recursive_mutex(void) {
+#ifdef _WIN32
+            InitializeCriticalSection(&_native_handle);
+#else
+            pthread_mutexattr_t attr;
+            pthread_mutexattr_init(&attr);
+            pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+            pthread_mutex_init(&_native_handle, NULL);
+            pthread_mutexattr_destroy(&attr);
+#endif
+        }
+
+        ~recursive_mutex() {
+#ifdef _WIN32
+            DeleteCriticalSection(&_native_handle);
+#else
+            pthread_mutex_destroy(&_native_handle);
+#endif
+        }
+
+        inline void
+        lock(void) {
+#ifdef _WIN32
+            EnterCriticalSection(&_native_handle);
+#else
+            pthread_mutex_lock(&_native_handle);
+#endif
+        }
+
+        inline void
+        unlock(void) {
+#ifdef _WIN32
+            LeaveCriticalSection(&_native_handle);
+#else
+            pthread_mutex_unlock(&_native_handle);
+#endif
+        }
+
+    private:
+        native_handle_type _native_handle;
+    };
+
+
     template <typename T>
     class thread_specific_ptr
     {
index 7e1a544a163597997130251f0f269ebfb63b2342..a0203544ee6b1298683c9e5c2b2e0b088c7aeb65 100644 (file)
 namespace os {
 
 
-/* 
- * Trick from http://locklessinc.com/articles/pthreads_on_windows/
- */
-static CRITICAL_SECTION
-criticalSection = {
-    (PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0
-};
-
-
-void
-acquireMutex(void)
-{
-    EnterCriticalSection(&criticalSection);
-}
-
-
-void
-releaseMutex(void)
-{
-    LeaveCriticalSection(&criticalSection);
-}
-
-
 String
 getProcessName(void)
 {
index 52962c8b50e256adbc2841b9ad2af6c440834132..a3ab720b2dd13f9c89536e4905ed63981ead0b2f 100644 (file)
@@ -128,7 +128,7 @@ static unsigned next_thread_id = 0;
 static os::thread_specific_ptr<unsigned> thread_id_specific_ptr;
 
 unsigned LocalWriter::beginEnter(const FunctionSig *sig) {
-    os::acquireMutex();
+    mutex.lock();
     ++acquired;
 
     if (!m_file->isOpened()) {
@@ -152,11 +152,11 @@ unsigned LocalWriter::beginEnter(const FunctionSig *sig) {
 void LocalWriter::endEnter(void) {
     Writer::endEnter();
     --acquired;
-    os::releaseMutex();
+    mutex.unlock();
 }
 
 void LocalWriter::beginLeave(unsigned call) {
-    os::acquireMutex();
+    mutex.lock();
     ++acquired;
     Writer::beginLeave(call);
 }
@@ -164,16 +164,17 @@ void LocalWriter::beginLeave(unsigned call) {
 void LocalWriter::endLeave(void) {
     Writer::endLeave();
     --acquired;
-    os::releaseMutex();
+    mutex.unlock();
 }
 
 void LocalWriter::flush(void) {
     /*
      * Do nothing if the mutex is already acquired (e.g., if a segfault happen
-     * while writing the file) to prevent dead-lock.
+     * while writing the file) as state could be inconsistent, therefore yield
+     * inconsistent trace files and/or repeated segfaults till infinity.
      */
 
-    os::acquireMutex();
+    mutex.lock();
     if (acquired) {
         os::log("apitrace: ignoring exception while tracing\n");
     } else {
@@ -184,7 +185,7 @@ void LocalWriter::flush(void) {
         }
         --acquired;
     }
-    os::releaseMutex();
+    mutex.unlock();
 }
 
 
index 7c705801b716de4fb7d56d73a5c1cef63df3476d..e54142f82b816654679b149306966954b3ac4633 100644 (file)
@@ -31,6 +31,7 @@
 #define _TRACE_WRITER_LOCAL_HPP_
 
 
+#include "os_thread.hpp"
 #include "trace_writer.hpp"
 
 
@@ -52,6 +53,10 @@ namespace trace {
      */
     class LocalWriter : public Writer {
     protected:
+        /**
+         * We need a recursive mutex so that it doesn't dead lock when a segfault happens when the mutex is held.
+         */
+        os::recursive_mutex mutex;
         int acquired;
 
     public: