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