Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some data races #890

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/effectengine/Effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <utils/Components.h>
#include <utils/Image.h>

#include <atomic>

class Hyperion;
class Logger;

Expand Down Expand Up @@ -88,7 +90,7 @@ class Effect : public QThread

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

QSize _imageSize;
QImage _image;
Expand Down
13 changes: 6 additions & 7 deletions include/hyperion/Hyperion.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,6 @@ class Hyperion : public QObject
///
const quint8 & getInstanceIndex() { return _instIndex; }

///
/// Returns the number of attached leds
///
unsigned getLedCount() const;

///
/// @brief Return the size of led grid
///
Expand All @@ -92,8 +87,6 @@ class Hyperion : public QObject
/// gets the methode how image is maped to leds
const int & getLedMappingType();

int getLatchTime() const;

/// forward smoothing config
unsigned addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0);
unsigned updateSmoothingConfig(unsigned id, int settlingTime_ms=200, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0);
Expand All @@ -113,6 +106,12 @@ class Hyperion : public QObject
LedDevice * getActiveDevice() const;

public slots:
int getLatchTime() const;

///
/// Returns the number of attached leds
///
unsigned getLedCount() const;

///
/// @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()
Expand Down
20 changes: 10 additions & 10 deletions include/webserver/WebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,6 @@ class WebServer : public QObject {
void start();
void stop();

quint16 getPort() const { return _port; }

/// check if server has been inited
bool isInited() const { return _inited; }

///
/// @brief Set a new description, if empty the description is NotFound for clients
///
void setSSDPDescription(const QString & desc);

signals:
///
/// @emits whenever server is started or stopped (to sync with SSDPHandler)
Expand Down Expand Up @@ -78,6 +68,16 @@ public slots:
///
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);

///
/// @brief Set a new description, if empty the description is NotFound for clients
///
void setSSDPDescription(const QString & desc);

/// check if server has been inited
bool isInited() const { return _inited; }

quint16 getPort() const { return _port; }

private:
QJsonDocument _config;
bool _useSsl;
Expand Down
11 changes: 9 additions & 2 deletions libsrc/effectengine/Effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ Effect::Effect(Hyperion *hyperion, int priority, int timeout, const QString &scr

Effect::~Effect()
{
requestInterruption();
wait();

delete _painter;
_imageStack.clear();
}
Expand Down Expand Up @@ -82,10 +85,14 @@ void Effect::run()
PyModule_AddObject(module, "__effectObj", PyCapsule_New((void*)this, "hyperion.__effectObj", nullptr));

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

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

// add a args variable to the interpreter
PyObject_SetAttrString(module, "args", EffectModule::json2python(_args));
Expand Down
8 changes: 4 additions & 4 deletions libsrc/effectengine/EffectModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ PyObject* EffectModule::wrapSetColor(PyObject *self, PyObject *args)
{
getEffect()->_colors.fill(color);
QVector<ColorRgb> _cQV = getEffect()->_colors;
getEffect()->setInput(getEffect()->_priority, std::vector<ColorRgb>( _cQV.begin(), _cQV.end() ), timeout, false);
emit getEffect()->setInput(getEffect()->_priority, std::vector<ColorRgb>( _cQV.begin(), _cQV.end() ), timeout, false);
Py_RETURN_NONE;
}
return nullptr;
Expand All @@ -163,7 +163,7 @@ PyObject* EffectModule::wrapSetColor(PyObject *self, PyObject *args)
char * data = PyByteArray_AS_STRING(bytearray);
memcpy(getEffect()->_colors.data(), data, length);
QVector<ColorRgb> _cQV = getEffect()->_colors;
getEffect()->setInput(getEffect()->_priority, std::vector<ColorRgb>( _cQV.begin(), _cQV.end() ), timeout, false);
emit getEffect()->setInput(getEffect()->_priority, std::vector<ColorRgb>( _cQV.begin(), _cQV.end() ), timeout, false);
Py_RETURN_NONE;
}
else
Expand Down Expand Up @@ -218,7 +218,7 @@ PyObject* EffectModule::wrapSetImage(PyObject *self, PyObject *args)
Image<ColorRgb> image(width, height);
char * data = PyByteArray_AS_STRING(bytearray);
memcpy(image.memptr(), data, length);
getEffect()->setInputImage(getEffect()->_priority, image, timeout, false);
emit getEffect()->setInputImage(getEffect()->_priority, image, timeout, false);
Py_RETURN_NONE;
}
else
Expand Down Expand Up @@ -375,7 +375,7 @@ PyObject* EffectModule::wrapImageShow(PyObject *self, PyObject *args)
}

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

