// release all the sessions associated with this token bool SessionManager::releaseSessions( uint32 token ) { m_mtx.lock(); // do we have the session? SessionUserMap::iterator pos = m_susers.find( token ); if( pos != m_susers.end() ) { // copy the list of sessions to be closed, so that we can work on it. SessionList lCopy = pos->second; m_susers.erase( pos ); m_mtx.unlock(); SessionList::iterator iter = lCopy.begin(); while( iter != lCopy.end() ) { SessionData::WeakRef* wsd = *iter; SessionData* sd = wsd->get(); // Still a valid reference? if( sd != 0 ) { // store on persistent media sd->store(); // mark as used now sd->touch(); // make available for other requests m_mtx.lock(); if( timeout() > 0 ) { m_expmap.insert( ExpirationMap::value_type( sd->lastTouched() + timeout(), sd->getWeakRef() ) ); } sd->release(); m_mtx.unlock(); } wsd->dropped(); ++iter; } } else { m_mtx.unlock(); } return true; }
void SessionManager::expireOldSessions() { numeric now = Sys::_seconds(); std::deque<SessionData*> expiredSessions; m_mtx.lock(); while( ! m_expmap.empty() && m_expmap.begin()->first < now ) { SessionData::WeakRef* wsd = m_expmap.begin()->second; SessionData* sd = wsd->get(); // Is the session still alive? if ( sd != 0 && sd->lastTouched() + timeout() < now ) { // the data is dead, so we remove it now from the available map m_smap.erase( sd->sID() ); // prevents others (and ourselves) to use it again sd->clearRefs(); // and we push it aside for later clearing expiredSessions.push_back( sd ); } // also, take it away from our expired data m_expmap.erase( m_expmap.begin() ); } m_mtx.unlock(); // now we can destroy the expired sessions std::deque<SessionData*>::iterator elem = expiredSessions.begin(); while( elem != expiredSessions.end() ) { SessionData* sd = *elem; sd->dispose(); delete sd; ++elem; } }