]> git.cworth.org Git - apitrace/commitdiff
Make sure that the traces are always complete.
authorZack Rusin <zack@kde.org>
Sat, 20 Aug 2011 22:05:04 +0000 (18:05 -0400)
committerZack Rusin <zack@kde.org>
Sat, 20 Aug 2011 22:05:04 +0000 (18:05 -0400)
os.hpp
os_posix.cpp
os_win32.cpp
trace_file.cpp
trace_writer.cpp

diff --git a/os.hpp b/os.hpp
index 4376c97b50eea2d55a548022907f429476a70196..e93b113fbe8606f2ebea12fc4f425bbecb8ddc8e 100644 (file)
--- a/os.hpp
+++ b/os.hpp
@@ -90,6 +90,8 @@ long long GetTime(void);
 
 void Abort(void);
 
+void CatchInterrupts(void (*func)(int));
+
 } /* namespace OS */
 
 #endif /* _OS_HPP_ */
index cb9b7e59113130b5f696f21a41769aa5c463fc7a..3a864720735740207346fa5b98fa4b86de4a3807 100644 (file)
@@ -33,6 +33,7 @@
 #include <pthread.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <signal.h>
 
 #ifdef __APPLE__
 #include <mach-o/dyld.h>
@@ -137,5 +138,28 @@ Abort(void)
 }
 
 
+void
+CatchInterrupts(void (*func)(int))
+{
+    struct sigaction new_action, old_action;
+
+    new_action.sa_handler = func;
+    sigemptyset(&new_action.sa_mask);
+    new_action.sa_flags = 0;
+
+#define SET_IF_NOT_IGNORED(sig)                \
+    do {                                       \
+        sigaction(sig, NULL, &old_action);     \
+        if (old_action.sa_handler != SIG_IGN)  \
+            sigaction(sig, &new_action, NULL); \
+    } while (0)
+
+    SET_IF_NOT_IGNORED(SIGINT);
+    SET_IF_NOT_IGNORED(SIGHUP);
+    SET_IF_NOT_IGNORED(SIGTERM);
+
+#undef SET_IF_NOT_IGNORED
+}
+
 } /* namespace OS */
 
index f220ae5ec46dbbcd7368ca0204a36a669d26c835..90ce8d3a74a41a5a660cc71547d27898d0d834e1 100644 (file)
@@ -24,6 +24,7 @@
  **************************************************************************/
 
 #include <windows.h>
+#include <signal.h>
 #include <string.h>
 #include <stdio.h>
 
@@ -133,4 +134,13 @@ Abort(void)
 #endif
 }
 
+void
+CatchInterrupts(void (*func)(int))
+{
+    signal(SIGINT, func);
+    signal(SIGHUP, func);
+    signal(SIGTERM, func);
+}
+
+
 } /* namespace OS */
index 27b3eb18c07d10eb7e0a2fc3e5dc1bdd9e366b26..421120fc4ce568663d1383a9cd8330da085f000c 100644 (file)
@@ -6,13 +6,62 @@
 #include <zlib.h>
 #include <snappy.h>
 
+#include "os.hpp"
+
 #include <iostream>
+#include <set>
 
 using namespace Trace;
 
 #define SNAPPY_BYTE1 'a'
 #define SNAPPY_BYTE2 't'
 
+static void cleanupHandler(int sig);
+
+class FileCleanup
+{
+public:
+    FileCleanup()
+        : m_quitOnFlush(false)
+    {
+        OS::CatchInterrupts(cleanupHandler);
+    }
+
+    ~FileCleanup()
+    {
+    }
+
+    void addFile(Trace::File *file)
+    {
+        m_files.insert(file);
+    }
+    void removeFile(Trace::File *file)
+    {
+        m_files.erase(file);
+        if (m_files.empty() && m_quitOnFlush) {
+            OS::Abort();
+        }
+    }
+
+    void setQuitOnFlush(bool quit) {
+        m_quitOnFlush = quit;
+    }
+    bool quitOnFlush() const
+    {
+        return m_quitOnFlush;
+    }
+
+private:
+    std::set<Trace::File*> m_files;
+    bool m_quitOnFlush;
+};
+static FileCleanup s_cleaner;
+
+static void cleanupHandler(int sig)
+{
+    s_cleaner.setQuitOnFlush(true);
+}
+
 File::File(const std::string &filename,
            File::Mode mode)
     : m_filename(filename),
@@ -52,6 +101,10 @@ bool File::open(const std::string &filename, File::Mode mode)
     }
     m_isOpened = rawOpen(filename, mode);
     m_mode = mode;
+
+    if (m_isOpened) {
+        s_cleaner.addFile(this);
+    }
     return m_isOpened;
 }
 
@@ -76,12 +129,16 @@ void File::close()
     if (m_isOpened) {
         rawClose();
         m_isOpened = false;
+        s_cleaner.removeFile(this);
     }
 }
 
 void File::flush()
 {
     rawFlush();
+    if (s_cleaner.quitOnFlush()) {
+        close();
+    }
 }
 
 int File::getc()
index bc2ee6ce9e8850ed5511bea89b8880531a6252c1..7511d3192420db31f65ee2e74dd5203db3ec201a 100644 (file)
@@ -199,7 +199,6 @@ unsigned Writer::beginEnter(const FunctionSig *sig) {
 
 void Writer::endEnter(void) {
     _writeByte(Trace::CALL_END);
-    m_file->flush();
     OS::ReleaseMutex();
 }