summaryrefslogtreecommitdiff
path: root/src/log.cpp
diff options
context:
space:
mode:
authorEkdohibs <nathanael.courant@laposte.net>2016-04-21 10:45:42 +0200
committerparamat <mat.gregory@virginmedia.com>2016-04-21 10:15:17 +0100
commitc350cfb50b3bf81c075a80307adb15393ea773d0 (patch)
tree141921a19662a79cc3943d730f87c413e6c9c6eb /src/log.cpp
parent5c32c5e945275c612c10021bbd2117a73a97fc3f (diff)
downloadminetest-c350cfb50b3bf81c075a80307adb15393ea773d0.tar.gz
minetest-c350cfb50b3bf81c075a80307adb15393ea773d0.tar.bz2
minetest-c350cfb50b3bf81c075a80307adb15393ea773d0.zip
Make logging use a fixed-length buffer to avoid race conditions.
Previously, race conditions occurred inside logging, that caused segfaults because a thread was trying to use an old pointer that was freed when the string was reallocated. Using a fixed-length buffer avoids this, at the cost of cutting too long messages over seveal lines.
Diffstat (limited to 'src/log.cpp')
-rw-r--r--src/log.cpp24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/log.cpp b/src/log.cpp
index 600e715c1..589cfd909 100644
--- a/src/log.cpp
+++ b/src/log.cpp
@@ -34,9 +34,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cerrno>
#include <cstring>
+const int BUFFER_LENGTH = 256;
+
class StringBuffer : public std::streambuf {
public:
- StringBuffer() {}
+ StringBuffer() {
+ buffer_index = 0;
+ }
int overflow(int c);
virtual void flush(const std::string &buf) = 0;
@@ -44,7 +48,8 @@ public:
void push_back(char c);
private:
- std::string buffer;
+ char buffer[BUFFER_LENGTH];
+ int buffer_index;
};
@@ -338,11 +343,18 @@ std::streamsize StringBuffer::xsputn(const char *s, std::streamsize n)
void StringBuffer::push_back(char c)
{
if (c == '\n' || c == '\r') {
- if (!buffer.empty())
- flush(buffer);
- buffer.clear();
+ if (buffer_index)
+ flush(std::string(buffer, buffer_index));
+ buffer_index = 0;
} else {
- buffer.push_back(c);
+ int index = buffer_index;
+ buffer[index++] = c;
+ if (index >= BUFFER_LENGTH) {
+ flush(std::string(buffer, buffer_index));
+ buffer_index = 0;
+ } else {
+ buffer_index = index;
+ }
}
}