Fix native-newline printing to print atomically

* With the log append setup, printing lines and newlines separately can
  lead to them being interleaved between multiple processes writing to
  the same log.
* This way the lines in a print could still be scattered, but without
  over-allocating to modify newlines in place (which would be more
  expensive too) this can't be fixed, and both multi-line prints and
  multiple processes writing a lot of log prints are rare.
This commit is contained in:
baldurk
2017-09-26 12:15:51 +01:00
parent 8e40cabd57
commit 05c87778ea
+28 -18
View File
@@ -335,7 +335,16 @@ void rdclogprint_int(LogType type, const char *fullMsg, const char *msg)
}
const int rdclog_outBufSize = 4 * 1024;
static char rdclog_outputBuffer[rdclog_outBufSize + 1];
static char rdclog_outputBuffer[rdclog_outBufSize + 3];
static void write_newline(char *output)
{
#if ENABLED(RDOC_WIN32)
*(output++) = '\r';
#endif
*(output++) = '\n';
*output = 0;
}
void rdclog_int(LogType type, const char *project, const char *file, unsigned int line,
const char *fmt, ...)
@@ -413,7 +422,7 @@ void rdclog_int(LogType type, const char *project, const char *file, unsigned in
if(totalWritten > rdclog_outBufSize)
{
available = totalWritten + 3;
oversizedBuffer = output = new char[available];
oversizedBuffer = output = new char[available + 3];
base = output;
numWritten = StringFormat::snprintf(output, available, "% 4s %06u: %s%s%s - ", project,
@@ -432,32 +441,33 @@ void rdclog_int(LogType type, const char *project, const char *file, unsigned in
va_end(args2);
}
*output = 0;
const char newline[] =
#if ENABLED(RDOC_WIN32)
"\r\n";
#else
"\n";
#endif
// likely path - string contains no newlines
char *nl = strchr(base, '\n');
if(nl == NULL)
{
rdclogprint_int(type, base, noPrefixOutput);
// append newline
write_newline(output);
// print a newline automatically
rdclogprint_int(type, newline, newline);
rdclogprint_int(type, base, noPrefixOutput);
}
else
{
char backup[2];
// otherwise, print the string in sections to ensure newlines are in native format
while(nl)
{
*nl = 0;
// backup the two characters after the \n, to allow for DOS newlines ('\r' '\n' '\0')
backup[0] = nl[1];
backup[1] = nl[2];
write_newline(nl);
rdclogprint_int(type, base, noPrefixOutput);
rdclogprint_int(type, newline, newline);
// restore the characters
nl[1] = backup[0];
nl[2] = backup[1];
base = nl + 1;
noPrefixOutput = nl + 1;
@@ -465,10 +475,10 @@ void rdclog_int(LogType type, const char *project, const char *file, unsigned in
nl = strchr(base, '\n');
}
// there will be the remainder up to the final non-trailing newline, print it
// append final newline and write the last line
write_newline(output);
rdclogprint_int(type, base, noPrefixOutput);
rdclogprint_int(type, newline, newline);
}
SAFE_DELETE_ARRAY(oversizedBuffer);