diff --git a/modules/libcom/src/error/errlog.c b/modules/libcom/src/error/errlog.c index 7ed6a8bd7..8c1c9c0ce 100644 --- a/modules/libcom/src/error/errlog.c +++ b/modules/libcom/src/error/errlog.c @@ -65,6 +65,7 @@ typedef struct listenerNode{ typedef struct { char *base; size_t pos; + size_t nchar; } buffer_t; static struct { @@ -91,8 +92,8 @@ static struct { /* A loop counter maintained by errlogThread. */ epicsUInt32 flushSeq; - size_t nFlushers; - size_t nLost; + unsigned long nFlushers; + unsigned long nLost; /* 'log' and 'print' combine to form a double buffer. */ buffer_t *log; @@ -118,9 +119,14 @@ char* msgbufAlloc(void) errlogInit(0); epicsMutexMustLock(pvt.msgQueueLock); /* matched in msgbufCommit() */ - if(pvt.bufSize - pvt.log->pos >= 1+pvt.maxMsgSize) { + if(pvt.bufSize - pvt.log->pos - pvt.log->nchar >= 1+pvt.maxMsgSize) { /* there is enough space for the worst cast */ ret = pvt.log->base + pvt.log->pos; + if (pvt.log->nchar) { + /* append to last message */ + return ret + 1 + pvt.log->nchar; + } + /* new message */ ret[0] = ERL_STATE_WRITE; ret++; } @@ -138,7 +144,7 @@ size_t msgbufCommit(size_t nchar, int localEcho) int isOkToBlock = epicsThreadIsOkToBlock(); int wasEmpty = pvt.log->pos==0; int atExit = pvt.atExit; - char *start = pvt.log->base + pvt.log->pos; + char *start = pvt.log->base + pvt.log->pos + pvt.log->nchar; /* nchar returned by snprintf() is >= maxMsgSize when truncated */ if(nchar >= pvt.maxMsgSize) { @@ -157,15 +163,20 @@ size_t msgbufCommit(size_t nchar, int localEcho) */ fprintf(pvt.console, "%s", start); - } else { - start[0u] = ERL_STATE_READY | (localEcho ? ERL_LOCALECHO : 0); + } else if (start[nchar] != '\n') { + /* incomplete message, prepare to append */ + pvt.log->nchar += nchar; - pvt.log->pos += 1u + nchar + 1u; + } else { + pvt.log->base[pvt.log->pos] = ERL_STATE_READY | (localEcho ? ERL_LOCALECHO : 0); + + pvt.log->pos += 1 + pvt.log->nchar + nchar + 1; + pvt.log->nchar = 0; } epicsMutexUnlock(pvt.msgQueueLock); /* matched in msgbufAlloc() */ - if(wasEmpty && !atExit) + if(wasEmpty && !atExit && !pvt.log->nchar) epicsEventMustTrigger(pvt.waitForWork); if(localEcho && isOkToBlock && !atExit) @@ -519,7 +530,7 @@ static void errlogThread(void) } else { /* snapshot and swap buffers for use while unlocked */ - size_t nLost = pvt.nLost; + unsigned long nLost = pvt.nLost; FILE *console = pvt.toConsole ? pvt.console : NULL; size_t pos = 0u; buffer_t *print; @@ -564,7 +575,7 @@ static void errlogThread(void) print->pos = 0u; if(nLost && console) - fprintf(console, "errlog: lost %zu messages\n", nLost); + fprintf(console, "errlog: lost %lu messages\n", nLost); if(console) fflush(console);