瀏覽代碼

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

ruanshudong 3 年之前
父節點
當前提交
5e95c4e577

+ 1 - 1
examples/HttpDemo/HttpServer/HttpServer.cpp

@@ -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;
 }
 
 /////////////////////////////////////////////////////////////////

+ 2 - 1
servant/libservant/AdminServant.cpp

@@ -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);
 }
 
 ///////////////////////////////////////////////////////////////////////

+ 73 - 49
servant/libservant/Application.cpp

@@ -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) {
                 //手工监听

+ 15 - 13
servant/libservant/AuthLogic.cpp

@@ -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*/ )
 {

+ 2 - 2
servant/libservant/BaseNotify.cpp

@@ -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)

+ 8 - 2
servant/libservant/Current.cpp

@@ -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)

+ 2 - 0
servant/libservant/Servant.cpp

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

+ 6 - 5
servant/libservant/ServantHandle.cpp

@@ -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);
 

+ 60 - 19
servant/servant/Application.h

@@ -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; }
+
     /**
      * 非taf协议server,设置Servant的协议解析器
      * @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
      */

+ 4 - 3
servant/servant/AuthLogic.h

@@ -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:默认生成鉴权请求方法

+ 11 - 0
servant/servant/BaseNotify.h

@@ -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;
+
 };
 /////////////////////////////////////////////////////////////////////
 }

+ 1 - 1
servant/servant/NotifyObserver.h

@@ -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:
     /**

+ 13 - 1
servant/servant/ServantHandle.h

@@ -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;
 
     /**
      * 处理对象

+ 1 - 1
servant/servant/ServantHelper.h

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

+ 3 - 2
util/include/util/tc_epoll_server.h

@@ -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);
 

+ 10 - 2
util/include/util/tc_port.h

@@ -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 );

+ 55 - 19
util/src/tc_port.cpp

@@ -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::registerCtrlC(std::function<void()> callback)
+void TC_Port::registerSig(int sig, std::function<void()> callback)
 {
-    std::lock_guard<std::mutex> lock(_mutex);
+	std::lock_guard<std::mutex> lock(_mutex);
+
+	auto it = _callbacks.find(sig);
 
-	if(_callbacks.empty())
+	if(it == _callbacks.end())
 	{
- 	   registerCtrlC();
+		//没有注册过, 才注册
+		registerSig(sig);
 	}
 
-    _callbacks.push_back(callback);
+	_callbacks[SIGINT].push_back(callback);
 }
 
-void TC_Port::registerCtrlC()
+void TC_Port::registerCtrlC(std::function<void()> callback)
 {
 #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
-    std::thread th(signal, SIGINT, TC_Port::sighandler);
-    th.detach();
+	registerSig(SIGINT, callback);
 #else
-    std::thread th([] {SetConsoleCtrlHandler(TC_Port::HandlerRoutine, TRUE); });
+	registerSig(CTRL_C_EVENT, callback);
+#endif
+}
+
+void TC_Port::registerTerm(std::function<void()> callback)
+{
+#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
+
+	registerSig(SIGTERM, callback);
+#else
+	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
 
+
 }