* Author : Maxim Mamontov <faust@stargazer.dp.ua>
*/
-#ifndef __STG_SGCONF_ACTION_H__
-#define __STG_SGCONF_ACTION_H__
+#pragma once
#include <string>
#include <map>
public:
virtual ~ACTION() {}
- virtual ACTION * Clone() const = 0;
virtual std::string ParamDescription() const = 0;
virtual std::string DefaultDescription() const = 0;
virtual OPTION_BLOCK & Suboptions() = 0;
virtual PARSER_STATE Parse(int argc, char ** argv, void * data = NULL) = 0;
virtual void ParseValue(const std::string &) {}
- class ERROR : public std::runtime_error
+ struct ERROR : std::runtime_error
{
- public:
- ERROR(const std::string & message)
- : std::runtime_error(message.c_str()) {}
+ explicit ERROR(const std::string & message)
+ : std::runtime_error(message.c_str()) {}
};
};
} // namespace SGCONF
-
-#endif
class FUNC0_ACTION : public ACTION
{
public:
- FUNC0_ACTION(const F & func) : m_func(func) {}
+ explicit FUNC0_ACTION(const F & func) : m_func(func) {}
- virtual ACTION * Clone() const { return new FUNC0_ACTION<F>(*this); }
-
- virtual std::string ParamDescription() const { return ""; }
- virtual std::string DefaultDescription() const { return ""; }
- virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/)
+ std::string ParamDescription() const override { return ""; }
+ std::string DefaultDescription() const override { return ""; }
+ OPTION_BLOCK & Suboptions() override { return m_suboptions; }
+ PARSER_STATE Parse(int argc, char ** argv, void * /*data*/) override
{
- m_func();
- return PARSER_STATE(true, argc, argv);
+ m_func();
+ return PARSER_STATE(true, argc, argv);
}
private:
template <typename F>
inline
-FUNC0_ACTION<F> * MakeFunc0Action(F func)
+std::unique_ptr<ACTION> MakeFunc0Action(F func)
{
-return new FUNC0_ACTION<F>(func);
+return std::make_unique<FUNC0_ACTION<F>>(func);
}
template <typename T>
m_description(paramDescription),
m_hasDefault(true)
{}
- PARAM_ACTION(STG::Optional<T> & param)
+ explicit PARAM_ACTION(STG::Optional<T> & param)
: m_param(param),
m_hasDefault(false)
{}
m_hasDefault(false)
{}
- virtual ACTION * Clone() const { return new PARAM_ACTION<T>(*this); }
-
- virtual std::string ParamDescription() const { return m_description; }
- virtual std::string DefaultDescription() const;
- virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/);
- virtual void ParseValue(const std::string & value);
+ std::string ParamDescription() const override { return m_description; }
+ std::string DefaultDescription() const override;
+ OPTION_BLOCK & Suboptions() override { return m_suboptions; }
+ PARSER_STATE Parse(int argc, char ** argv, void * /*data*/) override;
+ void ParseValue(const std::string & value) override;
private:
STG::Optional<T> & m_param;
template <typename T>
inline
-PARAM_ACTION<T> * MakeParamAction(STG::Optional<T> & param,
- const T & defaultValue,
- const std::string & paramDescription)
+std::unique_ptr<ACTION> MakeParamAction(STG::Optional<T> & param,
+ const T & defaultValue,
+ const std::string & paramDescription)
{
-return new PARAM_ACTION<T>(param, defaultValue, paramDescription);
+return std::make_unique<PARAM_ACTION<T>>(param, defaultValue, paramDescription);
}
template <typename T>
inline
-PARAM_ACTION<T> * MakeParamAction(STG::Optional<T> & param)
+std::unique_ptr<ACTION> MakeParamAction(STG::Optional<T> & param)
{
-return new PARAM_ACTION<T>(param);
+return std::make_unique<PARAM_ACTION<T>>(param);
}
template <typename T>
inline
-PARAM_ACTION<T> * MakeParamAction(STG::Optional<T> & param,
- const std::string & paramDescription)
+std::unique_ptr<ACTION> MakeParamAction(STG::Optional<T> & param,
+ const std::string & paramDescription)
{
-return new PARAM_ACTION<T>(param, paramDescription);
+return std::make_unique<PARAM_ACTION<T>>(param, paramDescription);
}
class KV_ACTION : public ACTION
m_description(paramDescription)
{}
- virtual ACTION * Clone() const { return new KV_ACTION(*this); }
-
- virtual std::string ParamDescription() const { return m_description; }
- virtual std::string DefaultDescription() const { return ""; }
- virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv, void * data);
+ std::string ParamDescription() const override { return m_description; }
+ std::string DefaultDescription() const override { return ""; }
+ OPTION_BLOCK & Suboptions() override { return m_suboptions; }
+ PARSER_STATE Parse(int argc, char ** argv, void * data) override;
private:
std::string m_name;
}
inline
-KV_ACTION * MakeKVAction(const std::string & name,
- const std::string & paramDescription)
+std::unique_ptr<ACTION> MakeKVAction(const std::string & name,
+ const std::string & paramDescription)
{
-return new KV_ACTION(name, paramDescription);
+return std::make_unique<KV_ACTION>(name, paramDescription);
}
} // namespace SGCONF
m_funPtr(funPtr)
{}
- virtual ACTION * Clone() const { return new API_ACTION(*this); }
-
- virtual std::string ParamDescription() const { return m_description; }
- virtual std::string DefaultDescription() const { return ""; }
- virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/);
+ std::string ParamDescription() const override { return m_description; }
+ std::string DefaultDescription() const override { return ""; }
+ OPTION_BLOCK & Suboptions() override { return m_suboptions; }
+ PARSER_STATE Parse(int argc, char ** argv, void * /*data*/) override;
private:
COMMANDS & m_commands;
};
inline
-ACTION * MakeAPIAction(COMMANDS & commands,
+std::unique_ptr<ACTION> MakeAPIAction(COMMANDS & commands,
const std::string & paramDescription,
const std::vector<API_ACTION::PARAM> & params,
API_FUNCTION funPtr)
{
-return new API_ACTION(commands, paramDescription, true, params, funPtr);
+return std::make_unique<API_ACTION>(commands, paramDescription, true, params, funPtr);
}
inline
-ACTION * MakeAPIAction(COMMANDS & commands,
+std::unique_ptr<ACTION> MakeAPIAction(COMMANDS & commands,
const std::vector<API_ACTION::PARAM> & params,
API_FUNCTION funPtr)
{
-return new API_ACTION(commands, "", false, params, funPtr);
+return std::make_unique<API_ACTION>(commands, "", false, params, funPtr);
}
inline
-ACTION * MakeAPIAction(COMMANDS & commands,
+std::unique_ptr<ACTION> MakeAPIAction(COMMANDS & commands,
const std::string & paramDescription,
API_FUNCTION funPtr)
{
-return new API_ACTION(commands, paramDescription, true, funPtr);
+return std::make_unique<API_ACTION>(commands, paramDescription, true, funPtr);
}
inline
-ACTION * MakeAPIAction(COMMANDS & commands,
+std::unique_ptr<ACTION> MakeAPIAction(COMMANDS & commands,
API_FUNCTION funPtr)
{
-return new API_ACTION(commands, "", false, funPtr);
+return std::make_unique<API_ACTION>(commands, "", false, funPtr);
}
}
class FUNC1_ADAPTER : public std::unary_function<A, R>
{
public:
- FUNC1_ADAPTER(R (*func)(A)) : m_func(func) {}
+ explicit FUNC1_ADAPTER(R (*func)(A)) : m_func(func) {}
const R operator()(A arg) const { return (m_func)(arg); }
private:
R (*m_func)(A);
m_description(paramDescription)
{}
- virtual ACTION * Clone() const { return new CONFIG_ACTION(*this); }
-
- virtual std::string ParamDescription() const { return m_description; }
- virtual std::string DefaultDescription() const { return ""; }
- virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/);
+ std::string ParamDescription() const override { return m_description; }
+ std::string DefaultDescription() const override { return ""; }
+ OPTION_BLOCK & Suboptions() override { return m_suboptions; }
+ PARSER_STATE Parse(int argc, char ** argv, void * /*data*/) override;
private:
SGCONF::CONFIG & m_config;
}
}
-inline
-CONFIG_ACTION * MakeParamAction(SGCONF::CONFIG & config,
- const std::string & paramDescription)
+std::unique_ptr<SGCONF::ACTION> MakeParamAction(SGCONF::CONFIG & config,
+ const std::string & paramDescription)
{
-return new CONFIG_ACTION(config, paramDescription);
+return std::make_unique<CONFIG_ACTION>(config, paramDescription);
}
} // namespace SGCONF
template <class C>
void ReadConfigFile(const std::string & filePath, void (C::* callback)(const std::string&, const std::string&), C * obj)
{
-std::ifstream stream(filePath.c_str());
-std::string line;
-size_t num = 0;
-while (std::getline(stream, line))
+ std::ifstream stream(filePath.c_str());
+ std::string line;
+ size_t num = 0;
+ while (std::getline(stream, line))
{
- ++num;
- line = Trim(line);
- std::string::size_type pos = line.find_first_of('#');
- if (pos != std::string::npos)
- line = line.substr(0, pos);
- if (line.empty())
- continue;
- pos = line.find_first_of('=');
- if (pos == std::string::npos)
+ ++num;
+ line = Trim(line);
+ std::string::size_type pos = line.find_first_of('#');
+ if (pos != std::string::npos)
+ line = line.substr(0, pos);
+ if (line.empty())
+ continue;
+ pos = line.find_first_of('=');
+ if (pos == std::string::npos)
{
- std::ostringstream error;
- error << "Bad file format, missing '=' in '" << filePath << ":" << num << "'.";
- throw std::runtime_error(error.str().c_str());
+ std::ostringstream error;
+ error << "Bad file format, missing '=' in '" << filePath << ":" << num << "'.";
+ throw std::runtime_error(error.str().c_str());
}
- (obj->*callback)(Trim(line.substr(0, pos)), Trim(line.substr(pos + 1, line.length() - pos - 1)));
+ (obj->*callback)(Trim(line.substr(0, pos)), Trim(line.substr(pos + 1, line.length() - pos - 1)));
}
}
OPTION::OPTION(const std::string & shortName,
const std::string & longName,
- ACTION * action,
+ std::unique_ptr<ACTION> action,
const std::string & description)
: m_shortName(shortName),
m_longName(longName),
- m_action(action),
+ m_action(std::move(action)),
m_description(description)
{
}
OPTION::OPTION(const std::string & longName,
- ACTION * action,
+ std::unique_ptr<ACTION> action,
const std::string & description)
: m_longName(longName),
- m_action(action),
+ m_action(std::move(action)),
m_description(description)
{
}
-OPTION::OPTION(const OPTION & rhs)
- : m_shortName(rhs.m_shortName),
- m_longName(rhs.m_longName),
- m_action(rhs.m_action->Clone()),
- m_description(rhs.m_description)
-{
-}
-
-OPTION::~OPTION()
-{
-delete m_action;
-}
-
-OPTION & OPTION::operator=(const OPTION & rhs)
-{
-m_shortName = rhs.m_shortName;
-m_longName = rhs.m_longName;
-m_action = rhs.m_action->Clone();
-m_description = rhs.m_description;
-return *this;
-}
-
void OPTION::Help(size_t level) const
{
-if (!m_action)
- throw ERROR("Option is not defined.");
-std::string indent(level, '\t');
-std::cout << indent;
-if (!m_shortName.empty())
- std::cout << "-" << m_shortName << ", ";
-std::cout << "--" << m_longName << " " << m_action->ParamDescription()
- << "\t" << m_description << m_action->DefaultDescription() << "\n";
-m_action->Suboptions().Help(level);
+ if (!m_action)
+ throw ERROR("Option is not defined.");
+ std::string indent(level, '\t');
+ std::cout << indent;
+ if (!m_shortName.empty())
+ std::cout << "-" << m_shortName << ", ";
+ std::cout << "--" << m_longName << " " << m_action->ParamDescription()
+ << "\t" << m_description << m_action->DefaultDescription() << "\n";
+ m_action->Suboptions().Help(level);
}
bool OPTION::Check(const char * arg) const
{
-if (arg == NULL)
- return false;
+ if (arg == NULL)
+ return false;
-if (*arg++ != '-')
- return false;
+ if (*arg++ != '-')
+ return false;
-if (*arg == '-')
-{
- return m_longName == arg + 1;
-}
+ if (*arg == '-')
+ return m_longName == arg + 1;
-return m_shortName == arg;
+ return m_shortName == arg;
}
PARSER_STATE OPTION::Parse(int argc, char ** argv, void * data)
{
-if (!m_action)
- throw ERROR("Option is not defined.");
-try
+ if (!m_action)
+ throw ERROR("Option is not defined.");
+ try
{
- return m_action->Parse(argc, argv, data);
+ return m_action->Parse(argc, argv, data);
}
-catch (const ACTION::ERROR & ex)
+ catch (const ACTION::ERROR & ex)
{
- if (m_longName.empty())
- throw ERROR("-" + m_shortName + ": " + ex.what());
- else
- throw m_shortName.empty() ? ERROR("--" + m_longName + ": " + ex.what())
- : ERROR("--" + m_longName + ", -" + m_shortName + ": " + ex.what());
+ if (m_longName.empty())
+ throw ERROR("-" + m_shortName + ": " + ex.what());
+ else
+ throw m_shortName.empty() ? ERROR("--" + m_longName + ": " + ex.what())
+ : ERROR("--" + m_longName + ", -" + m_shortName + ": " + ex.what());
}
}
void OPTION::ParseValue(const std::string & value)
{
-if (!m_action)
- throw ERROR("Option is not defined.");
-try
+ if (!m_action)
+ throw ERROR("Option is not defined.");
+ try
{
- return m_action->ParseValue(value);
+ return m_action->ParseValue(value);
}
-catch (const ACTION::ERROR & ex)
+ catch (const ACTION::ERROR & ex)
{
- throw ERROR(m_longName + ": " + ex.what());
+ throw ERROR(m_longName + ": " + ex.what());
}
}
OPTION_BLOCK & OPTION_BLOCK::Add(const std::string & shortName,
const std::string & longName,
- ACTION * action,
+ std::unique_ptr<ACTION> action,
const std::string & description)
{
-m_options.push_back(OPTION(shortName, longName, action, description));
-return *this;
+ m_options.emplace_back(shortName, longName, std::move(action), description);
+ return *this;
}
OPTION_BLOCK & OPTION_BLOCK::Add(const std::string & longName,
- ACTION * action,
+ std::unique_ptr<ACTION> action,
const std::string & description)
{
-m_options.push_back(OPTION(longName, action, description));
-return *this;
+ m_options.emplace_back(longName, std::move(action), description);
+ return *this;
}
void OPTION_BLOCK::Help(size_t level) const
{
-if (m_options.empty())
- return;
-if (!m_description.empty())
- std::cout << m_description << ":\n";
-std::for_each(m_options.begin(),
- m_options.end(),
- [&level](const auto& opt){ opt.Help(level + 1); });
+ if (m_options.empty())
+ return;
+ if (!m_description.empty())
+ std::cout << m_description << ":\n";
+ for (const auto& option : m_options)
+ option.Help(level + 1);
}
PARSER_STATE OPTION_BLOCK::Parse(int argc, char ** argv, void * data)
{
-PARSER_STATE state(false, argc, argv);
-if (state.argc == 0)
- return state;
-while (state.argc > 0 && !state.stop)
+ PARSER_STATE state(false, argc, argv);
+ if (state.argc == 0)
+ return state;
+ while (state.argc > 0 && !state.stop)
{
- const auto it = std::find_if(m_options.begin(), m_options.end(), [&state](const auto& opt){ return opt.Check(*state.argv); });
- if (it != m_options.end())
- state = it->Parse(--state.argc, ++state.argv, data);
- else
- break;
+ const auto it = std::find_if(m_options.begin(), m_options.end(), [&state](const auto& opt){ return opt.Check(*state.argv); });
+ if (it != m_options.end())
+ state = it->Parse(--state.argc, ++state.argv, data);
+ else
+ break;
}
-return state;
+ return state;
}
void OPTION_BLOCK::ParseFile(const std::string & filePath)
{
-if (access(filePath.c_str(), R_OK))
- throw ERROR("File '" + filePath + "' does not exists.");
-ReadConfigFile(filePath, &OPTION_BLOCK::OptionCallback, this);
+ if (access(filePath.c_str(), R_OK))
+ throw ERROR("File '" + filePath + "' does not exists.");
+ ReadConfigFile(filePath, &OPTION_BLOCK::OptionCallback, this);
}
void OPTION_BLOCK::OptionCallback(const std::string & key, const std::string & value)
{
-for (std::vector<OPTION>::iterator it = m_options.begin(); it != m_options.end(); ++it)
- if (it->Name() == key)
- it->ParseValue(value);
+ for (auto& option : m_options)
+ if (option.Name() == key)
+ option.ParseValue(value);
}
void OPTION_BLOCKS::Help(size_t level) const
{
-std::list<OPTION_BLOCK>::const_iterator it(m_blocks.begin());
-while (it != m_blocks.end())
+ for (const auto& block : m_blocks)
{
- it->Help(level);
- std::cout << "\n";
- ++it;
+ block.Help(level);
+ std::cout << "\n";
}
}
PARSER_STATE OPTION_BLOCKS::Parse(int argc, char ** argv)
{
-PARSER_STATE state(false, argc, argv);
-std::list<OPTION_BLOCK>::iterator it(m_blocks.begin());
-while (state.argc > 0 && !state.stop && it != m_blocks.end())
+ PARSER_STATE state(false, argc, argv);
+ auto it = m_blocks.begin();
+ while (state.argc > 0 && !state.stop && it != m_blocks.end())
{
- state = it->Parse(state.argc, state.argv);
- ++it;
+ state = it->Parse(state.argc, state.argv);
+ ++it;
}
-return state;
+ return state;
}
* Author : Maxim Mamontov <faust@stargazer.dp.ua>
*/
-#ifndef __STG_SGCONF_OPTIONS_H__
-#define __STG_SGCONF_OPTIONS_H__
+#pragma once
#include <string>
#include <vector>
-#include <list>
#include <utility>
#include <stdexcept>
+#include <memory>
#include <cstddef> // size_t
namespace SGCONF
public:
OPTION(const std::string & shortName,
const std::string & longName,
- ACTION * action,
+ std::unique_ptr<ACTION> action,
const std::string & description);
OPTION(const std::string & longName,
- ACTION * action,
+ std::unique_ptr<ACTION> action,
const std::string & description);
- OPTION(const OPTION & rhs);
- ~OPTION();
- OPTION & operator=(const OPTION & rhs);
+ OPTION(OPTION&& rhs) = default;
+ OPTION& operator=(OPTION& rhs) = default;
void Help(size_t level = 0) const;
PARSER_STATE Parse(int argc, char ** argv, void * data);
bool Check(const char * arg) const;
const std::string & Name() const { return m_longName; }
- class ERROR : public std::runtime_error
+ struct ERROR : std::runtime_error
{
- public:
- ERROR(const std::string & message)
- : std::runtime_error(message.c_str()) {}
+ explicit ERROR(const std::string & message)
+ : std::runtime_error(message.c_str()) {}
};
private:
std::string m_shortName;
std::string m_longName;
- ACTION * m_action;
+ std::unique_ptr<ACTION> m_action;
std::string m_description;
};
{
public:
OPTION_BLOCK() {}
- OPTION_BLOCK(const std::string & description)
+ explicit OPTION_BLOCK(const std::string & description)
: m_description(description) {}
+
+ OPTION_BLOCK(OPTION_BLOCK&&) = default;
+ OPTION_BLOCK& operator=(OPTION_BLOCK&&) = default;
+
OPTION_BLOCK & Add(const std::string & shortName,
const std::string & longName,
- ACTION * action,
+ std::unique_ptr<ACTION> action,
const std::string & description);
OPTION_BLOCK & Add(const std::string & longName,
- ACTION * action,
+ std::unique_ptr<ACTION> action,
const std::string & description);
void Help(size_t level) const;
PARSER_STATE Parse(int argc, char ** argv, void * data = NULL);
void ParseFile(const std::string & filePath);
- class ERROR : public std::runtime_error
+ struct ERROR : std::runtime_error
{
- public:
- ERROR(const std::string & message)
- : std::runtime_error(message.c_str()) {}
+ explicit ERROR(const std::string & message)
+ : std::runtime_error(message.c_str()) {}
};
private:
public:
OPTION_BLOCK & Add(const std::string & description)
{ m_blocks.push_back(OPTION_BLOCK(description)); return m_blocks.back(); }
- void Add(const OPTION_BLOCK & block) { m_blocks.push_back(block); }
+ void Add(OPTION_BLOCK&& block) { m_blocks.push_back(std::move(block)); }
void Help(size_t level) const;
PARSER_STATE Parse(int argc, char ** argv);
private:
- std::list<OPTION_BLOCK> m_blocks;
+ std::vector<OPTION_BLOCK> m_blocks;
};
} // namespace SGCONF
-
-#endif
-#ifndef __ACTIONS_H__
-#define __ACTIONS_H__
+#pragma once
// Usage:
//
template <class ACTIVE_CLASS, typename DATA_TYPE>
struct ACTOR
{
-typedef void (ACTIVE_CLASS::*TYPE)(DATA_TYPE);
+ using TYPE = void (ACTIVE_CLASS::*)(DATA_TYPE);
};
// Abstract base action class for polymorphic action invocation
// Concrete generalized action type - an actor with it's data and owner
template <class ACTIVE_CLASS, typename DATA_TYPE>
-class ACTION : public BASE_ACTION,
- public std::unary_function<ACTIVE_CLASS &, void>
+class ACTION : public BASE_ACTION
{
public:
ACTION(ACTIVE_CLASS & ac,
typename ACTOR<ACTIVE_CLASS, DATA_TYPE>::TYPE a,
DATA_TYPE d)
: activeClass(ac), actor(a), data(d) {}
- void Invoke() override;
+ void Invoke() override
+ {
+ (activeClass.*actor)(data);
+ }
private:
ACTION(const ACTION<ACTIVE_CLASS, DATA_TYPE> & rvalue);
ACTION<ACTIVE_CLASS, DATA_TYPE> & operator=(const ACTION<ACTIVE_CLASS, DATA_TYPE> & rvalue);
// A list of an actions
// All methods are thread-safe
-class ACTIONS_LIST : private std::vector<BASE_ACTION *>
+class ACTIONS_LIST
{
public:
- // Just a typedef for parent class
- typedef std::vector<BASE_ACTION *> parent;
+ ~ACTIONS_LIST()
+ {
+ std::lock_guard lock(m_mutex);
+ for (auto action : m_list)
+ delete action;
+ }
- // Initialize mutex
- ACTIONS_LIST();
- // Delete actions and destroy mutex
- virtual ~ACTIONS_LIST();
+ auto begin() { std::lock_guard lock(m_mutex); return m_list.begin(); }
+ auto end() { std::lock_guard lock(m_mutex); return m_list.end(); }
+ auto begin() const { std::lock_guard lock(m_mutex); return m_list.begin(); }
+ auto end() const { std::lock_guard lock(m_mutex); return m_list.end(); }
- parent::iterator begin();
- parent::iterator end();
- parent::const_iterator begin() const;
- parent::const_iterator end() const;
-
- bool empty() const;
- size_t size() const;
- void swap(ACTIONS_LIST & list);
+ bool empty() const { std::lock_guard lock(m_mutex); return m_list.empty(); }
+ size_t size() const { std::lock_guard lock(m_mutex); return m_list.size(); }
+ void swap(ACTIONS_LIST & rhs) { std::lock_guard lock(m_mutex); m_list.swap(rhs.m_list); }
// Add an action to list
template <class ACTIVE_CLASS, typename DATA_TYPE>
void Enqueue(ACTIVE_CLASS & ac,
typename ACTOR<ACTIVE_CLASS, DATA_TYPE>::TYPE a,
- DATA_TYPE d);
+ DATA_TYPE d)
+ {
+ std::lock_guard lock(m_mutex);
+ m_list.push_back(new ACTION<ACTIVE_CLASS, DATA_TYPE>(ac, a, d));
+ }
// Invoke all actions in the list
- void InvokeAll();
+ void InvokeAll()
+ {
+ std::lock_guard lock(m_mutex);
+ for (auto action : m_list)
+ action->Invoke();
+ }
private:
mutable std::mutex m_mutex;
+ std::vector<BASE_ACTION*> m_list;
};
-
-#include "actions.inl.h"
-
-#endif
+++ /dev/null
-#ifndef __ACTIONS_INL_H__
-#define __ACTIONS_INL_H__
-
-#include <algorithm>
-
-#include "stg/locker.h"
-
-// Polymorphick action invocation
-template <class ACTIVE_CLASS, typename DATA_TYPE>
-inline
-void ACTION<ACTIVE_CLASS, DATA_TYPE>::Invoke()
-{
-(activeClass.*actor)(data);
-}
-
-inline
-ACTIONS_LIST::ACTIONS_LIST()
-{
-}
-
-// Delete all actions before deleting list
-inline
-ACTIONS_LIST::~ACTIONS_LIST()
-{
-std::lock_guard lock(m_mutex);
-
-parent::iterator it(parent::begin());
-while (it != parent::end())
- delete *it++;
-}
-
-inline
-ACTIONS_LIST::parent::iterator ACTIONS_LIST::begin()
-{
-std::lock_guard lock(m_mutex);
-return parent::begin();
-}
-
-inline
-ACTIONS_LIST::parent::iterator ACTIONS_LIST::end()
-{
-std::lock_guard lock(m_mutex);
-return parent::end();
-}
-
-inline
-ACTIONS_LIST::parent::const_iterator ACTIONS_LIST::begin() const
-{
-std::lock_guard lock(m_mutex);
-return parent::begin();
-}
-
-inline
-ACTIONS_LIST::parent::const_iterator ACTIONS_LIST::end() const
-{
-std::lock_guard lock(m_mutex);
-return parent::end();
-}
-
-inline
-bool ACTIONS_LIST::empty() const
-{
-std::lock_guard lock(m_mutex);
-return parent::empty();
-}
-
-inline
-size_t ACTIONS_LIST::size() const
-{
-std::lock_guard lock(m_mutex);
-return parent::size();
-}
-
-inline
-void ACTIONS_LIST::swap(ACTIONS_LIST & list)
-{
-std::lock_guard lock(m_mutex);
-parent::swap(list);
-}
-
-template <class ACTIVE_CLASS, typename DATA_TYPE>
-inline
-void ACTIONS_LIST::Enqueue(ACTIVE_CLASS & ac,
- typename ACTOR<ACTIVE_CLASS, DATA_TYPE>::TYPE a,
- DATA_TYPE d)
-{
-std::lock_guard lock(m_mutex);
-push_back(new ACTION<ACTIVE_CLASS, DATA_TYPE>(ac, a, d));
-}
-
-inline
-void ACTIONS_LIST::InvokeAll()
-{
-std::lock_guard lock(m_mutex);
-std::for_each(
- parent::begin(),
- parent::end(),
- [](auto action){ action->Invoke(); });
-}
-
-#endif
-#include <csignal>
-#include <cerrno>
-#include <cstring>
-
-#include "stg/locker.h"
#include "stg/common.h"
#include "eventloop.h"
-EVENT_LOOP::EVENT_LOOP()
- : ACTIONS_LIST(),
- _running(false),
- _stopped(true),
- _tid(),
- _mutex(),
- _condition()
-{
-pthread_mutex_init(&_mutex, NULL);
-pthread_cond_init(&_condition, NULL);
-}
+#include <csignal>
+#include <cerrno>
+#include <cstring>
-EVENT_LOOP::~EVENT_LOOP()
+EVENT_LOOP& EVENT_LOOP::instance()
{
-pthread_cond_destroy(&_condition);
-pthread_mutex_destroy(&_mutex);
+ static EVENT_LOOP el;
+ return el;
}
bool EVENT_LOOP::Start()
{
-_running = true;
-if (pthread_create(&_tid, NULL, Run, this))
- {
- printfd(__FILE__, "EVENT_LOOP::Start - Failed to create thread: '%s'\n", strerror(errno));
- return true;
- }
+m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
return false;
}
bool EVENT_LOOP::Stop()
{
-_running = false;
+m_thread.request_stop();
// Wake up thread
-pthread_cond_signal(&_condition);
-// Wait until thread exit
-pthread_join(_tid, NULL);
+m_cond.notify_all();
+m_thread.join();
return false;
}
-void * EVENT_LOOP::Run(void * self)
-{
-EVENT_LOOP * ev = static_cast<EVENT_LOOP *>(self);
-ev->Runner();
-return NULL;
-}
-
-void EVENT_LOOP::Runner()
+void EVENT_LOOP::Run(std::stop_token token)
{
sigset_t signalSet;
sigfillset(&signalSet);
pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
-_stopped = false;
printfd(__FILE__, "EVENT_LOOP::Runner - Before start\n");
-while (_running)
+while (!token.stop_requested())
{
+ // Create new empty actions list
+ ACTIONS_LIST local;
{
- STG_LOCKER lock(&_mutex);
+ std::unique_lock lock(m_mutex);
// Check for any actions...
- if (empty())
- {
- // ... and sleep until new actions added
- printfd(__FILE__, "EVENT_LOOP::Runner - Sleeping until new actions arrived\n");
- pthread_cond_wait(&_condition, &_mutex);
- }
+ // ... and sleep until new actions added
+ printfd(__FILE__, "EVENT_LOOP::Runner - Sleeping until new actions arrived\n");
+ m_cond.wait(lock);
// Check for running after wake up
- if (!_running)
- {
- // Don't process any actions if stopping
- break;
- }
+ if (token.stop_requested())
+ break; // Don't process any actions if stopping
+ if (!m_list.empty())
+ local.swap(m_list);
}
- // Create new empty actions list
- ACTIONS_LIST local;
// Fast swap with current
- swap(local);
+ m_list.swap(local);
// Invoke all current actions
printfd(__FILE__, "EVENT_LOOP::Runner - Invoke %d actions\n", local.size());
local.InvokeAll();
}
printfd(__FILE__, "EVENT_LOOP::Runner - Before stop\n");
-_stopped = true;
-}
-
-namespace {
-
-pthread_mutex_t singletonMutex;
-
-}
-
-EVENT_LOOP & EVENT_LOOP_SINGLETON::GetInstance()
-{
-// Double-checking technique
-if (!_instance)
- {
- STG_LOCKER lock(&singletonMutex);
- if (!_instance)
- {
- CreateInstance();
- }
- }
-return *_instance;
}
-
-void EVENT_LOOP_SINGLETON::CreateInstance()
-{
-static EVENT_LOOP loop;
-_instance = &loop;
-}
-
-EVENT_LOOP * EVENT_LOOP_SINGLETON::_instance = NULL;
#ifndef __EVENT_LOOP_H__
#define __EVENT_LOOP_H__
-#include <pthread.h>
-
-#include "stg/noncopyable.h"
#include "actions.h"
-class EVENT_LOOP : private NONCOPYABLE,
- private ACTIONS_LIST
+#include <mutex>
+#include <condition_variable>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include <jthread.hpp>
+#pragma GCC diagnostic pop
+
+class EVENT_LOOP
{
public:
+ static EVENT_LOOP& instance();
+
bool Start();
bool Stop();
- bool IsRunning() const { return _running; }
template <class ACTIVE_CLASS, typename DATA_TYPE>
void Enqueue(ACTIVE_CLASS & ac,
typename ACTOR<ACTIVE_CLASS, DATA_TYPE>::TYPE a,
- DATA_TYPE d);
+ DATA_TYPE d)
+ {
+ std::lock_guard lock(m_mutex);
+ // Add new action
+ m_list.Enqueue(ac, a, d);
+ // Signal about new action
+ m_cond.notify_all();
+ }
private:
- bool _running;
- bool _stopped;
- pthread_t _tid;
- pthread_mutex_t _mutex;
- pthread_cond_t _condition;
-
- EVENT_LOOP();
- virtual ~EVENT_LOOP();
-
- static void * Run(void *);
- void Runner();
-
- friend class EVENT_LOOP_SINGLETON;
-};
+ std::jthread m_thread;
+ std::mutex m_mutex;
+ std::condition_variable m_cond;
-class EVENT_LOOP_SINGLETON : private NONCOPYABLE
-{
- public:
- static EVENT_LOOP & GetInstance();
+ ACTIONS_LIST m_list;
- private:
- static EVENT_LOOP * _instance;
- static void CreateInstance();
+ EVENT_LOOP() = default;
- EVENT_LOOP_SINGLETON() {}
- ~EVENT_LOOP_SINGLETON() {}
+ void Run(std::stop_token token);
};
-template <class ACTIVE_CLASS, typename DATA_TYPE>
-void EVENT_LOOP::Enqueue(ACTIVE_CLASS & ac,
- typename ACTOR<ACTIVE_CLASS, DATA_TYPE>::TYPE a,
- DATA_TYPE d)
-{
-STG_LOCKER lock(&_mutex);
-// Add new action
-ACTIONS_LIST::Enqueue(ac, a, d);
-// Signal about new action
-pthread_cond_signal(&_condition);
-}
-
#endif
return -1;
}
- auto& loop = EVENT_LOOP_SINGLETON::GetInstance();
+ auto& loop = EVENT_LOOP::instance();
StoreLoader storeLoader(settings);
if (storeLoader.load())
}
//-----------------------------------------------------------------------------
BPF_CAP::BPF_CAP()
- : nonstop(false),
- isRunning(false),
+ : isRunning(false),
capSock(-1),
traffCnt(NULL),
logger(STG::PluginLogger::get("cap_bpf"))
return -1;
}
-nonstop = true;
-
-if (pthread_create(&thread, NULL, Run, this))
- {
- errorStr = "Cannot create thread.";
- logger("Cannot create thread.");
- printfd(__FILE__, "Cannot create thread\n");
- return -1;
- }
+m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
return 0;
}
BPFCapClose();
-nonstop = false;
+m_thread.request_stop();
//5 seconds to thread stops itself
int i;
//after 5 seconds waiting thread still running. now killing it
if (isRunning)
- {
- //TODO pthread_cancel()
- if (pthread_kill(thread, SIGINT))
- {
- errorStr = "Cannot kill thread.";
- logger("Cannot send signal to thread.");
- printfd(__FILE__, "Cannot kill thread\n");
- return -1;
- }
- }
+ m_thread.detach();
+else
+ m_thread.join();
return 0;
}
//-----------------------------------------------------------------------------
-void * BPF_CAP::Run(void * d)
+void BPF_CAP::Run(std::stop_token token)
{
sigset_t signalSet;
sigfillset(&signalSet);
pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
-BPF_CAP * dc = static_cast<BPF_CAP *>(d);
-dc->isRunning = true;
+isRunning = true;
uint8_t hdr[96]; //68 + 14 + 4(size) + 9(SYS_IFACE) + 1(align to 4) = 96
rpp->dataLen = -1;
char * iface;
-while (dc->nonstop)
+while (!token.stop_requested())
{
- if (dc->BPFCapRead((char*)&hdr, 68 + 14, &iface))
+ if (BPFCapRead((char*)&hdr, 68 + 14, &iface))
continue;
if (!(hdr[12] == 0x8 && hdr[13] == 0x0))
continue;
- dc->traffCnt->process(*rpp);
+ traffCnt->process(*rpp);
}
-dc->isRunning = false;
-return NULL;
+isRunning = false;
}
//-----------------------------------------------------------------------------
int BPF_CAP::BPFCapOpen()
#include <string>
#include <vector>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include <jthread.hpp>
+#pragma GCC diagnostic pop
#include <cstdint>
-#include <pthread.h>
#include <sys/poll.h>
#define BUFF_LEN (128)
BPF_CAP(const BPF_CAP & rvalue);
BPF_CAP & operator=(const BPF_CAP & rvalue);
- static void * Run(void *);
+ void Run(std::stop_token token);
int BPFCapOpen();
int BPFCapOpen(BPF_DATA * bd);
int BPFCapClose();
std::vector<BPF_DATA> bpfData;
std::vector<pollfd> polld;
- pthread_t thread;
- bool nonstop;
+ std::jthread m_thread;
bool isRunning;
int capSock;
STG::ModuleSettings settings;
}
//-----------------------------------------------------------------------------
ETHER_CAP::ETHER_CAP()
- : nonstop(false),
- isRunning(false),
+ : isRunning(false),
capSock(-1),
traffCnt(NULL),
logger(STG::PluginLogger::get("cap_ether"))
return -1;
}
-nonstop = true;
-
-if (pthread_create(&thread, NULL, Run, this))
- {
- errorStr = "Cannot create thread.";
- logger("Cannot create thread.");
- printfd(__FILE__, "Cannot create thread\n");
- return -1;
- }
+m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
return 0;
}
if (!isRunning)
return 0;
-nonstop = false;
+m_thread.request_stop();
//5 seconds to thread stops itself
for (int i = 0; i < 25 && isRunning; i++)
}
//after 5 seconds waiting thread still running. now killing it
if (isRunning)
- {
- if (pthread_kill(thread, SIGUSR1))
- {
- errorStr = "Cannot kill thread.";
- logger("Cannot send signal to thread.");
- return -1;
- }
- for (int i = 0; i < 25 && isRunning; ++i)
- {
- struct timespec ts = {0, 200000000};
- nanosleep(&ts, NULL);
- }
- if (isRunning)
- {
- errorStr = "ETHER_CAP not stopped.";
- logger("Cannot stop thread.");
- printfd(__FILE__, "Cannot stop thread\n");
- return -1;
- }
- else
- {
- pthread_join(thread, NULL);
- }
- }
+ m_thread.detach();
+else
+ m_thread.join();
EthCapClose();
return 0;
}
//-----------------------------------------------------------------------------
-void * ETHER_CAP::Run(void * d)
+void ETHER_CAP::Run(std::stop_token token)
{
sigset_t signalSet;
sigfillset(&signalSet);
pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
-ETHER_CAP * dc = static_cast<ETHER_CAP *>(d);
-dc->isRunning = true;
+isRunning = true;
struct ETH_IP
{
char * iface = NULL;
-while (dc->nonstop)
+while (!token.stop_requested())
{
- if (dc->EthCapRead(ðip, 68 + 14, &iface))
+ if (EthCapRead(ðip, 68 + 14, &iface))
{
continue;
}
if (ethIP->ethHdr[7] != 0x8)
continue;
- dc->traffCnt->process(ethIP->rp);
+ traffCnt->process(ethIP->rp);
}
-dc->isRunning = false;
-return NULL;
+isRunning = false;
}
//-----------------------------------------------------------------------------
int ETHER_CAP::EthCapOpen()
int ETHER_CAP::EthCapRead(void * buffer, int blen, char **)
{
struct sockaddr_ll addr;
-int addrLen;
+socklen_t addrLen;
if (!WaitPackets(capSock))
{
addrLen = sizeof(addr);
-if (recvfrom(capSock, ((char*)buffer) + 2, blen, 0, (struct sockaddr *)&addr, (socklen_t*)&addrLen) < 0)
+if (recvfrom(capSock, static_cast<char*>(buffer) + 2, blen, 0, reinterpret_cast<sockaddr *>(&addr), &addrLen) < 0)
{
logger("recvfrom error: %s", strerror(errno));
return ENODATA;
#pragma once
-#include <pthread.h>
-
-#include <string>
-
#include "stg/plugin.h"
#include "stg/module_settings.h"
#include "stg/logger.h"
+#include <string>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include <jthread.hpp>
+#pragma GCC diagnostic pop
+
namespace STG
{
ETHER_CAP(const ETHER_CAP & rvalue);
ETHER_CAP & operator=(const ETHER_CAP & rvalue);
- static void * Run(void *);
+ void Run(std::stop_token token);
int EthCapOpen();
int EthCapClose();
int EthCapRead(void * buffer, int blen, char ** iface);
mutable std::string errorStr;
- pthread_t thread;
- bool nonstop;
+ std::jthread m_thread;
bool isRunning;
int capSock;
}
//-----------------------------------------------------------------------------
NFQ_CAP::NFQ_CAP()
- : nonstop(false),
- isRunning(false),
+ : isRunning(false),
queueNumber(0),
nfqHandle(NULL),
queueHandle(NULL),
return -1;
}
-nonstop = true;
-
-if (pthread_create(&thread, NULL, Run, this))
- {
- errorStr = "Cannot create thread.";
- logger("Cannot create thread.");
- printfd(__FILE__, "Cannot create thread\n");
- return -1;
- }
+m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
return 0;
}
if (!isRunning)
return 0;
-nonstop = false;
+m_thread.request_stop();
//5 seconds to thread stops itself
for (int i = 0; i < 25 && isRunning; i++)
}
//after 5 seconds waiting thread still running. now killing it
if (isRunning)
- {
- if (pthread_kill(thread, SIGUSR1))
- {
- errorStr = "Cannot kill thread.";
- logger("Cannot send signal to thread.");
- return -1;
- }
- for (int i = 0; i < 25 && isRunning; ++i)
- {
- struct timespec ts = {0, 200000000};
- nanosleep(&ts, NULL);
- }
- if (isRunning)
- {
- errorStr = "NFQ_CAP not stopped.";
- logger("Cannot stop thread.");
- printfd(__FILE__, "Cannot stop thread\n");
- return -1;
- }
- }
-
-pthread_join(thread, NULL);
+ m_thread.detach();
+else
+ m_thread.join();
nfq_destroy_queue(queueHandle);
nfq_close(nfqHandle);
return 0;
}
//-----------------------------------------------------------------------------
-void * NFQ_CAP::Run(void * d)
+void NFQ_CAP::Run(std::stop_token token)
{
sigset_t signalSet;
sigfillset(&signalSet);
pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
-NFQ_CAP * dc = static_cast<NFQ_CAP *>(d);
-dc->isRunning = true;
+isRunning = true;
-int fd = nfq_fd(dc->nfqHandle);
+int fd = nfq_fd(nfqHandle);
char buf[4096];
-while (dc->nonstop)
+while (!token.stop_requested())
{
if (!WaitPackets(fd))
continue;
int rv = read(fd, buf, sizeof(buf));
if (rv < 0)
{
- dc->errorStr = std::string("Read error: ") + strerror(errno);
- dc->logger(dc->errorStr);
+ errorStr = std::string("Read error: ") + strerror(errno);
+ logger(errorStr);
break;
}
- nfq_handle_packet(dc->nfqHandle, buf, rv);
+ nfq_handle_packet(nfqHandle, buf, rv);
}
-dc->isRunning = false;
-return NULL;
+isRunning = false;
}
//-----------------------------------------------------------------------------
void NFQ_CAP::Process(const STG::RawPacket & packet)
#include <string>
#include <vector>
-
-#include <pthread.h>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include <jthread.hpp>
+#pragma GCC diagnostic pop
namespace STG
{
NFQ_CAP(const NFQ_CAP & rvalue);
NFQ_CAP & operator=(const NFQ_CAP & rvalue);
- static void * Run(void *);
+ void Run(std::stop_token token);
mutable std::string errorStr;
- pthread_t thread;
- bool nonstop;
+ std::jthread m_thread;
bool isRunning;
STG::ModuleSettings settings;
}
//-----------------------------------------------------------------------------
PCAP_CAP::PCAP_CAP()
- : nonstop(false),
- isRunning(false),
+ : isRunning(false),
traffCnt(NULL),
logger(STG::PluginLogger::get("pcap_cap"))
{
++it;
}
-nonstop = true;
-
-if (pthread_create(&thread, NULL, Run, this))
- {
- errorStr = "Cannot create thread.";
- logger("Cannot create thread.");
- printfd(__FILE__, "Cannot create thread\n");
- return -1;
- }
+m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
return 0;
}
if (!isRunning)
return 0;
-nonstop = false;
+m_thread.request_stop();
//5 seconds to thread stops itself
for (int i = 0; i < 25 && isRunning; i++)
}
//after 5 seconds waiting thread still running. now killing it
if (isRunning)
- {
- if (pthread_kill(thread, SIGUSR1))
- {
- errorStr = "Cannot kill thread.";
- logger("Cannot send signal to thread.");
- return -1;
- }
- for (int i = 0; i < 25 && isRunning; ++i)
- {
- struct timespec ts = {0, 200000000};
- nanosleep(&ts, NULL);
- }
- if (isRunning)
- {
- errorStr = "PCAP_CAP not stopped.";
- logger("Cannot stop thread.");
- printfd(__FILE__, "Cannot stop thread\n");
- return -1;
- }
- }
-
-pthread_join(thread, NULL);
+ m_thread.detach();
+else
+ m_thread.join();
for (DEV_MAP::iterator it(devices.begin()); it != devices.end(); ++it)
{
return 0;
}
//-----------------------------------------------------------------------------
-void * PCAP_CAP::Run(void * d)
+void PCAP_CAP::Run(std::stop_token token)
{
sigset_t signalSet;
sigfillset(&signalSet);
pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
-PCAP_CAP * dc = static_cast<PCAP_CAP *>(d);
-dc->isRunning = true;
+isRunning = true;
fd_set fds;
FD_ZERO(&fds);
int maxFd = 0;
-for (DEV_MAP::const_iterator it(dc->devices.begin()); it != dc->devices.end(); ++it)
+for (DEV_MAP::const_iterator it(devices.begin()); it != devices.end(); ++it)
{
FD_SET(it->fd, &fds);
maxFd = std::max(maxFd, it->fd);
}
-while (dc->nonstop)
+while (!token.stop_requested())
{
fd_set rfds = fds;
struct timeval tv = {0, 500000};
if (select(maxFd + 1, &rfds, NULL, NULL, &tv) > 0)
- dc->TryRead(rfds);
+ TryRead(rfds);
}
-dc->isRunning = false;
-return NULL;
+isRunning = false;
}
void PCAP_CAP::TryRead(const fd_set & set)
#include <string>
#include <vector>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include <jthread.hpp>
+#pragma GCC diagnostic pop
#include <pcap.h>
-#include <pthread.h>
#include <sys/select.h>
namespace STG
struct DEV
{
DEV() : device("any"), filterExpression("ip"), handle(NULL), fd(-1) {}
- DEV(const std::string & d) : device(d), filterExpression("ip"), handle(NULL), fd(-1) {}
+ explicit DEV(const std::string & d) : device(d), filterExpression("ip"), handle(NULL), fd(-1) {}
DEV(const std::string & d, const std::string & f)
: device(d), filterExpression(f), handle(NULL), fd(-1) {}
void TryRead(const fd_set & set);
void TryReadDev(const DEV & dev);
- static void * Run(void *);
+ void Run(std::stop_token token);
mutable std::string errorStr;
- pthread_t thread;
- bool nonstop;
+ std::jthread m_thread;
bool isRunning;
STG::ModuleSettings settings;
DEV_MAP devices;
if (isRunning)
m_thread.detach();
+ else
+ m_thread.join();
return 0;
}
if (isRunning)
m_thread.detach();
+else
+ m_thread.join();
return 0;
}
logger("Cannot stop thread.");
m_thread.detach();
}
+else
+ m_thread.join();
return 0;
}
if (!stopped)
m_thread.detach();
+else
+ m_thread.join();
ResetNotifiers();
#include <string>
#include <vector>
-struct ToLower {
- char operator() (char c) const { return static_cast<char>(std::tolower(c)); }
-};
-
class FIREBIRD_STORE : public STG::Store {
public:
FIREBIRD_STORE();
#include "postgresql_store.h"
-#include "postgresql_store_utils.h"
-#include "postgresql_store.h"
-
#include "stg/common.h" // str2x, printfd
#include <string>
+++ /dev/null
-#ifndef POSTGRESQL_UTILS_STORE_H
-#define POSTGRESQL_UTILS_STORE_H
-
-#include <functional>
-
-struct ToLower : public std::unary_function<char, char>
-{
-char operator() (char c) const { return static_cast<char>(std::tolower(c)); }
-};
-
-#endif
//5 seconds to thread stops itself
struct timespec ts = {0, 200000000};
for (int i = 0; i < 25 && !stopped; i++)
- {
nanosleep(&ts, NULL);
- }
if (!stopped)
{
return -1;
}
+m_thread.join();
+
printfd(__FILE__, "TraffCounter::Stop()\n");
return 0;
if (!oldValue)
return;
-EVENT_LOOP_SINGLETON::GetInstance().Enqueue(traffCnt, &TraffCounterImpl::DelUser, oldValue);
+EVENT_LOOP::instance().Enqueue(traffCnt, &TraffCounterImpl::DelUser, oldValue);
}
//-----------------------------------------------------------------------------
inline
if (!newValue)
return;
-EVENT_LOOP_SINGLETON::GetInstance().Enqueue(traffCnt, &TraffCounterImpl::AddUser, user);
+EVENT_LOOP::instance().Enqueue(traffCnt, &TraffCounterImpl::AddUser, user);
}
//-----------------------------------------------------------------------------
inline
void ADD_USER_NONIFIER::Notify(const UserImplPtr & user)
{
-EVENT_LOOP_SINGLETON::GetInstance().Enqueue(traffCnt, &TraffCounterImpl::SetUserNotifiers, user);
+EVENT_LOOP::instance().Enqueue(traffCnt, &TraffCounterImpl::SetUserNotifiers, user);
}
//-----------------------------------------------------------------------------
inline
void DEL_USER_NONIFIER::Notify(const UserImplPtr & user)
{
-EVENT_LOOP_SINGLETON::GetInstance().Enqueue(traffCnt, &TraffCounterImpl::UnSetUserNotifiers, user);
-EVENT_LOOP_SINGLETON::GetInstance().Enqueue(traffCnt, &TraffCounterImpl::DelUser, user->GetCurrIP());
+EVENT_LOOP::instance().Enqueue(traffCnt, &TraffCounterImpl::UnSetUserNotifiers, user);
+EVENT_LOOP::instance().Enqueue(traffCnt, &TraffCounterImpl::DelUser, user->GetCurrIP());
}
//-----------------------------------------------------------------------------
}
//TODO pthread_cancel()
m_thread.detach();
}
+else
+ m_thread.join();
printfd(__FILE__, "Before USERS::Run()\n");
for_each(users.begin(), users.end(), [](auto& user){ user.Run(); });