Skip to content

Commit

Permalink
libdeng2: Protect log entries against multithreaded access
Browse files Browse the repository at this point in the history
The libdeng2 Log is a multithreaded system. Entries may be created in
any thread, and they get collected into a central LogBuffer. The buffer
is flushed whenever a new entry triggers the flush condition, which
means flushing may occur from any thread.

Log entry arguments are appended after the creation of the entry and
even after it has been inserted to the buffer. Therefore it is possible
that an entry is being flushed while another thread is still adding
arguments to it.

This scenario is now handled by locking the entry while it is being
converted to text or while an argument is being added.
  • Loading branch information
skyjake committed Dec 4, 2012
1 parent bafde25 commit 367db83
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 1 deletion.
4 changes: 3 additions & 1 deletion doomsday/libdeng2/include/de/core/log.h
Expand Up @@ -270,7 +270,7 @@ class DENG2_PUBLIC Log
*
* @ingroup core
*/
class DENG2_PUBLIC LogEntry
class DENG2_PUBLIC LogEntry : public Lockable
{
public:
/**
Expand Down Expand Up @@ -434,7 +434,9 @@ class DENG2_PUBLIC LogEntry
template <typename ValueType>
inline LogEntry &operator << (ValueType const &v) {
if(!_disabled) {
lock();
_args.push_back(new Arg(v));
unlock();
}
return *this;
}
Expand Down
5 changes: 5 additions & 0 deletions doomsday/libdeng2/src/core/log.cpp
Expand Up @@ -21,6 +21,7 @@
#include "de/Time"
#include "de/Date"
#include "de/LogBuffer"
#include "de/Guard"
#include "logtextstyle.h"

#include <QMap>
Expand Down Expand Up @@ -76,6 +77,8 @@ LogEntry::LogEntry(Log::LogLevel level, String const &section, int sectionDepth,

LogEntry::~LogEntry()
{
DENG2_GUARD(this); // cannot delete if someone has a lock

for(Args::iterator i = _args.begin(); i != _args.end(); ++i)
{
delete *i;
Expand All @@ -84,6 +87,8 @@ LogEntry::~LogEntry()

String LogEntry::asText(Flags const &formattingFlags, int shortenSection) const
{
DENG2_GUARD(this); // others shouldn't touch the entry while we're converting

/// @todo This functionality belongs in an entry formatter class.

Flags flags = formattingFlags;
Expand Down

0 comments on commit 367db83

Please sign in to comment.