return Py_BuildValue("");
}
Expand Down
16 changes: 11 additions & 5 deletions libsrc/ssdp/SSDPHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ void SSDPHandler::initServer()
}

// startup if localAddress is found
if(!_localAddress.isEmpty() && _webserver->isInited())
bool isInited = false;
QMetaObject::invokeMethod(_webserver, "isInited", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, isInited));

if(!_localAddress.isEmpty() && isInited)
{
handleWebServerStateChange(true);
}
Expand Down Expand Up @@ -100,14 +103,14 @@ void SSDPHandler::handleWebServerStateChange(const bool newState)
if(newState)
{
// refresh info
_webserver->setSSDPDescription(buildDesc());
QMetaObject::invokeMethod(_webserver, "setSSDPDescription", Qt::BlockingQueuedConnection, Q_ARG(QString, buildDesc()));
setDescriptionAddress(getDescAddress());
if(start())
sendAnnounceList(true);
}
else
{
_webserver->setSSDPDescription("");
QMetaObject::invokeMethod(_webserver, "setSSDPDescription", Qt::BlockingQueuedConnection, Q_ARG(QString, ""));
sendAnnounceList(false);
stop();
}
Expand All @@ -124,7 +127,7 @@ void SSDPHandler::handleNetworkConfigurationChanged(const QNetworkConfiguration

// update desc & notify new ip
_localAddress = localAddress;
_webserver->setSSDPDescription(buildDesc());
QMetaObject::invokeMethod(_webserver, "setSSDPDescription", Qt::BlockingQueuedConnection, Q_ARG(QString, buildDesc()));
setDescriptionAddress(getDescAddress());
sendAnnounceList(true);
}
Expand Down Expand Up @@ -177,7 +180,9 @@ QString SSDPHandler::getDescAddress() const

QString SSDPHandler::getBaseAddress() const
{
return QString("http://%1:%2/").arg(_localAddress).arg(_webserver->getPort());
quint16 port = 0;
QMetaObject::invokeMethod(_webserver, "getPort", Qt::BlockingQueuedConnection, Q_RETURN_ARG(quint16, port));
return QString("http://%1:%2/").arg(_localAddress).arg(port);
}

QString SSDPHandler::buildDesc() const
Expand All @@ -195,3 +200,4 @@ void SSDPHandler::sendAnnounceList(const bool alive)
alive ? SSDPServer::sendAlive(entry) : SSDPServer::sendByeBye(entry);
}
}

1 change: 0 additions & 1 deletion libsrc/webserver/WebServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
// netUtil
#include <utils/NetUtils.h>


WebServer::WebServer(const QJsonDocument& config, const bool& useSsl, QObject * parent)
: QObject(parent)
, _config(config)
Expand Down
46 changes: 26 additions & 20 deletions src/hyperiond/hyperiond.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,31 +168,32 @@ void HyperionDaemon::freeObjects()

// destroy network first as a client might want to access hyperion
delete _jsonServer;
_flatBufferServer->thread()->quit();
_flatBufferServer->thread()->wait(1000);
delete _flatBufferServer->thread();
delete _flatBufferServer;

_protoServer->thread()->quit();
_protoServer->thread()->wait(1000);
delete _protoServer->thread();
delete _protoServer;
auto flatBufferServerThread = _flatBufferServer->thread();
flatBufferServerThread->quit();
flatBufferServerThread->wait();
delete flatBufferServerThread;

