libuv封裝uvloop自動建立新的loop迴圈
阿新 • • 發佈:2018-11-24
#ifndef __CUVLOOP__H_ #define __CUVLOOP__H_ #include "UvThread.h" #include "UvBase.h" #include "UvMutex.h" #include <queue> class CUvLoop : public CUvThread, public CUvBase { public: CUvLoop(); ~CUvLoop(); public: int PushUvBase(CUvBase* pUvBase); public: static void AsyncCb(uv_async_t* pHandle); protected: int OnInit(); int OnThreadRun(); private: void PopUvBase(); private: uv_loop_t mstUvLoop; uv_async_t mstUvAsync; int miBakFdNum; std::queue<CUvBase*> mqueUvBase; CUvMutex mcQueBaseMutex; }; #endif #include "UvLoop.h" #define MAX_UV_LOOP_BAK_FD 10000 CUvLoop::CUvLoop(){ if (uv_loop_init(&mstUvLoop) == 0) { SetUvLoop(&mstUvLoop); } miBakFdNum = 0; } CUvLoop::~CUvLoop(){ if (nullptr != mpUvLoop) { uv_loop_close(mpUvLoop); mpUvLoop = nullptr; } } int CUvLoop::OnInit() { uv_handle_set_data((uv_handle_t*)&mstUvAsync, (void*)this); uv_async_init(mpUvLoop, &mstUvAsync, CUvLoop::AsyncCb); return Start(); } void CUvLoop::AsyncCb(uv_async_t* pHandle) { CUvLoop* pUvLoop = (CUvLoop*)uv_handle_get_data((uv_handle_t*)pHandle); if (nullptr != pUvLoop) { pUvLoop->PopUvBase(); } } void CUvLoop::PopUvBase() { CUvBase* pUvBase = nullptr; mcQueBaseMutex.Lock(); if (!mqueUvBase.empty()) { pUvBase = mqueUvBase.front(); mqueUvBase.pop(); } mcQueBaseMutex.UnLock(); if (nullptr != pUvBase) { pUvBase->SetUvLoop(mpUvLoop); pUvBase->Init(); }else { return; } miBakFdNum = uv_backend_fd(mpUvLoop); LOG_INFO("miBakFdNum = %d", miBakFdNum); PopUvBase(); } int CUvLoop::PushUvBase(CUvBase* pUvBase) { ASSERT_RET_VALUE(nullptr != mpUvLoop && nullptr != pUvBase && miBakFdNum <= MAX_UV_LOOP_BAK_FD, 1); mcQueBaseMutex.Lock(); mqueUvBase.push(pUvBase); mcQueBaseMutex.UnLock(); return uv_async_send(&mstUvAsync); } int CUvLoop::OnThreadRun() { ASSERT_RET_VALUE(nullptr != mpUvLoop, 1); //always run return uv_run(mpUvLoop, UV_RUN_DEFAULT); }
如下是uvloop管理功能類
#ifndef __CUvLoopMgr__H_ #define __CUvLoopMgr__H_ #include "singleton.h" #include "UvLoop.h" #include <vector> class CUvLoopMgr : public CSingleton<CUvLoopMgr>{ SINGLE_CLASS_INITIAL(CUvLoopMgr); public: ~CUvLoopMgr(); public: int AddUvBase(CUvBase* pUvBase); private: std::vector<CUvLoop*> mvecUvLoop; CUvMutex mcVecUvLoopMuex; }; #define sUvLoopMgr CUvLoopMgr::Instance() #endif #include "UvLoopMgr.h" CUvLoopMgr::CUvLoopMgr(){ } CUvLoopMgr::~CUvLoopMgr(){ } int CUvLoopMgr::AddUvBase(CUvBase* pUvBase) { ASSERT_RET_VALUE(nullptr != pUvBase, 1); bool bFlag = false; mcVecUvLoopMuex.Lock(); for (std::vector<CUvLoop*>::iterator iter = mvecUvLoop.begin(); iter != mvecUvLoop.end(); ++iter) { CUvLoop* pUvLoop = *iter; if (nullptr != pUvLoop && pUvLoop->PushUvBase(pUvBase) == 0) { bFlag = true; break; } } mcVecUvLoopMuex.UnLock(); if (!bFlag) { CUvLoop* pUvLoop = new CUvLoop(); if (nullptr != pUvLoop) { if (0 == pUvLoop->Init()) { pUvLoop->PushUvBase(pUvBase); mcVecUvLoopMuex.Lock(); mvecUvLoop.push_back(pUvLoop); mcVecUvLoopMuex.UnLock(); }else { DODELETE(pUvLoop); LOG_ERR("CUvLoop Init Error"); return 1; } }else { LOG_ERR("New UvLoop Error"); return 1; } } return 0; }