Skip to content

Commit 126c18e

Browse files
authored
Fix some data races (#890)
1 parent 6362cfc commit 126c18e

File tree

8 files changed

+69
-50
lines changed

8 files changed

+69
-50
lines changed

include/effectengine/Effect.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <utils/Components.h>
1919
#include <utils/Image.h>
2020

21+
#include <atomic>
22+
2123
class Hyperion;
2224
class Logger;
2325

@@ -88,7 +90,7 @@ class Effect : public QThread
8890

8991
Logger *_log;
9092
// Reflects whenever this effects should interupt (timeout or external request)
91-
bool _interupt = false;
93+
std::atomic<bool> _interupt {};
9294

9395
QSize _imageSize;
9496
QImage _image;

include/hyperion/Hyperion.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,6 @@ class Hyperion : public QObject
7979
///
8080
const quint8 & getInstanceIndex() { return _instIndex; }
8181

82-
///
83-
/// Returns the number of attached leds
84-
///
85-
unsigned getLedCount() const;
86-
8782
///
8883
/// @brief Return the size of led grid
8984
///
@@ -92,8 +87,6 @@ class Hyperion : public QObject
9287
/// gets the methode how image is maped to leds
9388
const int & getLedMappingType();
9489

95-
int getLatchTime() const;
96-
9790
/// forward smoothing config
9891
unsigned addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0);
9992
unsigned updateSmoothingConfig(unsigned id, int settlingTime_ms=200, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0);
@@ -113,6 +106,12 @@ class Hyperion : public QObject
113106
LedDevice * getActiveDevice() const;
114107

115108
public slots:
109+
int getLatchTime() const;
110+
111+
///
112+
/// Returns the number of attached leds
113+
///
114+
unsigned getLedCount() const;
116115

117116
///
118117
/// @brief Register a new input by priority, the priority is not active (timeout -100 isn't muxer recognized) until you start to update the data with setInput()

include/webserver/WebServer.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,6 @@ class WebServer : public QObject {
3939
void start();
4040
void stop();
4141

42-
quint16 getPort() const { return _port; }
43-
44-
/// check if server has been inited
45-
bool isInited() const { return _inited; }
46-
47-
///
48-
/// @brief Set a new description, if empty the description is NotFound for clients
49-
///
50-
void setSSDPDescription(const QString & desc);
51-
5242
signals:
5343
///
5444
/// @emits whenever server is started or stopped (to sync with SSDPHandler)
@@ -78,6 +68,16 @@ public slots:
7868
///
7969
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
8070

71+
///
72+
/// @brief Set a new description, if empty the description is NotFound for clients
73+
///
74+
void setSSDPDescription(const QString & desc);
75+
76+
/// check if server has been inited
77+
bool isInited() const { return _inited; }
78+
79+
quint16 getPort() const { return _port; }
80+
8181
private:
8282
QJsonDocument _config;
8383
bool _useSsl;

libsrc/effectengine/Effect.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ Effect::Effect(Hyperion *hyperion, int priority, int timeout, const QString &scr
5353

5454
Effect::~Effect()
5555
{
56+
requestInterruption();
57+
wait();
58+
5659
delete _painter;
5760
_imageStack.clear();
5861
}
@@ -82,10 +85,14 @@ void Effect::run()
8285
PyModule_AddObject(module, "__effectObj", PyCapsule_New((void*)this, "hyperion.__effectObj", nullptr));
8386

8487
// add ledCount variable to the interpreter
85-
PyObject_SetAttrString(module, "ledCount", Py_BuildValue("i", _hyperion->getLedCount()));
88+
unsigned ledCount = 0;
89+
QMetaObject::invokeMethod(_hyperion, "getLedCount", Qt::BlockingQueuedConnection, Q_RETURN_ARG(unsigned, ledCount));
90+
PyObject_SetAttrString(module, "ledCount", Py_BuildValue("i", ledCount));
8691

8792
// add minimumWriteTime variable to the interpreter
88-
PyObject_SetAttrString(module, "latchTime", Py_BuildValue("i", _hyperion->getLatchTime()));
93+
int latchTime = 0;
94+
QMetaObject::invokeMethod(_hyperion, "getLatchTime", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, latchTime));
95+
PyObject_SetAttrString(module, "latchTime", Py_BuildValue("i", latchTime));
8996

9097
// add a args variable to the interpreter
9198
PyObject_SetAttrString(module, "args", EffectModule::json2python(_args));

libsrc/effectengine/EffectModule.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ PyObject* EffectModule::wrapSetColor(PyObject *self, PyObject *args)
144144
{
145145
getEffect()->_colors.fill(color);
146146
QVector<ColorRgb> _cQV = getEffect()->_colors;
147-
getEffect()->setInput(getEffect()->_priority, std::vector<ColorRgb>( _cQV.begin(), _cQV.end() ), timeout, false);
147+
emit getEffect()->setInput(getEffect()->_priority, std::vector<ColorRgb>( _cQV.begin(), _cQV.end() ), timeout, false);
148148
Py_RETURN_NONE;
149149
}
150150
return nullptr;
@@ -163,7 +163,7 @@ PyObject* EffectModule::wrapSetColor(PyObject *self, PyObject *args)
163163
char * data = PyByteArray_AS_STRING(bytearray);
164164
memcpy(getEffect()->_colors.data(), data, length);
165165
QVector<ColorRgb> _cQV = getEffect()->_colors;
166-
getEffect()->setInput(getEffect()->_priority, std::vector<ColorRgb>( _cQV.begin(), _cQV.end() ), timeout, false);
166+
emit getEffect()->setInput(getEffect()->_priority, std::vector<ColorRgb>( _cQV.begin(), _cQV.end() ), timeout, false);
167167
Py_RETURN_NONE;
168168
}
169169
else
@@ -218,7 +218,7 @@ PyObject* EffectModule::wrapSetImage(PyObject *self, PyObject *args)
218218
Image<ColorRgb> image(width, height);
219219
char * data = PyByteArray_AS_STRING(bytearray);
220220
memcpy(image.memptr(), data, length);
221-
getEffect()->setInputImage(getEffect()->_priority, image, timeout, false);
221+
emit getEffect()->setInputImage(getEffect()->_priority, image, timeout, false);
222222
Py_RETURN_NONE;
223223
}
224224
else
@@ -375,7 +375,7 @@ PyObject* EffectModule::wrapImageShow(PyObject *self, PyObject *args)
375375
}
376376

