回调线程需要不断地遍历回调队列queue<GSKResponse*> m_hasCallbackMap,一旦回调队列为空,它就阻塞
void GSKCNet::callbackLoop()
{
SetCallbckLoop(true);
SetExitCallbckLoop(false);
std::mutex conlock;
std::unique_lock < std::mutex > lck(conlock);
while (GetCallbckLoop())
{
if (CallbackQueueIsEmpty())
{
if (GetCallbckLoop())
{
m_cv.wait(lck);
}
else
{
break;
}
}
GSKResponse* p = GetCallbackFrontResp();
if (p)
{
handleMsgCallBackF(p->code, p->stHead.seqid, p->stHead.wCmd, p->stHead.wClt,
p->stHead.subCmd, p->GetMsg(), p->m_reqBody, p->cb);
delete p;
}
}
//等待接收线程退出(这样才能正确处理所有请求回调)最多500ms
int num = 0;
while (!GetExitRecvLoop())
{
glodon::sleep(10);
++num;
if (num > 20)
{
break;
}
}
LOGI_GSKCNET_INFO("callbackLoop() finish to wait recn thread exit num=%d",num);
if (!CallbackQueueIsEmpty())
{
std::queue<GSKResponse*> tmpQ;
SwapCallbackQueue(tmpQ);
while (!tmpQ.empty())
{
GSKResponse* p = tmpQ.front();
tmpQ.pop();
if (p)
{
handleMsgCallBackF(p->code, p->stHead.seqid, p->stHead.wCmd, p->stHead.wClt,
p->stHead.subCmd, p->GetMsg(), p->m_reqBody, p->cb);
delete p;
}
}
}
SetExitCallbckLoop(true);
}
调用回调函数的过程如下:
void GSKCNet::handleMsgCallBackF(int code, unsigned long long seqid, int cmd, int deviceType,
int subCmd, std::string msg, std::string reqMsg, GSKCNetCallbackType cb)
{
__GSKNetArg stArg;
stArg.iCode = code;
stArg.iSeq = seqid;
stArg.iCmd = cmd;
stArg.iSubCmd = subCmd;
stArg.iDeviceType = deviceType;
stArg.strMsg = msg;
stArg.requestMsg = reqMsg;
if (cb)
{
cb(stArg);
}
}
回调线程需要等待接收线程退出,因为接收线程会往回调队列里插入元素
网友评论