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; }
void Subscription::close() { RCF_ASSERT(mThisWeakPtr != SubscriptionWeakPtr()); { RecursiveLock lock(mMutex); if (mClosed) { return; } RcfSessionPtr rcfSessionPtr(mRcfSessionWeakPtr.lock()); if (rcfSessionPtr) { // When this function returns, the caller is allowed to delete // the object that this subscription refers to. So we need to // make sure there are no calls in progress. Lock sessionLock(rcfSessionPtr->mStopCallInProgressMutex); rcfSessionPtr->mStopCallInProgress = true; // Remove subscription binding. rcfSessionPtr->setDefaultStubEntryPtr(StubEntryPtr()); // Clear the destroy callback. // TODO: how do we know that we're not clearing someone else's callback? rcfSessionPtr->setOnDestroyCallback( RcfSession::OnDestroyCallback()); } mRcfSessionWeakPtr.reset(); if ( mConnectionPtr ) { mConnectionPtr->getClientStub().disconnect(); } mClosed = true; } mSubscriptionService.closeSubscription(mThisWeakPtr); }