auto protoServerThread = _protoServer->thread();
protoServerThread->quit();
protoServerThread->wait();
delete protoServerThread;

//ssdp before webserver
_ssdp->thread()->quit();
_ssdp->thread()->wait(1000);
delete _ssdp->thread();
delete _ssdp;
auto ssdpThread = _ssdp->thread();
ssdpThread->quit();
ssdpThread->wait();
delete ssdpThread;

_webserver->thread()->quit();
_webserver->thread()->wait(1000);
delete _webserver->thread();
delete _webserver;
auto webserverThread =_webserver->thread();
webserverThread->quit();
webserverThread->wait();
delete webserverThread;

_sslWebserver->thread()->quit();
_sslWebserver->thread()->wait(1000);
delete _sslWebserver->thread();
delete _sslWebserver;
auto sslWebserverThread =_sslWebserver->thread();
sslWebserverThread->quit();
sslWebserverThread->wait();
delete sslWebserverThread;

// stop Hyperions (non blocking)
_instanceManager->stopAll();
Expand Down Expand Up @@ -236,6 +237,7 @@ void HyperionDaemon::startNetworkServices()
fbThread->setObjectName("FlatBufferServerThread");
_flatBufferServer->moveToThread(fbThread);
connect(fbThread, &QThread::started, _flatBufferServer, &FlatBufferServer::initServer);
connect(fbThread, &QThread::finished, _flatBufferServer, &FlatBufferServer::deleteLater);
connect(this, &HyperionDaemon::settingsChanged, _flatBufferServer, &FlatBufferServer::handleSettingsUpdate);
fbThread->start();

Expand All @@ -245,6 +247,7 @@ void HyperionDaemon::startNetworkServices()
pThread->setObjectName("ProtoServerThread");
_protoServer->moveToThread(pThread);
connect(pThread, &QThread::started, _protoServer, &ProtoServer::initServer);
connect(pThread, &QThread::finished, _protoServer, &ProtoServer::deleteLater);
connect(this, &HyperionDaemon::settingsChanged, _protoServer, &ProtoServer::handleSettingsUpdate);
pThread->start();

Expand All @@ -254,6 +257,7 @@ void HyperionDaemon::startNetworkServices()
wsThread->setObjectName("WebServerThread");
_webserver->moveToThread(wsThread);
connect(wsThread, &QThread::started, _webserver, &WebServer::initServer);
connect(wsThread, &QThread::finished, _webserver, &WebServer::deleteLater);
connect(this, &HyperionDaemon::settingsChanged, _webserver, &WebServer::handleSettingsUpdate);
wsThread->start();

Expand All @@ -263,6 +267,7 @@ void HyperionDaemon::startNetworkServices()
sslWsThread->setObjectName("SSLWebServerThread");
_sslWebserver->moveToThread(sslWsThread);
connect(sslWsThread, &QThread::started, _sslWebserver, &WebServer::initServer);
connect(sslWsThread, &QThread::finished, _sslWebserver, &WebServer::deleteLater);
connect(this, &HyperionDaemon::settingsChanged, _sslWebserver, &WebServer::handleSettingsUpdate);
sslWsThread->start();

Expand All @@ -272,6 +277,7 @@ void HyperionDaemon::startNetworkServices()
ssdpThread->setObjectName("SSDPThread");
_ssdp->moveToThread(ssdpThread);
connect(ssdpThread, &QThread::started, _ssdp, &SSDPHandler::initServer);
connect(ssdpThread, &QThread::finished, _ssdp, &SSDPHandler::deleteLater);
connect(_webserver, &WebServer::stateChange, _ssdp, &SSDPHandler::handleWebServerStateChange);
connect(this, &HyperionDaemon::settingsChanged, _ssdp, &SSDPHandler::handleSettingsUpdate);
ssdpThread->start();
Expand Down