IM客户端开发(4)——回调线程

回调线程需要不断地遍历回调队列queue 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 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);
    }
}

回调线程需要等待接收线程退出,因为接收线程会往回调队列里插入元素

你可能感兴趣的:(IM客户端开发(4)——回调线程)