get rid of the singleton. You can start multiple applications in

a process!
pull/135/head
ruanshudong 2020-11-09 13:51:03 +08:00
parent 680d9ff52e
commit 5e95c4e577
17 changed files with 270 additions and 124 deletions

View File

@ -42,7 +42,7 @@ HttpServer::destroyApp()
void HttpServer::onNewClient(TC_EpollServer::Connection* conn)
{
std::cout << "New client from " << conn->getIp() << ":" << conn->getPort() << std::endl;
// std::cout << "New client from " << conn->getIp() << ":" << conn->getPort() << std::endl;
}
/////////////////////////////////////////////////////////////////

View File

@ -60,7 +60,8 @@ string AdminServant::notify(const string &command, CurrentPtr current)
{
RemoteNotify::getInstance()->report("AdminServant::notify:" + command);
return NotifyObserver::getInstance()->notify(command, current);
// return NotifyObserver::getInstance()->notify(command, current);
return this->getApplication()->getNotifyObserver()->notify(command, current);
}
///////////////////////////////////////////////////////////////////////

View File

@ -44,22 +44,22 @@
namespace tars
{
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
static void sighandler( int sig_no )
{
TLOGERROR("[TARS][sighandler] sig_no :" << sig_no << endl);
Application::terminate();
}
#else
static BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
{
TLOGERROR("[TARS][sighandler] dwCtrlType :" << dwCtrlType << endl);
Application::terminate();
ExitProcess(0);
return TRUE;
}
#endif
//#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
//static void sighandler( int sig_no )
//{
// TLOGERROR("[TARS][sighandler] sig_no :" << sig_no << endl);
//
// Application::terminate();
//}
//#else
//static BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
//{
// TLOGERROR("[TARS][sighandler] dwCtrlType :" << dwCtrlType << endl);
// Application::terminate();
// ExitProcess(0);
// return TRUE;
//}
//#endif
std::string ServerConfig::TarsPath; //服务路径
@ -101,8 +101,8 @@ std::string ServerConfig::Ciphers;
map<string, string> ServerConfig::Context;
///////////////////////////////////////////////////////////////////////////////////////////
TC_Config Application::_conf;
TC_EpollServerPtr Application::_epollServer = NULL;
//TC_Config Application::_conf;
//TC_EpollServerPtr Application::_epollServer = NULL;
CommunicatorPtr Application::_communicator = NULL;
PropertyReportPtr g_pReportRspQueue;
@ -117,6 +117,12 @@ Application::Application()
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
#endif
_servantHelper = std::make_shared<ServantHelperManager>();
_notifyObserver = std::make_shared<NotifyObserver>();
setNotifyObserver(_notifyObserver);
}
Application::~Application()
@ -131,16 +137,16 @@ string Application::getTarsVersion()
{
return TARS_VERSION;
}
TC_Config& Application::getConfig()
{
return _conf;
}
TC_EpollServerPtr& Application::getEpollServer()
{
return _epollServer;
}
//
//TC_Config& Application::getConfig()
//{
// return _conf;
//}
//
//TC_EpollServerPtr& Application::getEpollServer()
//{
// return _epollServer;
//}
CommunicatorPtr& Application::getCommunicator()
{
@ -530,7 +536,7 @@ bool Application::cmdViewAdminCommands(const string& command, const string& para
{
TLOGTARS("Application::cmdViewAdminCommands:" << command << " " << params << endl);
result =result + NotifyObserver::getInstance()->viewRegisterCommand();
result =result + _notifyObserver->viewRegisterCommand();
return true;
}
@ -541,7 +547,7 @@ bool Application::cmdSetDyeing(const string& command, const string& params, stri
if(vDyeingParams.size() == 2 || vDyeingParams.size() == 3)
{
ServantHelperManager::getInstance()->setDyeing(vDyeingParams[0], vDyeingParams[1], vDyeingParams.size() == 3 ? vDyeingParams[2] : "");
_servantHelper->setDyeing(vDyeingParams[0], vDyeingParams[1], vDyeingParams.size() == 3 ? vDyeingParams[2] : "");
result = "DyeingKey=" + vDyeingParams[0] + "\r\n" +
"DyeingServant=" + vDyeingParams[1] + "\r\n" +
@ -626,7 +632,7 @@ bool Application::cmdViewResource(const string& command, const string& params, s
vector<TC_EpollServer::BindAdapterPtr> adapters = _epollServer->getBindAdapters();
for(auto adapter : adapters)
{
outAdapter(os, ServantHelperManager::getInstance()->getAdapterServant(adapter->getName()), adapter);
outAdapter(os, _servantHelper->getAdapterServant(adapter->getName()), adapter);
os << TC_Common::outfill("recv-buffer-count") << adapter->getRecvBufferSize() << endl;
os << TC_Common::outfill("send-buffer-count") << adapter->getSendBufferSize() << endl;
}
@ -644,7 +650,7 @@ void Application::outAllAdapter(ostream &os)
for (auto it = m.begin(); it != m.end(); ++it)
{
outAdapter(os, ServantHelperManager::getInstance()->getAdapterServant(it->second->getName()), it->second);
outAdapter(os, _servantHelper->getAdapterServant(it->second->getName()), it->second);
os << OUT_LINE << endl;
}
@ -709,6 +715,9 @@ void Application::main(const TC_Option &option)
exit(-1);
}
string config = TC_File::load2str(ServerConfig::ConfigFile);
main(config);
}
void Application::main(const string &config)
@ -833,16 +842,30 @@ void Application::main(const string &config)
RemoteNotify::getInstance()->report("restart");
//ctrl + c能够完美结束服务
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
std::thread th1(signal, SIGINT, sighandler);
th1.detach();
//k8s pod完美退出
std::thread th2(signal, SIGTERM, sighandler);
th2.detach();
#else
std::thread th([] {SetConsoleCtrlHandler(HandlerRoutine, TRUE); });
th.detach();
//#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
// std::thread th1(signal, SIGINT, sighandler);
// th1.detach();
// //k8s pod完美退出
// std::thread th2(signal, SIGTERM, sighandler);
// th2.detach();
//#else
// std::thread th([] {SetConsoleCtrlHandler(HandlerRoutine, TRUE); });
// th.detach();
//#endif
//#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
TC_Port::registerCtrlC([=]{
this->terminate();
#if TARGET_PLATFORM_WINDOWS
ExitProcess(0);
#endif
});
TC_Port::registerTerm([=]{
this->terminate();
#if TARGET_PLATFORM_WINDOWS
ExitProcess(0);
#endif
});
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
if(_conf.get("/tars/application/server<closecout>",AppCache::getInstance()->get("closeCout")) != "0")
{
@ -961,7 +984,7 @@ string Application::setDivision()
void Application::addServantProtocol(const string& servant, const TC_NetWorkBuffer::protocol_functor& protocol)
{
string adapterName = ServantHelperManager::getInstance()->getServantAdapter(servant);
string adapterName = _servantHelper->getServantAdapter(servant);
if (adapterName == "")
{
@ -985,7 +1008,7 @@ void Application::onAccept(TC_EpollServer::Connection* cPtr)
void Application::addServantOnClose(const string& servant, const TC_EpollServer::close_functor& cf)
{
string adapterName = ServantHelperManager::getInstance()->getServantAdapter(servant);
string adapterName = _servantHelper->getServantAdapter(servant);
if (adapterName.empty())
{
@ -1220,9 +1243,9 @@ void Application::initializeServer()
if(!ServerConfig::Local.empty())
{
ServantHelperManager::getInstance()->addServant<AdminServant>("AdminObj", this);
_servantHelper->addServant<AdminServant>("AdminObj", this);
ServantHelperManager::getInstance()->setAdapterServant("AdminAdapter", "AdminObj");
_servantHelper->setAdapterServant("AdminAdapter", "AdminObj");
TC_EpollServer::BindAdapterPtr lsPtr = new TC_EpollServer::BindAdapter(_epollServer.get());
@ -1240,7 +1263,7 @@ void Application::initializeServer()
lsPtr->setProtocol(AppProtocol::parse);
lsPtr->setHandle<ServantHandle>(1);
lsPtr->setHandle<ServantHandle>(1, this);
_epollServer->bind(lsPtr);
}
@ -1271,7 +1294,8 @@ void Application::setAdapter(TC_EpollServer::BindAdapterPtr& adapter, const stri
if (!accKey.empty())
adapter->setAkSk(accKey, secretKey);
adapter->setAuthProcessWrapper(&tars::processAuth);
// adapter->setAuthProcessWrapper(&tars::processAuth);
adapter->setAuthProcessWrapper(std::bind(tars::processAuth, std::placeholders::_1, std::placeholders::_2, _servantHelper->getAdapterServant(name)));
}
#if TARS_SSL
@ -1320,7 +1344,7 @@ void Application::bindAdapter(vector<TC_EpollServer::BindAdapterPtr>& adapters)
checkServantNameValid(servant, sPrefix);
ServantHelperManager::getInstance()->setAdapterServant(adapterName[i], servant);
_servantHelper->setAdapterServant(adapterName[i], servant);
TC_EpollServer::BindAdapterPtr bindAdapter = new TC_EpollServer::BindAdapter(_epollServer.get());
@ -1369,7 +1393,7 @@ void Application::bindAdapter(vector<TC_EpollServer::BindAdapterPtr>& adapters)
exit(-1);
}
#endif
bindAdapter->setHandle<ServantHandle>(TC_Common::strto<int>(_conf.get(sLastPath + "<threads>", "1")));
bindAdapter->setHandle<ServantHandle>(TC_Common::strto<int>(_conf.get(sLastPath + "<threads>", "1")), this);
if(ServerConfig::ManualListen) {
//手工监听

View File

@ -27,7 +27,7 @@
namespace tars
{
bool processAuth(TC_EpollServer::Connection *conn, const shared_ptr<TC_EpollServer::RecvContext> &data)
bool processAuth(TC_EpollServer::Connection *conn, const shared_ptr<TC_EpollServer::RecvContext> &data, const string &objName)
{
conn->tryInitAuthState(AUTH_INIT);
@ -71,7 +71,8 @@ bool processAuth(TC_EpollServer::Connection *conn, const shared_ptr<TC_EpollServ
}
int currentState = conn->_authState;
int newstate = tars::defaultProcessAuthReq(request.sBuffer.data(), request.sBuffer.size(), adapter->getName());
// int newstate = tars::defaultProcessAuthReq(request.sBuffer.data(), request.sBuffer.size(), adapter->getName());
int newstate = tars::defaultProcessAuthReq(request.sBuffer.data(), request.sBuffer.size(), adapter, objName);
std::string out = tars::etos((tars::AUTH_STATE)newstate);
if (newstate < 0)
@ -197,7 +198,8 @@ int processAuthReqHelper(const BasicAuthPackage& pkg, const BasicAuthInfo& info)
// 只需要传入 expect 的objname
// 内部根据obj查找access账号集
int defaultProcessAuthReq(const char* request, size_t len, const string& expectObj)
//int defaultProcessAuthReq(const char* request, size_t len, const string& expectObj)
int defaultProcessAuthReq(const char* request, size_t len, const TC_EpollServer::BindAdapterPtr &adapter, const string &objName)
{
if (len <= 20)
return AUTH_PROTO_ERR;
@ -212,25 +214,25 @@ int defaultProcessAuthReq(const char* request, size_t len, const string& expectO
return AUTH_PROTO_ERR;
}
TC_EpollServer::BindAdapterPtr bap = Application::getEpollServer()->getBindAdapter(expectObj);
if (!bap)
return AUTH_WRONG_OBJ;
// TC_EpollServer::BindAdapterPtr bap = Application::getEpollServer()->getBindAdapter(expectObj);
// if (!bap)
// return AUTH_WRONG_OBJ;
BasicAuthInfo info;
string expectServantName = ServantHelperManager::getInstance()->getAdapterServant(expectObj);
info.sObjName = expectServantName;
// string expectServantName = ServantHelperManager::getInstance()->getAdapterServant(expectObj);
info.sObjName = objName;
info.sAccessKey = pkg.sAccessKey;
info.sHashSecretKey2 = bap->getSk(info.sAccessKey);
info.sHashSecretKey2 = adapter->getSk(info.sAccessKey);
if (info.sHashSecretKey2.empty())
return AUTH_WRONG_AK;
return processAuthReqHelper(pkg, info);
}
int defaultProcessAuthReq(const string& request, const string& expectObj)
{
return defaultProcessAuthReq(request.data(), request.size(), expectObj);
}
//int defaultProcessAuthReq(const string& request, const string& expectObj)
//{
// return defaultProcessAuthReq(request.data(), request.size(), expectObj);
//}
string defaultCreateAuthReq(const BasicAuthInfo& info /*, const string& hashMethod*/ )
{

View File

@ -34,7 +34,7 @@ void BaseNotify::addAdminCommandPrefix(const string& command, TAdminFunc func)
_procFunctors.insert(std::make_pair(command, func));
NotifyObserver::getInstance()->registerPrefix(command, this);
_observer->registerPrefix(command, this);
}
void BaseNotify::addAdminCommandNormal(const string& command, TAdminFunc func)
@ -43,7 +43,7 @@ void BaseNotify::addAdminCommandNormal(const string& command, TAdminFunc func)
_procFunctors.insert(std::make_pair(command, func));
NotifyObserver::getInstance()->registerNotify(command, this);
_observer->registerNotify(command, this);
}
bool BaseNotify::notify(const string& cmd, const string& params, CurrentPtr current, string& result)

View File

@ -164,7 +164,11 @@ void Current::initialize(const shared_ptr<TC_EpollServer::RecvContext> &data)
{
_data = data;
_request.sServantName = ServantHelperManager::getInstance()->getAdapterServant(_data->adapter()->getName());
Application *application = (Application*)this->_servantHandle->getApplication();
_request.sServantName = application->getServantHelper()->getAdapterServant(_data->adapter()->getName());
// _request.sServantName = ServantHelperManager::getInstance()->getAdapterServant(_data->adapter()->getName());
if (_data->adapter()->isTarsProtocol())
{
@ -176,7 +180,9 @@ void Current::initializeClose(const shared_ptr<TC_EpollServer::RecvContext> &dat
{
_data = data;
_request.sServantName = ServantHelperManager::getInstance()->getAdapterServant(_data->adapter()->getName());
Application *application = (Application*)this->_servantHandle->getApplication();
_request.sServantName = application->getServantHelper()->getAdapterServant(_data->adapter()->getName());
}
void Current::initialize(const vector<char>& sRecvBuffer)

View File

@ -48,6 +48,8 @@ string Servant::getName() const
void Servant::setApplication(Application *application)
{
_application = application;
setNotifyObserver(application->getNotifyObserver());
}
Application* Servant::getApplication() const

View File

@ -23,6 +23,7 @@
#include "servant/BaseF.h"
#include "servant/KeepAliveNodeF.h"
#include "servant/Cookie.h"
#include "servant/Application.h"
#ifdef TARS_OPENTRACKING
#include "servant/text_map_carrier.h"
#endif
@ -32,8 +33,8 @@ namespace tars
/////////////////////////////////////////////////////////////////////////
//
ServantHandle::ServantHandle()
: _coroSched(NULL)
ServantHandle::ServantHandle(Application *application)
: _application(application),_coroSched(NULL)
{
}
@ -340,7 +341,7 @@ bool ServantHandle::allFilterIsEmpty()
void ServantHandle::initialize()
{
ServantPtr servant = ServantHelperManager::getInstance()->create(_bindAdapter->getName());
ServantPtr servant = _application->getServantHelper()->create(_bindAdapter->getName());
if (servant)
{
@ -682,12 +683,12 @@ bool ServantHandle::processDye(const CurrentPtr &current, string& dyeingKey)
}
//servant已经被染色, 开启染色日志
if (ServantHelperManager::getInstance()->isDyeing())
if (_application->getServantHelper()->isDyeing())
{
map<string, string>::const_iterator dyeingKeyIt = current->getRequestStatus().find(ServantProxy::STATUS_GRID_KEY);
if (dyeingKeyIt != current->getRequestStatus().end() &&
ServantHelperManager::getInstance()->isDyeingReq(dyeingKeyIt->second, current->getServantName(), current->getFuncName()))
_application->getServantHelper()->isDyeingReq(dyeingKeyIt->second, current->getServantName(), current->getFuncName()))
{
TLOGTARS("[TARS] dyeing servant got a dyeing req, key:" << dyeingKeyIt->second << endl);

View File

@ -144,6 +144,7 @@ struct SVT_DLL_API ServerConfig
};
class PropertyReport;
class NotifyObserver;
//////////////////////////////////////////////////////////////////////
/**
@ -181,26 +182,28 @@ public:
*
* @return TC_Config&
*/
static TC_Config &getConfig();
TC_Config &getConfig() { return _conf; }
const TC_Config &getConfig() const { return _conf; }
/**
*
*
* @return CommunicatorPtr&
*/
/**
*
*
* @return CommunicatorPtr&
*/
static CommunicatorPtr& getCommunicator();
/**
* Server
*
* @return TC_EpollServerPtr&
*/
static TC_EpollServerPtr &getEpollServer();
/**
* Server
*
* @return TC_EpollServerPtr&
*/
TC_EpollServerPtr &getEpollServer() { return _epollServer; }
const TC_EpollServerPtr &getEpollServer() const { return _epollServer; }
/**
*
*/
static void terminate();
/**
*
*/
void terminate();
/**
* tarsservant
@ -232,9 +235,29 @@ public:
template<typename T>
void addServant(const string &id)
{
ServantHelperManager::getInstance()->addServant<T>(id, this, true);
_servantHelper->addServant<T>(id, this, true);
}
template<typename T, typename P>
void addServantWithParams(const string &id, const P &p)
{
#ifndef GEN_PYTHON_MASK
_servantHelper->addServant<T>(id, this, p, true);
#endif
}
/**
* get servant helper
* @return
*/
const shared_ptr<ServantHelperManager> &getServantHelper() { return _servantHelper; }
/**
* get notify observer
* @return
*/
const shared_ptr<NotifyObserver> &getNotifyObserver() { return _notifyObserver; }
/**
* tafserverServant
* @param protocol
@ -473,6 +496,11 @@ protected:
*/
void bindAdapter(vector<TC_EpollServer::BindAdapterPtr> &adapters);
/**
* set adapter
* @param adapter
* @param name
*/
void setAdapter(TC_EpollServer::BindAdapterPtr& adapter, const string &name);
/**
@ -500,20 +528,33 @@ protected:
/**
* config
*/
static TC_Config _conf;
TC_Config _conf;
/**
* epoll server
*/
static TC_EpollServerPtr _epollServer;
TC_EpollServerPtr _epollServer;
/**
* communicator
*/
static CommunicatorPtr _communicator;
/**
* accept
*/
std::vector<TC_EpollServer::accept_callback_functor> _acceptFuncs;
/**
* servant helper
*/
shared_ptr<ServantHelperManager> _servantHelper;
/**
* notify observer
*/
shared_ptr<NotifyObserver> _notifyObserver;
/**
* ssl ctx
*/

View File

@ -7,7 +7,7 @@ namespace tars
/**
* server :
*/
bool processAuth(TC_EpollServer::Connection *c, const shared_ptr<TC_EpollServer::RecvContext>& data);
bool processAuth(TC_EpollServer::Connection *c, const shared_ptr<TC_EpollServer::RecvContext>& data, const string &objName);
/**
* server :
@ -17,8 +17,9 @@ int processAuthReqHelper(const BasicAuthPackage& pkg, const BasicAuthInfo& info)
/**
* server :
*/
int defaultProcessAuthReq(const char* request, size_t len, const string& expectObj);
int defaultProcessAuthReq(const string& request, const string& expectObj);
//int defaultProcessAuthReq(const char* request, size_t len, const string& expectObj);
//int defaultProcessAuthReq(const string& request, const string& expectObj);
int defaultProcessAuthReq(const char* request, size_t len, const TC_EpollServer::BindAdapterPtr &adapter, const string &objName);
/**
* client:

View File

@ -24,6 +24,8 @@
namespace tars
{
class NotifyObserver;
//////////////////////////////////////////////////////////////////////
/**
*
@ -73,11 +75,20 @@ public:
*/
void addAdminCommandPrefix(const string& command, TAdminFunc func);
protected:
void setNotifyObserver(const shared_ptr<NotifyObserver> &notifyObserver) { _observer = notifyObserver; }
protected:
/**
*
*/
map<string, TAdminFunc> _procFunctors;
/**
* notify observer
*/
shared_ptr<NotifyObserver> _observer;
};
/////////////////////////////////////////////////////////////////////
}

View File

@ -30,7 +30,7 @@ class BaseNotify;
/**
*
*/
class SVT_DLL_API NotifyObserver : public TC_Singleton<NotifyObserver>, public TC_ThreadRecMutex
class SVT_DLL_API NotifyObserver : public TC_ThreadRecMutex
{
public:
/**

View File

@ -33,6 +33,8 @@
namespace tars
{
class Application;
//////////////////////////////////////////////////////////////////////////////
/**
* 线
@ -51,7 +53,7 @@ public:
/**
*
*/
ServantHandle();
ServantHandle(Application *application);
/**
*
@ -68,6 +70,12 @@ public:
*/
CoroutineScheduler* getCoroSched() { return _coroSched; }
/**
* get Application
* @return
*/
Application *getApplication() { return _application; }
protected:
/**
@ -194,6 +202,10 @@ protected:
*/
bool checkValidSetInvoke(const CurrentPtr &current);
protected:
/**
* application
*/
Application *_application = NULL;
/**
*

View File

@ -55,7 +55,7 @@ struct ServantCreation : public ServantHelperCreation
/**
* Servant
*/
class SVT_DLL_API ServantHelperManager : public TC_Singleton<ServantHelperManager>
class SVT_DLL_API ServantHelperManager
{
public:
/**

View File

@ -901,7 +901,8 @@ public:
* 线,线
* Initialize the processing thread, which will start
*/
template<typename T> void setHandle(size_t n)
template<typename T, typename ...Args>
void setHandle(size_t n, Args&&... args)
{
if(!_handles.empty())
{
@ -921,7 +922,7 @@ public:
for (int32_t i = 0; i < _iHandleNum ; ++i)
{
HandlePtr handle = new T();
HandlePtr handle = new T(args...);
handle->setHandleIndex(i);

View File

@ -27,6 +27,7 @@ typedef unsigned short mode_t;
#include <vector>
#include <functional>
#include <mutex>
#include <unordered_map>
using namespace std;
@ -85,13 +86,20 @@ public:
static void registerCtrlC(std::function<void()> callback);
static void registerTerm(std::function<void()> callback);
protected:
static void registerCtrlC();
// static void registerCtrlC();
static void registerSig(int sig, std::function<void()> callback);
static void registerSig(int sig);
static std::mutex _mutex;
static vector<std::function<void()>> _callbacks;
// static vector<std::function<void()>> _callbacks;
static unordered_map<int, vector<std::function<void()>>> _callbacks;
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
static void sighandler( int sig_no );

View File

@ -261,28 +261,51 @@ string TC_Port::exec(const char *cmd)
return fileData;
}
vector<std::function<void()>> TC_Port::_callbacks;
unordered_map<int, vector<std::function<void()>>> TC_Port::_callbacks;
std::mutex TC_Port::_mutex;
void TC_Port::registerSig(int sig, std::function<void()> callback)
{
std::lock_guard<std::mutex> lock(_mutex);
auto it = _callbacks.find(sig);
if(it == _callbacks.end())
{
//没有注册过, 才注册
registerSig(sig);
}
_callbacks[SIGINT].push_back(callback);
}
void TC_Port::registerCtrlC(std::function<void()> callback)
{
std::lock_guard<std::mutex> lock(_mutex);
if(_callbacks.empty())
{
registerCtrlC();
}
_callbacks.push_back(callback);
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
registerSig(SIGINT, callback);
#else
registerSig(CTRL_C_EVENT, callback);
#endif
}
void TC_Port::registerCtrlC()
void TC_Port::registerTerm(std::function<void()> callback)
{
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
std::thread th(signal, SIGINT, TC_Port::sighandler);
th.detach();
registerSig(SIGTERM, callback);
#else
std::thread th([] {SetConsoleCtrlHandler(TC_Port::HandlerRoutine, TRUE); });
registerSig(CTRL_SHUTDOWN_EVENT, callback);
#endif
}
void TC_Port::registerSig(int sig)
{
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
std::thread th(signal, sig, TC_Port::sighandler);
th.detach();
#else
std::thread th([] {SetConsoleCtrlHandler(TC_Port::HandlerRoutine, TRUE); });
th.detach();
#endif
}
@ -290,20 +313,33 @@ void TC_Port::registerCtrlC()
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
void TC_Port::sighandler( int sig_no )
{
for(auto f : TC_Port::_callbacks)
{
try {f(); } catch(...) {}
}
std::lock_guard<std::mutex> lock(_mutex);
auto it = TC_Port::_callbacks.find(sig_no);
if(it != TC_Port::_callbacks.end())
{
for (auto f : it->second)
{
try { f(); } catch (...) {}
}
}
}
#else
BOOL WINAPI TC_Port::HandlerRoutine(DWORD dwCtrlType)
{
for(auto f : TC_Port::_callbacks)
{
try {f(); } catch(...) {}
}
return TRUE;
std::lock_guard<std::mutex> lock(_mutex);
auto it = TC_Port::_callbacks.find(sig_no);
if(it != TC_Port::_callbacks.end())
{
for (auto f : it->second)
{
try { f(); } catch (...) {}
}
}
return TRUE:
}
#endif
}