예제 #1
0
    bool PingBackService::cycle(
        int timeoutMs,
        const volatile bool &stopFlag)
    {
        mTimerHeap.rebase();

        PingBackTimerEntry entry;

        while (     !stopFlag 
                &&  !mStopFlag 
                &&  mTimerHeap.getExpiredEntry(entry))
        {
            // Is the session still alive?
            RcfSessionPtr rcfSessionPtr( entry.second.lock() );
            if (rcfSessionPtr)
            {
                Lock lock(rcfSessionPtr->mIoStateMutex);

                // Is the timer entry still there? It can't change while we hold mIoStateMutex.
                if (mTimerHeap.compareTop(entry))
                {
                    // Calculate the next ping back time.
                    boost::uint32_t pingBackIntervalMs = rcfSessionPtr->getPingBackIntervalMs();
                    pingBackIntervalMs = RCF_MAX(pingBackIntervalMs, boost::uint32_t(1000));

                    boost::uint32_t nextFireMs = 
                        Platform::OS::getCurrentTimeMs() + pingBackIntervalMs;

                    PingBackTimerEntry nextEntry(nextFireMs, rcfSessionPtr);

                    mTimerHeap.remove(entry);
                    mTimerHeap.add(nextEntry);
                    rcfSessionPtr->mPingBackTimerEntry = nextEntry;

                    // Only send a pingback, if previous one has completed.
                    if (!rcfSessionPtr->mWritingPingBack)
                    {
                        rcfSessionPtr->sendPingBack();
                    }

                    mTimerHeap.add(nextEntry);
                }
            }
        } 

        boost::uint32_t queueTimeoutMs = RCF_MIN(
            static_cast<boost::uint32_t>(timeoutMs),
            mTimerHeap.getNextEntryTimeoutMs());

        if (!stopFlag && !mStopFlag)
        {
            Lock lock(mMutex);
            mCondition.timed_wait(lock, queueTimeoutMs);
        }            

        return stopFlag || mStopFlag;
    }
    bool PingBackService::cycle(
        int timeoutMs,
        const volatile bool &stopFlag)
    {
        mTimerHeap.rebase();

        PingBackTimerEntry entry;

        while (     !stopFlag 
                &&  !mStopFlag 
                &&  mTimerHeap.popExpiredEntry(entry))
        {

            RcfSessionPtr rcfSessionPtr( entry.second.lock() );

            if (rcfSessionPtr)
            {
                // No sub-second pingbacks.
                boost::uint32_t pingBackIntervalMs = rcfSessionPtr->getPingBackIntervalMs();
                pingBackIntervalMs = RCF_MAX(pingBackIntervalMs, boost::uint32_t(1000));

                boost::uint32_t nextFireMs = 
                    Platform::OS::getCurrentTimeMs() + pingBackIntervalMs;

                Entry nextEntry(nextFireMs, rcfSessionPtr);

                if (    rcfSessionPtr.get() 
                    &&  rcfSessionPtr->sendPingBack(nextEntry, pingBackIntervalMs))
                {
                    mTimerHeap.add(nextEntry);
                }
            }
        } 

        boost::uint32_t queueTimeoutMs = RCF_MIN(
            static_cast<boost::uint32_t>(timeoutMs),
            mTimerHeap.getNextEntryTimeoutMs());

        if (!stopFlag && !mStopFlag)
        {
            Lock lock(mMutex);
            mCondition.timed_wait(lock, queueTimeoutMs);
        }            

        return stopFlag || mStopFlag;
    }