Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 7b51b7b

Browse files
committed
Logger should be thread safe
1 parent ea1b59b commit 7b51b7b

File tree

12 files changed

+348
-317
lines changed

12 files changed

+348
-317
lines changed

Libs/libLogger/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ SET( SRC_FILES
1515
LogTemplate.cpp
1616
LogManager.cpp
1717
LogConsumer.cpp
18+
Internal.cpp
1819
)
1920

2021
SET( PUB_HDR_FILES
@@ -29,7 +30,7 @@ SET( PUB_HDR_FILES
2930
)
3031

3132
SET( PRI_HDR_FILES
32-
33+
Internal.hpp
3334
)
3435

3536
SET( HDR_FILES ${PRI_HDR_FILES} ${PUB_HDR_FILES} )

Libs/libLogger/Internal.cpp

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
* MacGitver
3+
* Copyright (C) 2012-2015 The MacGitver-Developers <dev@macgitver.org>
4+
*
5+
* (C) Sascha Cunz <sascha@cunz-rad.com>
6+
* (C) Cunz RaD Ltd.
7+
*
8+
* This program is free software; you can redistribute it and/or modify it under the terms of the
9+
* GNU General Public License (Version 2) as published by the Free Software Foundation.
10+
*
11+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
12+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License along with this program; if
16+
* not, see <http://www.gnu.org/licenses/>.
17+
*
18+
*/
19+
20+
#include "libLogger/Internal.hpp"
21+
22+
#include "libLogger/LogChannel.hpp"
23+
#include "libLogger/LogConsumer.hpp"
24+
#include "libLogger/LogEvent.hpp"
25+
#include "libLogger/LogTemplate.hpp"
26+
27+
#include <QObject>
28+
29+
namespace Log
30+
{
31+
32+
System::System()
33+
: mNextId(1)
34+
, mConsumer(nullptr)
35+
{
36+
createDefaultChannels();
37+
}
38+
39+
System::~System()
40+
{
41+
}
42+
43+
44+
void System::release()
45+
{
46+
sSelf.reset();
47+
}
48+
49+
System::Ptr System::sSelf;
50+
51+
System::Ptr System::self()
52+
{
53+
if (!sSelf) {
54+
sSelf = new System;
55+
}
56+
return sSelf;
57+
}
58+
59+
/**
60+
* @internal
61+
* @brief create the default channels
62+
*
63+
* This method sets up the default channels that are used for convenience logging.
64+
*
65+
*/
66+
void System::createDefaultChannels()
67+
{
68+
Channel ch = Channel::create(CHNAME_ERROR);
69+
ch.setDisplayName(QObject::trUtf8("Errors", "Channelname"));
70+
71+
Template t = Template::create(CHNAME_ERROR);
72+
t.setTransformation(QStringLiteral("<span style=\"color: red;\">$$</span>"));
73+
ch.setDefaultTemplate(t);
74+
addTemplate(t);
75+
76+
addChannel(ch);
77+
78+
ch = Channel::create(CHNAME_WARNING);
79+
ch.setDisplayName(QObject::trUtf8("Warnings", "Channelname"));
80+
81+
t = Template::create(CHNAME_WARNING);
82+
t.setTransformation(QStringLiteral("<span style=\"color: yellow;\">$$</span>"));
83+
addTemplate(t);
84+
ch.setDefaultTemplate(t);
85+
86+
addChannel(ch);
87+
88+
ch = Channel::create(CHNAME_INFO);
89+
ch.setDisplayName(QObject::trUtf8("Infos", "Channelname"));
90+
91+
t = Template::create(CHNAME_INFO);
92+
t.setTransformation(QStringLiteral("<span style=\"color: blue;\">$$</span>"));
93+
addTemplate(t);
94+
ch.setDefaultTemplate(t);
95+
96+
addChannel(ch);
97+
98+
ch = Channel::create(CHNAME_DEBUG);
99+
ch.setDisplayName(QObject::trUtf8("Debug", "Channelname"));
100+
101+
t = Template::create(CHNAME_DEBUG);
102+
t.setTransformation(QStringLiteral("<span style=\"color: navy;\">$$</span>"));
103+
addTemplate(t);
104+
ch.setDefaultTemplate(t);
105+
106+
addChannel(ch);
107+
108+
ch = Channel::create(CHNAME_NORMAL);
109+
ch.setDisplayName(QObject::trUtf8("Default output", "Channelname"));
110+
111+
t = Template::create(CHNAME_NORMAL);
112+
t.setTransformation(QStringLiteral("$$"));
113+
addTemplate(t);
114+
ch.setDefaultTemplate(t);
115+
116+
addChannel(ch);
117+
}
118+
119+
/**
120+
* @internal
121+
* @brief Inform log consumer of new event
122+
*
123+
* @param[in] event The new event that was added to a channel.
124+
*
125+
* This method is internally called from the Channel when a new Event was added to it. If a
126+
* Consumer is installed, it will be informed about the new event.
127+
*
128+
*/
129+
void System::eventAdded(const Event& event)
130+
{
131+
QMutexLocker l(&mMtx);
132+
133+
if (Consumer* c = mConsumer) {
134+
l.unlock();
135+
c->eventAdded(event);
136+
}
137+
}
138+
139+
void System::addTemplate(const Template& t)
140+
{
141+
QMutexLocker l(&mMtx);
142+
mTemplates.insert(t.name(), t);
143+
}
144+
145+
Template System::findTemplate(const QString& name) const
146+
{
147+
QMutexLocker l(&mMtx);
148+
return mTemplates.value(name, Template());
149+
}
150+
151+
void System::addChannel(const Channel& ch)
152+
{
153+
QMutexLocker l(&mMtx);
154+
mChannels.insert(ch.name(), ch);
155+
156+
if (Consumer* c = mConsumer) {
157+
l.unlock();
158+
c->channelAdded(ch);
159+
}
160+
}
161+
162+
Channel System::findChannel(const QString& name) const
163+
{
164+
QMutexLocker l(&mMtx);
165+
return mChannels.value(name, Channel());
166+
}
167+
168+
System::ChannelList System::channels() const
169+
{
170+
ChannelList l;
171+
172+
foreach (const Channel& c, mChannels) {
173+
l << c;
174+
}
175+
176+
return l;
177+
}
178+
179+
void System::setConsumer(Consumer* consumer)
180+
{
181+
QMutexLocker l(&mMtx);
182+
183+
if (consumer) {
184+
if (mConsumer != consumer) {
185+
if (mConsumer) {
186+
qDebug("A Log-Consumer was already set...");
187+
}
188+
mConsumer = consumer;
189+
}
190+
}
191+
else {
192+
mConsumer = nullptr;
193+
}
194+
}
195+
196+
Consumer* System::consumer() const
197+
{
198+
QMutexLocker l(&mMtx);
199+
return mConsumer;
200+
}
201+
202+
/**
203+
* @internal
204+
* @brief Get tne next event id
205+
*
206+
* @return The next available unique id for events.
207+
*
208+
*/
209+
quint64 System::nextLogEventId()
210+
{
211+
QMutexLocker l(&mMtx);
212+
return mNextId++;
213+
}
214+
215+
216+
}

Libs/libLogger/Internal.hpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* MacGitver
3+
* Copyright (C) 2012-2015 The MacGitver-Developers <dev@macgitver.org>
4+
*
5+
* (C) Sascha Cunz <sascha@cunz-rad.com>
6+
* (C) Cunz RaD Ltd.
7+
*
8+
* This program is free software; you can redistribute it and/or modify it under the terms of the
9+
* GNU General Public License (Version 2) as published by the Free Software Foundation.
10+
*
11+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
12+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License along with this program; if
16+
* not, see <http://www.gnu.org/licenses/>.
17+
*
18+
*/
19+
20+
#pragma once
21+
22+
#include <QHash>
23+
#include <QString>
24+
#include <QSharedData>
25+
#include <QMutex>
26+
27+
#define CHNAME_DEBUG QStringLiteral("Debug")
28+
#define CHNAME_NORMAL QStringLiteral("Normal")
29+
#define CHNAME_ERROR QStringLiteral("Error")
30+
#define CHNAME_INFO QStringLiteral("Info")
31+
#define CHNAME_WARNING QStringLiteral("Warning")
32+
33+
namespace Log
34+
{
35+
36+
class Template;
37+
class Channel;
38+
class Event;
39+
class Consumer;
40+
41+
class System
42+
: public QSharedData
43+
{
44+
public:
45+
using Ptr = QExplicitlySharedDataPointer<System>;
46+
using Templates = QHash<QString, Template>;
47+
using Channels = QHash<QString, Channel>;
48+
using ChannelList = QVector<Channel>;
49+
50+
public:
51+
System();
52+
~System();
53+
54+
public:
55+
void release();
56+
static Ptr self();
57+
58+
public:
59+
quint64 nextLogEventId();
60+
void createDefaultChannels();
61+
void eventAdded(const Event& event);
62+
63+
void addTemplate(const Template& t);
64+
Template findTemplate(const QString& name) const;
65+
66+
void addChannel(const Channel& ch);
67+
Channel findChannel(const QString& name) const;
68+
ChannelList channels() const;
69+
70+
void setConsumer(Consumer* consumer);
71+
Consumer* consumer() const;
72+
73+
private:
74+
static Ptr sSelf;
75+
mutable QMutex mMtx;
76+
quint64 mNextId;
77+
Consumer* mConsumer;
78+
Templates mTemplates;
79+
Channels mChannels;
80+
};
81+
82+
}

Libs/libLogger/LogChannel.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "libLogger/LogManager.hpp"
2727
#include "libLogger/LogTemplate.hpp"
2828

29+
#include "libLogger/Internal.hpp"
30+
2931
namespace Log
3032
{
3133

@@ -174,7 +176,7 @@ namespace Log
174176
event.setChannel(d.data());
175177
d->events.append(event);
176178

177-
log().eventAdded(event);
179+
System::self()->eventAdded(event);
178180
}
179181
}
180182

Libs/libLogger/LogEvent.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "libLogger/LogManager.hpp"
2828
#include "libLogger/LogTemplate.hpp"
2929

30+
#include "libLogger/Internal.hpp"
31+
3032
namespace Log
3133
{
3234

@@ -168,7 +170,7 @@ namespace Log
168170
*/
169171
Event Event::create(const QString& templ)
170172
{
171-
Template t = log().findTemplate(templ);
173+
Template t = System::self()->findTemplate(templ);
172174

173175
if (!t.isValid()) {
174176
return Event();
@@ -341,7 +343,7 @@ namespace Log
341343
{
342344
channel = NULL;
343345
timeStamp = QDateTime::currentDateTime();
344-
id = log().nextLogEventId();
346+
id = System::self()->nextLogEventId();
345347
}
346348

347349
}

0 commit comments

Comments
 (0)