local sync: write child messages into <test>.log text file

When running client-test, the normal stdout text is copied into
a .log text file named after the currently running test. The output
of the child process should also go there.

This patch achieves that by being more selective about which loggers
in the stack of loggers it removes: LogDir must be removed because it
writes per-process Synthesis .html files, LoggerStdout must remain for
.log. The difference is abstracted away behind a new
Logger::isProcessSafe() method, which tells LocalTransportAgent whether
sharing the logger instance between processes is okay.
This commit is contained in:
Patrick Ohly 2010-12-09 11:52:45 +01:00
parent 618ddd47eb
commit aaeb556afb
6 changed files with 33 additions and 5 deletions

View File

@ -141,16 +141,31 @@ void LocalTransportAgent::run()
// reading from the existing in-process variables. So let's
// try without exec, after some clean up.
// Remove writing into the parent's log file => implemented as
// removing every logger until we run into the parents LogRedirect
// instance. That instance needs to be remembered and flushed
// before this process may terminate.
// The parent may or may not have installed output redirection.
// That instance needs to be remembered and flushed before this
// process may terminate. The parent will also do the same kind of
// flushing (race condition?!), but it might die before being
// able to do so.
//
// This loop used to remove all other loggers above the
// redirection, to get rid of the one which writes into the
// -log.html file of the parent. This was too coarse and also
// removed the LoggerStdout which was installed by
// client-test. Now the logger for -log.html is detected via
// Logger::isProcessSafe().
int index = LoggerBase::numLoggers();
LogRedirect *redirect = NULL;
bool removing = true;
--index;
while (index >= 0 &&
!(redirect = dynamic_cast<LogRedirect *>(LoggerBase::loggerAt(index)))) {
LoggerBase::popLogger();
if (removing) {
if (!LoggerBase::loggerAt(index)->isProcessSafe()) {
LoggerBase::popLogger();
} else {
removing = false;
}
}
--index;
}

View File

@ -591,6 +591,7 @@ class LogRedirectTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT(level <= DEBUG && level >= 0);
m_streams[level] << StringPrintfV(format, args);
}
virtual bool isProcessSafe() const { return true; }
};
public:

View File

@ -70,6 +70,8 @@ class LoggerStdout : public LoggerBase
const char *function,
const char *format,
va_list args);
virtual bool isProcessSafe() const { return true; }
};
SE_END_CXX

View File

@ -132,6 +132,13 @@ class Logger
__attribute__((format(printf, 7, 8)))
#endif
;
/**
* this logger instance can be used by multiple processes:
* true for those which write single lines, false
* for more complicated output like HTML (Synthesis log)
*/
virtual bool isProcessSafe() const = 0;
};
/**

View File

@ -809,6 +809,8 @@ public:
m_parentLogger.messagev(level, prefix, file, line, function, format, args);
}
virtual bool isProcessSafe() const { return false; }
/**
* Compare two database dumps just based on their inodes.
* @return true if inodes differ

View File

@ -668,6 +668,7 @@ class SyncSourceBase : public Logger {
const char *function,
const char *format,
va_list args);
virtual bool isProcessSafe() const { return true; }
/**
* return Synthesis API pointer, if one currently is available