fix a deadlock or sporadic crash during shutdown
This commit is contained in:
@@ -21,15 +21,14 @@ namespace aman {
|
||||
*/
|
||||
class AircraftReporter {
|
||||
private:
|
||||
bool m_initialized;
|
||||
zmq::socket_t m_socket;
|
||||
std::unique_ptr<zmq::socket_t> m_socket;
|
||||
|
||||
AircraftReporter() noexcept;
|
||||
|
||||
template <typename T>
|
||||
bool setSocketKey(const std::string& key, T entry) {
|
||||
try {
|
||||
this->m_socket.set(entry, key);
|
||||
this->m_socket->set(entry, key);
|
||||
return true;
|
||||
}
|
||||
catch (std::exception&) {
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
#include <aman/config/IdentifierFileFormat.h>
|
||||
|
||||
#include <protobuf/AircraftReport.pb.h>
|
||||
#include <zmq.h>
|
||||
|
||||
#include "com/ZmqContext.h"
|
||||
#include "PlugIn.h"
|
||||
|
||||
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
|
||||
@@ -59,6 +61,8 @@ PlugIn::PlugIn() :
|
||||
return;
|
||||
}
|
||||
|
||||
ZmqContext::instance().initialize();
|
||||
|
||||
if (false == AircraftReporter::instance().initialize(this->m_configuration)) {
|
||||
this->DisplayUserMessage(PLUGIN_NAME, "ERROR", "Unable to initialize the reporter-connection to the backend", true, true, true, true, true);
|
||||
return;
|
||||
@@ -67,6 +71,7 @@ PlugIn::PlugIn() :
|
||||
|
||||
PlugIn::~PlugIn() noexcept {
|
||||
AircraftReporter::instance().deinitialize();
|
||||
ZmqContext::instance().deinitialize();
|
||||
google::protobuf::ShutdownProtobufLibrary();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,16 @@
|
||||
using namespace aman;
|
||||
|
||||
AircraftReporter::AircraftReporter() noexcept :
|
||||
m_initialized(false),
|
||||
m_socket() { }
|
||||
|
||||
bool AircraftReporter::initialize(const Communication& configuration) {
|
||||
if (true == this->m_initialized || false == configuration.valid)
|
||||
return this->m_initialized;
|
||||
if (nullptr != this->m_socket)
|
||||
return true;
|
||||
if (false == configuration.valid)
|
||||
return false;
|
||||
|
||||
this->m_socket = zmq::socket_t(ZmqContext::context(), zmq::socket_type::pub);
|
||||
this->m_socket.set(zmq::sockopt::immediate, true);
|
||||
this->m_socket = std::make_unique<zmq::socket_t>(ZmqContext::instance().context(), zmq::socket_type::pub);
|
||||
this->m_socket->set(zmq::sockopt::immediate, true);
|
||||
|
||||
/* configure the encryption */
|
||||
if (false == this->setSocketKey(configuration.serverPublicIdentifier, zmq::sockopt::curve_serverkey))
|
||||
@@ -36,32 +37,34 @@ bool AircraftReporter::initialize(const Communication& configuration) {
|
||||
|
||||
/* connect to the server */
|
||||
try {
|
||||
this->m_socket.connect("tcp://" + configuration.address + ":" + std::to_string(configuration.portReporter));
|
||||
this->m_socket->connect("tcp://" + configuration.address + ":" + std::to_string(configuration.portReporter));
|
||||
}
|
||||
catch (zmq::error_t&) {
|
||||
this->m_socket = std::unique_ptr<zmq::socket_t>();
|
||||
return false;
|
||||
}
|
||||
|
||||
this->m_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AircraftReporter::deinitialize() {
|
||||
if (false == this->m_initialized)
|
||||
if (nullptr == this->m_socket)
|
||||
return true;
|
||||
|
||||
this->m_socket.close();
|
||||
this->m_socket->close();
|
||||
this->m_socket = std::make_unique<zmq::socket_t>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AircraftReporter::send(zmq::message_t& message) {
|
||||
bool retval = false;
|
||||
|
||||
if (true == this->m_initialized) {
|
||||
if (nullptr != this->m_socket) {
|
||||
try {
|
||||
auto bla = message.size();
|
||||
auto result = this->m_socket.send(message, zmq::send_flags::none);
|
||||
retval = result.value() == bla;
|
||||
auto size = message.size();
|
||||
auto result = this->m_socket->send(message, zmq::send_flags::none);
|
||||
retval = result.value() == size;
|
||||
}
|
||||
catch (zmq::error_t&) {
|
||||
return false;
|
||||
|
||||
@@ -13,8 +13,23 @@
|
||||
|
||||
using namespace aman;
|
||||
|
||||
static zmq::context_t __context(2);
|
||||
ZmqContext::ZmqContext() : m_context() { }
|
||||
|
||||
void ZmqContext::initialize() {
|
||||
if (nullptr == this->m_context)
|
||||
this->m_context = std::make_unique<zmq::context_t>(2);
|
||||
}
|
||||
|
||||
void ZmqContext::deinitialize() {
|
||||
if (nullptr != this->m_context)
|
||||
this->m_context = std::unique_ptr<zmq::context_t>();
|
||||
}
|
||||
|
||||
zmq::context_t& ZmqContext::context() {
|
||||
return __context;
|
||||
return *this->m_context;
|
||||
}
|
||||
|
||||
ZmqContext& ZmqContext::instance() {
|
||||
static ZmqContext __instance;
|
||||
return __instance;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <zmq.hpp>
|
||||
|
||||
namespace aman {
|
||||
@@ -15,11 +17,25 @@ namespace aman {
|
||||
* @brief Handles the ZMQ context information
|
||||
*/
|
||||
class ZmqContext {
|
||||
private:
|
||||
ZmqContext();
|
||||
|
||||
std::unique_ptr<zmq::context_t> m_context;
|
||||
|
||||
public:
|
||||
ZmqContext(const ZmqContext&) = delete;
|
||||
ZmqContext(ZmqContext&&) = delete;
|
||||
ZmqContext& operator=(const ZmqContext&) = delete;
|
||||
ZmqContext& operator=(ZmqContext&&) = delete;
|
||||
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
|
||||
/**
|
||||
* @brief Returns the system wide context
|
||||
* @return The ZMQ context
|
||||
*/
|
||||
static zmq::context_t& context();
|
||||
zmq::context_t& context();
|
||||
static ZmqContext& instance();
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user