Skip to content

Commit

Permalink
SKA-477 inotify limits (#12)
Browse files Browse the repository at this point in the history
* SKA-477: unique inotify instance per mode

* SKA-477: update refactoring

* SKA-477: clean and optimize manager and adapter classes

* SKA-477: refactore code

* SKA-477: feedbacks took into account + refacto
  • Loading branch information
VKyllianAubry authored and GitHub Enterprise committed Apr 26, 2024
1 parent ab5632d commit afce11e
Show file tree
Hide file tree
Showing 17 changed files with 315 additions and 284 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ else()
message(FATAL_ERROR "Something went wrong : Could not find SIL Kit package.")
endif()

set(compile_options
#-g -O0 # Compile options for valgrind
set(compile_options
-pedantic -Wall -Wextra
-Wcast-align -Wformat=2
-Wshadow -Wsign-promo -Wstrict-overflow=5
Expand Down
17 changes: 15 additions & 2 deletions adapter/IOAdapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,32 @@

#include <vector>

#include "silkit/SilKit.hpp"
#include "silkit/services/logging/all.hpp"
#include "silkit/services/pubsub/all.hpp"

// Interface for handling one data
class IOAdapter
{
public:
// Sil Kit logger
SilKit::Services::Logging::ILogger* _logger;

// Sil Kit pub/sub
SilKit::Services::PubSub::IDataPublisher* _publisher;
SilKit::Services::PubSub::IDataSubscriber* _subscriber;

// Publisher and subscriber topics
std::string _publishTopic{};
std::string _subscribeTopic{};

virtual ~IOAdapter() = default;

virtual void Publish() = 0;
// Serialize internal values
virtual auto Serialize() -> std::vector<uint8_t> = 0;
// Deserialize all received values
virtual void Deserialize(const std::vector<uint8_t>& bytes) = 0;
// Handler to receive events
virtual void ReceiveEvent() = 0;

// Create an associate data subscriber can be done in a specific method
virtual void CreateDataSubscriber() {};
Expand Down
5 changes: 4 additions & 1 deletion adapter/IOManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
class IOManager
{
public:
// Sil Kit logger
SilKit::Services::Logging::ILogger* _logger;

virtual ~IOManager() = default;

// Initialize the adapters from YAML configuration file
virtual void InitAdaptersFromConfigFile(const YAML::Node& configFile,
std::vector<std::shared_ptr<IOAdapter>>& ioAdapters,
std::vector<std::unique_ptr<IOAdapter>>& ioAdapters,
SilKit::IParticipant* participant) = 0;

virtual void Stop() = 0;
Expand Down
5 changes: 3 additions & 2 deletions adapter/SilKitAdapterGenericLinuxIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <thread>
#include <vector>
#include <chrono>
#include <iostream>

#include "IOAdapter.hpp"
#include "IOManager.hpp"
Expand Down Expand Up @@ -122,7 +123,7 @@ int main(int argc, char** argv)

// Initialize chip and values
std::vector<std::unique_ptr<IOManager>> ioManagers;
std::vector<std::shared_ptr<IOAdapter>> ioAdapters;
std::vector<std::unique_ptr<IOAdapter>> ioAdapters;

if (configFile["advalues"])
{
Expand All @@ -147,7 +148,7 @@ int main(int argc, char** argv)

// Stop all io_contexts and threads
std::for_each(ioManagers.begin(), ioManagers.end(), [](const auto& manager){ manager->Stop(); });

auto runningStateFuture = runningStatePromise.get_future();
auto futureStatus = runningStateFuture.wait_for(15s);
if (futureStatus != std::future_status::ready)
Expand Down
10 changes: 5 additions & 5 deletions advalues/adapter/AdAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
AdAdapter::AdAdapter(SilKit::IParticipant* participant,
const std::string& publisherName,
const std::string& subscriberName,
std::unique_ptr<PubSubSpec> pubDataSpec,
std::unique_ptr<PubSubSpec> subDataSpec,
PubSubSpec* pubDataSpec,
PubSubSpec* subDataSpec,
const std::string& pathToCharDev,
asio::io_context* ioc,
const std::string& dataType) :
ChardevAdapter(participant, publisherName, subscriberName, std::move(pubDataSpec), std::move(subDataSpec), pathToCharDev, ioc),
const std::string& dataType,
int inotifyFd) :
ChardevAdapter(participant, publisherName, subscriberName, std::move(pubDataSpec), std::move(subDataSpec), pathToCharDev, inotifyFd),
_strDataType(dataType)
{
static std::unordered_map<std::string, EnumTypes> map {
Expand Down
38 changes: 22 additions & 16 deletions advalues/adapter/AdAdapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

#pragma once

#include "../../chardev/adapter/ChardevAdapter.hpp"

#include <sstream>
#include <stdexcept>
#include <limits>

#include "../../chardev/adapter/ChardevAdapter.hpp"

#include "silkit/SilKit.hpp"
#include "silkit/services/pubsub/all.hpp"

#include <asio/posix/stream_descriptor.hpp>
#include "asio/posix/stream_descriptor.hpp"

// Each file has a specific AdAdapter
class AdAdapter : public ChardevAdapter
Expand All @@ -22,41 +22,47 @@ enum EnumTypes {enum_int8_t, enum_uint8_t, enum_int16_t, enum_uint16_t,
enum_int32_t, enum_uint32_t, enum_int64_t, enum_uint64_t, enum_float, enum_double};

public:
friend class AdManager;

AdAdapter() = delete;
AdAdapter(SilKit::IParticipant* participant,
const std::string& publisherName,
const std::string& subscriberName,
std::unique_ptr<PubSubSpec> pubDataSpec,
std::unique_ptr<PubSubSpec> subDataSpec,
PubSubSpec* pubDataSpec,
PubSubSpec* subDataSpec,
const std::string& pathToCharDev,
asio::io_context* ioc,
const std::string& dataType);
const std::string& dataType,
int inotifyFd);

private:
EnumTypes _dataType;
std::string _strDataType;

// Serialize chip values
auto Serialize() -> std::vector<uint8_t> override;
// Deserialize received values
void Deserialize(const std::vector<uint8_t>& bytes) override;

private:
EnumTypes _dataType;
std::string _strDataType;

// Converting and checking values
template<typename T>
inline T bufferFromChardevTo();
inline auto bufferFromChardevTo() -> T;

template<typename T, typename U>
inline void throwIfInvalid(const T max, const T lowest, const U value);

template<typename T, typename U>
inline T isValidData(const std::string& str);
inline auto isValidData(const std::string& str) -> T;

void strContainsOnly(const std::string& str, const std::string& allowedChars, bool isFloatingNumber = false, bool isSigned = false);
auto strWithoutNewLine(const std::string& str) -> std::string;
};

// Inline implementations
////////////////////////////
// Inline implementations //
////////////////////////////

template<typename T>
T AdAdapter::bufferFromChardevTo()
auto AdAdapter::bufferFromChardevTo() -> T
{
std::string str(_bufferFromChardev.begin(), _bufferFromChardev.end());
std::stringstream val(str);
Expand All @@ -75,7 +81,7 @@ void AdAdapter::throwIfInvalid(const T max, const T lowest, const U value)
}

template<typename T, typename U>
T AdAdapter::isValidData(const std::string& str)
auto AdAdapter::isValidData(const std::string& str) -> T
{
static const std::string strNum{"0123456789"};

Expand Down
53 changes: 20 additions & 33 deletions advalues/adapter/AdManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
#include "AdManager.hpp"

#include <algorithm>
#include <sys/inotify.h>

#include "AdAdapter.hpp"
#include "../../util/Exceptions.hpp"

#include "yaml-cpp/yaml.h"

#include "silkit/util/serdes/Serialization.hpp"

#include "asio/read.hpp"

using namespace adapters;
using namespace SilKit::Services::PubSub;

Expand All @@ -21,34 +23,17 @@ static const std::vector<std::string> types
{"int8_t", "uint8_t", "int16_t", "uint16_t", "int32_t", "uint32_t", "int64_t", "uint64_t", "float", "double"};

AdManager::AdManager(const YAML::Node& configFile,
std::vector<std::shared_ptr<IOAdapter>>& ioAdapters,
std::vector<std::unique_ptr<IOAdapter>>& ioAdapters,
SilKit::Services::Logging::ILogger* logger,
SilKit::IParticipant* participant) :
_logger(logger)
ChardevManager(logger)
{
// Initialize values from config file
InitAdaptersFromConfigFile(configFile, ioAdapters, participant);
}

AdManager::~AdManager()
{
Stop();
}

void AdManager::Stop()
{
if (!_ioc.stopped())
{
_ioc.stop();
}
if (_thread.joinable())
{
_thread.join();
}
}

void AdManager::InitAdaptersFromConfigFile(const YAML::Node& configFile,
std::vector<std::shared_ptr<IOAdapter>>& ioAdapters,
std::vector<std::unique_ptr<IOAdapter>>& ioAdapters,
SilKit::IParticipant* participant)
{
std::vector<std::vector<Util::DataYAMLConfig>> advaluesYAMLConfigs;
Expand Down Expand Up @@ -77,21 +62,23 @@ void AdManager::InitAdaptersFromConfigFile(const YAML::Node& configFile,
publisherName = "pub" + fileValuesYaml.fileName;
}

auto newAdapter = std::make_shared<AdAdapter>(participant,
publisherName,
subscriberName,
std::move(pubDataSpec),
std::move(subDataSpec),
fileValuesYaml.path + fileValuesYaml.fileName,
&_ioc,
fileValuesYaml.dataType);

newAdapter->Initialize();
auto newAdapter = std::make_unique<AdAdapter>(participant,
publisherName,
subscriberName,
pubDataSpec.get(),
subDataSpec.get(),
fileValuesYaml.path + fileValuesYaml.fileName,
fileValuesYaml.dataType,
_inotifyFd);

ioAdapters.push_back(newAdapter);
_wdAdapter[newAdapter->_wd] = newAdapter.get();

ioAdapters.push_back(std::move(newAdapter));
}
}

ReceiveEvent();

_thread = std::thread([&]() -> void {
_ioc.run();
});
Expand Down Expand Up @@ -178,4 +165,4 @@ void AdManager::FillAdvaluesYAML(const YAML::Node& mainNode, std::vector<Util::D
throw YamlError("Missing mandatory 'files' attribute.");
}
}
}
}
24 changes: 10 additions & 14 deletions advalues/adapter/AdManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,38 @@

#include <vector>
#include <memory>
#include <unordered_map>

#include "AdAdapter.hpp"

#include "./../adapter/IOAdapter.hpp"
#include "../../adapter/IOManager.hpp"
#include "../../chardev/adapter/ChardevManager.hpp"

#include "../../util/YamlHelper.hpp"

#include "silkit/SilKit.hpp"
#include "silkit/services/logging/all.hpp"

#include <asio/posix/stream_descriptor.hpp>
#include "asio/posix/stream_descriptor.hpp"

// Manage all advalues adapters (initialize, events identification)
class AdManager : public IOManager
class AdManager : public ChardevManager
{
public:
AdManager() = delete;
AdManager(const YAML::Node& configFile,
std::vector<std::shared_ptr<IOAdapter>>& ioAdapters,
std::vector<std::unique_ptr<IOAdapter>>& ioAdapters,
SilKit::Services::Logging::ILogger* logger,
SilKit::IParticipant* participant);
~AdManager();

void Stop() override;
~AdManager() = default;

private:
// Get chip config from YAML file and initialize all chardev adapters
void InitAdaptersFromConfigFile(const YAML::Node& configFile,
std::vector<std::shared_ptr<IOAdapter>>& ioAdapters,
std::vector<std::unique_ptr<IOAdapter>>& ioAdapters,
SilKit::IParticipant* participant) override;

private:
// Ioc to handle every character devices
asio::io_context _ioc;
std::thread _thread;

SilKit::Services::Logging::ILogger* _logger;

// Get all informations from YAML configuration file
void GetYamlConfig(const YAML::Node& doc, std::vector<std::vector<adapters::Util::DataYAMLConfig>>& dataYAMLConfigs);
void FillAdvaluesYAML(const YAML::Node& mainNode, std::vector<adapters::Util::DataYAMLConfig>& advaluesYAMLConfigs, const std::string& dataType);
Expand Down
Loading

0 comments on commit afce11e

Please sign in to comment.