美文网首页
IM客户端开发(4)——回调线程

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

作者: Magic11 | 来源:发表于2019-12-06 10:43 被阅读0次

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

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

    相关文章

      网友评论

          本文标题:IM客户端开发(4)——回调线程

          本文链接:https://www.haomeiwen.com/subject/jvbsgctx.html