377377
memcpy(image.memptr(), binaryImage.data(), binaryImage.size());
378-
getEffect()->setInputImage(getEffect()->_priority, image, timeout, false);
378+
emit getEffect()->setInputImage(getEffect()->_priority, image, timeout, false);
379379

380380
return Py_BuildValue("");
381381
}

libsrc/ssdp/SSDPHandler.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ void SSDPHandler::initServer()
5454
}
5555

5656
// startup if localAddress is found
57-
if(!_localAddress.isEmpty() && _webserver->isInited())
57+
bool isInited = false;
58+
QMetaObject::invokeMethod(_webserver, "isInited", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, isInited));
59+
60+
if(!_localAddress.isEmpty() && isInited)
5861
{
5962
handleWebServerStateChange(true);
6063
}
@@ -100,14 +103,14 @@ void SSDPHandler::handleWebServerStateChange(const bool newState)
100103
if(newState)
101104
{
102105
// refresh info
103-
_webserver->setSSDPDescription(buildDesc());
106+
QMetaObject::invokeMethod(_webserver, "setSSDPDescription", Qt::BlockingQueuedConnection, Q_ARG(QString, buildDesc()));
104107
setDescriptionAddress(getDescAddress());
105108
if(start())
106109
sendAnnounceList(true);
107110
}
108111
else
109112
{
110-
_webserver->setSSDPDescription("");
113+
QMetaObject::invokeMethod(_webserver, "setSSDPDescription", Qt::BlockingQueuedConnection, Q_ARG(QString, ""));
111114
sendAnnounceList(false);
112115
stop();
113116
}
@@ -124,7 +127,7 @@ void SSDPHandler::handleNetworkConfigurationChanged(const QNetworkConfiguration
124127

125128
// update desc & notify new ip
126129
_localAddress = localAddress;
127-
_webserver->setSSDPDescription(buildDesc());
130+
QMetaObject::invokeMethod(_webserver, "setSSDPDescription", Qt::BlockingQueuedConnection, Q_ARG(QString, buildDesc()));
128131
setDescriptionAddress(getDescAddress());
129132
sendAnnounceList(true);
130133
}
@@ -177,7 +180,9 @@ QString SSDPHandler::getDescAddress() const
177180

178181
QString SSDPHandler::getBaseAddress() const
179182
{
180-
return QString("http://%1:%2/").arg(_localAddress).arg(_webserver->getPort());
183+
quint16 port = 0;
184+
QMetaObject::invokeMethod(_webserver, "getPort", Qt::BlockingQueuedConnection, Q_RETURN_ARG(quint16, port));
185+
return QString("http://%1:%2/").arg(_localAddress).arg(port);
181186
}
182187

183188
QString SSDPHandler::buildDesc() const
@@ -195,3 +200,4 @@ void SSDPHandler::sendAnnounceList(const bool alive)
195200
alive ? SSDPServer::sendAlive(entry) : SSDPServer::sendByeBye(entry);
196201
}
197202
}
203+

libsrc/webserver/WebServer.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
// netUtil
1313
#include <utils/NetUtils.h>
1414

15-
1615
WebServer::WebServer(const QJsonDocument& config, const bool& useSsl, QObject * parent)
1716
: QObject(parent)
1817
, _config(config)

src/hyperiond/hyperiond.cpp

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -175,31 +175,32 @@ void HyperionDaemon::freeObjects()
175175

