From: Zack Rusin Date: Sat, 20 Aug 2011 22:05:04 +0000 (-0400) Subject: Make sure that the traces are always complete. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=00e0021870c9bbba51376aa32554183e1c7859ba;p=apitrace Make sure that the traces are always complete. --- diff --git a/os.hpp b/os.hpp index 4376c97..e93b113 100644 --- 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_ */ diff --git a/os_posix.cpp b/os_posix.cpp index cb9b7e5..3a86472 100644 --- a/os_posix.cpp +++ b/os_posix.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef __APPLE__ #include @@ -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 */ diff --git a/os_win32.cpp b/os_win32.cpp index f220ae5..90ce8d3 100644 --- a/os_win32.cpp +++ b/os_win32.cpp @@ -24,6 +24,7 @@ **************************************************************************/ #include +#include #include #include @@ -133,4 +134,13 @@ Abort(void) #endif } +void +CatchInterrupts(void (*func)(int)) +{ + signal(SIGINT, func); + signal(SIGHUP, func); + signal(SIGTERM, func); +} + + } /* namespace OS */ diff --git a/trace_file.cpp b/trace_file.cpp index 27b3eb1..421120f 100644 --- a/trace_file.cpp +++ b/trace_file.cpp @@ -6,13 +6,62 @@ #include #include +#include "os.hpp" + #include +#include 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 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() diff --git a/trace_writer.cpp b/trace_writer.cpp index bc2ee6c..7511d31 100644 --- a/trace_writer.cpp +++ b/trace_writer.cpp @@ -199,7 +199,6 @@ unsigned Writer::beginEnter(const FunctionSig *sig) { void Writer::endEnter(void) { _writeByte(Trace::CALL_END); - m_file->flush(); OS::ReleaseMutex(); }