]> git.cworth.org Git - apitrace/commitdiff
Various changes to the flushing code.
authorZack Rusin <zack@kde.org>
Tue, 23 Aug 2011 04:37:07 +0000 (00:37 -0400)
committerZack Rusin <zack@kde.org>
Tue, 23 Aug 2011 04:37:07 +0000 (00:37 -0400)
os_posix.cpp
trace_file.cpp
trace_file.hpp

index 3a864720735740207346fa5b98fa4b86de4a3807..684ffac40f668dd4398a77e60688c561c9d73791 100644 (file)
@@ -138,27 +138,70 @@ Abort(void)
 }
 
 
+struct Interrupts
+{
+    Interrupts()
+        : set(false),
+          sig_int(NULL),
+          sig_hup(NULL),
+          sig_term(NULL)
+    {}
+
+    bool set;
+    void (*sig_int)(int);
+    void (*sig_hup)(int);
+    void (*sig_term)(int);
+
+    void (*handler)(int);
+};
+static Interrupts interrupts;
+
+static void InterruptHandler(int sig)
+{
+    if (interrupts.set && interrupts.handler) {
+        interrupts.handler(sig);
+    }
+    if (sig == SIGINT) {
+        if (!interrupts.sig_int)
+            exit(sig);
+        interrupts.sig_int(sig);
+    } else if (sig == SIGHUP) {
+        if (!interrupts.sig_hup)
+            exit(sig);
+        interrupts.sig_hup(sig);
+    } else if (sig == SIGTERM) {
+        if (!interrupts.sig_term)
+            exit(sig);
+        interrupts.sig_term(sig);
+    }
+}
+
 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);
-
+    interrupts.handler = func;
+
+    if (!interrupts.set) {
+        struct sigaction new_action, old_action;
+        new_action.sa_handler = InterruptHandler;
+        sigemptyset(&new_action.sa_mask);
+        new_action.sa_flags = 0;
+#define SET_IF_NOT_IGNORED(sig, old_handler)            \
+        do {                                            \
+            sigaction(sig, NULL, &old_action);          \
+            if (old_action.sa_handler != SIG_IGN) {     \
+                old_handler = old_action.sa_handler;    \
+                sigaction(sig, &new_action, NULL);      \
+            }                                           \
+        } while (0)
+
+        SET_IF_NOT_IGNORED(SIGINT, interrupts.sig_int);
+        SET_IF_NOT_IGNORED(SIGHUP, interrupts.sig_hup);
+        SET_IF_NOT_IGNORED(SIGTERM, interrupts.sig_term);
+
+        interrupts.set = true;
 #undef SET_IF_NOT_IGNORED
+    }
 }
 
 } /* namespace OS */
index 421120fc4ce568663d1383a9cd8330da085f000c..74cc3829e2b4ce5a18a3d69beb614e90b87ed6de 100644 (file)
@@ -22,13 +22,14 @@ class FileCleanup
 {
 public:
     FileCleanup()
-        : m_quitOnFlush(false)
     {
         OS::CatchInterrupts(cleanupHandler);
     }
 
     ~FileCleanup()
     {
+        flush();
+        m_files.clear();
     }
 
     void addFile(Trace::File *file)
@@ -38,28 +39,24 @@ public:
     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
+    void flush()
     {
-        return m_quitOnFlush;
+        std::set<Trace::File*>::const_iterator itr;
+        for (itr = m_files.begin(); itr != m_files.end(); ++itr) {
+            (*itr)->flush(File::FlushDeep);
+        }
     }
 
 private:
     std::set<Trace::File*> m_files;
-    bool m_quitOnFlush;
 };
 static FileCleanup s_cleaner;
 
 static void cleanupHandler(int sig)
 {
-    s_cleaner.setQuitOnFlush(true);
+    s_cleaner.flush();
 }
 
 File::File(const std::string &filename,
@@ -133,12 +130,9 @@ void File::close()
     }
 }
 
-void File::flush()
+void File::flush(FlushType type)
 {
-    rawFlush();
-    if (s_cleaner.quitOnFlush()) {
-        close();
-    }
+    rawFlush(type);
 }
 
 int File::getc()
@@ -222,7 +216,7 @@ void ZLibFile::rawClose()
     }
 }
 
-void ZLibFile::rawFlush()
+void ZLibFile::rawFlush(FlushType type)
 {
     gzflush(m_gzFile, Z_SYNC_FLUSH);
 }
@@ -324,6 +318,8 @@ bool SnappyFile::rawRead(void *buffer, int length)
             sizeToRead -= chunkSize;
             if (sizeToRead > 0)
                 flushCache();
+            if (!m_cacheSize)
+                break;
         }
     }
 
@@ -347,8 +343,11 @@ void SnappyFile::rawClose()
     m_cachePtr = NULL;
 }
 
-void SnappyFile::rawFlush()
+void SnappyFile::rawFlush(FlushType type)
 {
+    if (type == FlushDeep) {
+        flushCache();
+    }
     m_stream.flush();
 }
 
index ddc36c0c8b49a616a0ff5307f40746395b1f7d63..fb61b985d8c2e98862a95af05d37a897a1988c66 100644 (file)
@@ -12,6 +12,10 @@ public:
         Read,
         Write
     };
+    enum FlushType {
+        FlushShallow,
+        FlushDeep
+    };
 public:
     static bool isZLibCompressed(const std::string &filename);
     static bool isSnappyCompressed(const std::string &filename);
@@ -28,7 +32,7 @@ public:
     bool write(const void *buffer, int length);
     bool read(void *buffer, int length);
     void close();
-    void flush();
+    void flush(FlushType type = FlushShallow);
     int getc();
 
 protected:
@@ -37,7 +41,7 @@ protected:
     virtual bool rawRead(void *buffer, int length) = 0;
     virtual int rawGetc() = 0;
     virtual void rawClose() = 0;
-    virtual void rawFlush() = 0;
+    virtual void rawFlush(FlushType type) = 0;
 
 protected:
     std::string m_filename;
@@ -57,7 +61,7 @@ protected:
     virtual bool rawRead(void *buffer, int length);
     virtual int rawGetc();
     virtual void rawClose();
-    virtual void rawFlush();
+    virtual void rawFlush(FlushType type);
 private:
     void *m_gzFile;
 };
@@ -79,7 +83,7 @@ protected:
     virtual bool rawRead(void *buffer, int length);
     virtual int rawGetc();
     virtual void rawClose();
-    virtual void rawFlush();
+    virtual void rawFlush(FlushType type);
 
 private:
     inline int freeCacheSize() const