forked from Mirrorlandia_minetest/minetest
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.
This commit is contained in:
parent
5c32c5e945
commit
c350cfb50b
24
src/log.cpp
24
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user