176176
// destroy network first as a client might want to access hyperion
177177
delete _jsonServer;
178-
_flatBufferServer->thread()->quit();
179-
_flatBufferServer->thread()->wait(1000);
180-
delete _flatBufferServer->thread();
181-
delete _flatBufferServer;
182178

183-
_protoServer->thread()->quit();
184-
_protoServer->thread()->wait(1000);
185-
delete _protoServer->thread();
186-
delete _protoServer;
179+
auto flatBufferServerThread = _flatBufferServer->thread();
180+
flatBufferServerThread->quit();
181+
flatBufferServerThread->wait();
182+
delete flatBufferServerThread;
183+
184+
auto protoServerThread = _protoServer->thread();
185+
protoServerThread->quit();
186+
protoServerThread->wait();
187+
delete protoServerThread;
187188

188189
//ssdp before webserver
189-
_ssdp->thread()->quit();
190-
_ssdp->thread()->wait(1000);
191-
delete _ssdp->thread();
192-
delete _ssdp;
190+
auto ssdpThread = _ssdp->thread();
191+
ssdpThread->quit();
192+
ssdpThread->wait();
193+
delete ssdpThread;
193194

194-
_webserver->thread()->quit();
195-
_webserver->thread()->wait(1000);
196-
delete _webserver->thread();
197-
delete _webserver;
195+
auto webserverThread =_webserver->thread();
196+
webserverThread->quit();
197+
webserverThread->wait();
198+
delete webserverThread;
198199

199-
_sslWebserver->thread()->quit();
200-
_sslWebserver->thread()->wait(1000);
201-
delete _sslWebserver->thread();
202-
delete _sslWebserver;
200+
auto sslWebserverThread =_sslWebserver->thread();
201+
sslWebserverThread->quit();
202+
sslWebserverThread->wait();
203+
delete sslWebserverThread;
203204

204205
#ifdef ENABLE_CEC
205206
_cecHandler->thread()->quit();
@@ -247,6 +248,7 @@ void HyperionDaemon::startNetworkServices()
247248
fbThread->setObjectName("FlatBufferServerThread");
248249
_flatBufferServer->moveToThread(fbThread);
249250
connect(fbThread, &QThread::started, _flatBufferServer, &FlatBufferServer::initServer);
251+
connect(fbThread, &QThread::finished, _flatBufferServer, &FlatBufferServer::deleteLater);
250252
connect(this, &HyperionDaemon::settingsChanged, _flatBufferServer, &FlatBufferServer::handleSettingsUpdate);
251253
fbThread->start();
252254

@@ -256,6 +258,7 @@ void HyperionDaemon::startNetworkServices()
256258
pThread->setObjectName("ProtoServerThread");
257259
_protoServer->moveToThread(pThread);
258260
connect(pThread, &QThread::started, _protoServer, &ProtoServer::initServer);
261+
connect(pThread, &QThread::finished, _protoServer, &ProtoServer::deleteLater);
259262
connect(this, &HyperionDaemon::settingsChanged, _protoServer, &ProtoServer::handleSettingsUpdate);
260263
pThread->start();
261264

@@ -265,6 +268,7 @@ void HyperionDaemon::startNetworkServices()
265268
wsThread->setObjectName("WebServerThread");
266269
_webserver->moveToThread(wsThread);
267270
connect(wsThread, &QThread::started, _webserver, &WebServer::initServer);
271+
connect(wsThread, &QThread::finished, _webserver, &WebServer::deleteLater);
268272
connect(this, &HyperionDaemon::settingsChanged, _webserver, &WebServer::handleSettingsUpdate);
269273
wsThread->start();
270274

@@ -274,6 +278,7 @@ void HyperionDaemon::startNetworkServices()
274278
sslWsThread->setObjectName("SSLWebServerThread");
275279
_sslWebserver->moveToThread(sslWsThread);
276280
connect(sslWsThread, &QThread::started, _sslWebserver, &WebServer::initServer);
281+
connect(sslWsThread, &QThread::finished, _sslWebserver, &WebServer::deleteLater);
277282
connect(this, &HyperionDaemon::settingsChanged, _sslWebserver, &WebServer::handleSettingsUpdate);
278283
sslWsThread->start();
279284

@@ -283,6 +288,7 @@ void HyperionDaemon::startNetworkServices()
283288
ssdpThread->setObjectName("SSDPThread");
284289
_ssdp->moveToThread(ssdpThread);
285290
connect(ssdpThread, &QThread::started, _ssdp, &SSDPHandler::initServer);
291+
connect(ssdpThread, &QThread::finished, _ssdp, &SSDPHandler::deleteLater);
286292
connect(_webserver, &WebServer::stateChange, _ssdp, &SSDPHandler::handleWebServerStateChange);
287293
connect(this, &HyperionDaemon::settingsChanged, _ssdp, &SSDPHandler::handleSettingsUpdate);
288294
ssdpThread->start();

0 commit comments

Comments
 (0)