summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2010-03-10 09:58:46 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2010-03-10 09:58:46 +0100
commitee8bf6d6873b79a5b1ed5a2aae08adf0d4827ff3 (patch)
treefe7fe9aa579d90e58c270aa7d7d2294cd30d01ef
parent8833612e7516694e89148eb3dc1c88f5ea954d16 (diff)
parent6c43f93022caa3feaa7b4fa3d88ca31746fd94cf (diff)
downloadrsyslog-ee8bf6d6873b79a5b1ed5a2aae08adf0d4827ff3.tar.gz
rsyslog-ee8bf6d6873b79a5b1ed5a2aae08adf0d4827ff3.tar.xz
rsyslog-ee8bf6d6873b79a5b1ed5a2aae08adf0d4827ff3.zip
Merge branch 'v4-stable' into v4-stable-next
-rw-r--r--runtime/stream.c15
-rw-r--r--runtime/stream.h1
-rwxr-xr-xtests/diskqueue.sh3
3 files changed, 14 insertions, 5 deletions
diff --git a/runtime/stream.c b/runtime/stream.c
index bb92eeb5..d76f12e7 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -318,13 +318,11 @@ static rsRetVal strmCloseFile(strm_t *pThis)
ASSERT(pThis != NULL);
dbgoprint((obj_t*) pThis, "file %d closing\n", pThis->fd);
- if(!pThis->bInClose && pThis->tOperationsMode != STREAMMODE_READ) {
- pThis->bInClose = 1;
+ if(pThis->tOperationsMode != STREAMMODE_READ) {
strmFlush(pThis);
if(pThis->bAsyncWrite) {
strmWaitAsyncWriterDone(pThis);
}
- pThis->bInClose = 0;
}
close(pThis->fd);
@@ -882,13 +880,22 @@ strmSchedWrite(strm_t *pThis, uchar *pBuf, size_t lenBuf)
ASSERT(pThis != NULL);
+ /* we need to reset the buffer pointer BEFORE calling the actual write
+ * function. Otherwise, in circular mode, the write function will
+ * potentially close the file, then close will flush and as the
+ * buffer pointer is nonzero, will re-call into this code here. In
+ * the end result, we than have a problem (and things are screwed
+ * up). So we reset the buffer pointer first, and all this can
+ * not happen. It is safe to do so, because that pointer is NOT
+ * used inside the write functions. -- rgerhads, 2010-03-10
+ */
+ pThis->iBufPtr = 0; /* we are at the begin of a new buffer */
if(pThis->bAsyncWrite) {
CHKiRet(doAsyncWriteInternal(pThis, lenBuf));
} else {
CHKiRet(doWriteInternal(pThis, pBuf, lenBuf));
}
- pThis->iBufPtr = 0; /* we are at the begin of a new buffer */
finalize_it:
RETiRet;
diff --git a/runtime/stream.h b/runtime/stream.h
index 89175b0f..369d5a0f 100644
--- a/runtime/stream.h
+++ b/runtime/stream.h
@@ -119,7 +119,6 @@ typedef struct strm_s {
size_t iBufPtr; /* pointer into current buffer */
int iUngetC; /* char set via UngetChar() call or -1 if none set */
bool bInRecord; /* if 1, indicates that we are currently writing a not-yet complete record */
- bool bInClose; /* used to break "deadly close loops", tells us we are already inside a close */
int iZipLevel; /* zip level (0..9). If 0, zip is completely disabled */
Bytef *pZipBuf;
/* support for async flush procesing */
diff --git a/tests/diskqueue.sh b/tests/diskqueue.sh
index 8233d569..ad512ee8 100755
--- a/tests/diskqueue.sh
+++ b/tests/diskqueue.sh
@@ -6,6 +6,9 @@
# This file is part of the rsyslog project, released under GPLv3
# uncomment for debugging support:
echo diskqueue.sh: testing queue disk-only mode
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="log"
source $srcdir/diag.sh init
source $srcdir/diag.sh startup diskqueue.conf
# 20000 messages should be enough - the disk test is slow enough ;)