}
+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 */
{
public:
FileCleanup()
- : m_quitOnFlush(false)
{
OS::CatchInterrupts(cleanupHandler);
}
~FileCleanup()
{
+ flush();
+ m_files.clear();
}
void addFile(Trace::File *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
+ 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,
}
}
-void File::flush()
+void File::flush(FlushType type)
{
- rawFlush();
- if (s_cleaner.quitOnFlush()) {
- close();
- }
+ rawFlush(type);
}
int File::getc()
}
}
-void ZLibFile::rawFlush()
+void ZLibFile::rawFlush(FlushType type)
{
gzflush(m_gzFile, Z_SYNC_FLUSH);
}
sizeToRead -= chunkSize;
if (sizeToRead > 0)
flushCache();
+ if (!m_cacheSize)
+ break;
}
}
m_cachePtr = NULL;
}
-void SnappyFile::rawFlush()
+void SnappyFile::rawFlush(FlushType type)
{
+ if (type == FlushDeep) {
+ flushCache();
+ }
m_stream.flush();
}
Read,
Write
};
+ enum FlushType {
+ FlushShallow,
+ FlushDeep
+ };
public:
static bool isZLibCompressed(const std::string &filename);
static bool isSnappyCompressed(const std::string &filename);
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:
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;
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;
};
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