bool SessionManager::closeSession( const String& sSID, uint32 token ) { m_mtx.lock(); SessionMap::iterator iter = m_smap.find( sSID ); if( iter != m_smap.end() ) { SessionData* sd = iter->second; m_smap.erase( sSID ); sd->clearRefs(); m_mtx.unlock(); sd->dispose(); delete sd; return true; } m_mtx.unlock(); return false; }
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; } }
SessionData* SessionManager::getSession( const Falcon::String& sSID, uint32 token ) { SessionData* sd = 0; bool bCreated; // Should we start a new thread for this? if( timeout() > 0 ) expireOldSessions(); m_mtx.lock(); SessionMap::iterator iter = m_smap.find( sSID ); if( iter != m_smap.end() ) { sd = iter->second; if ( sd == 0 || sd->isAssigned() ) { m_mtx.unlock(); return 0; } sd->assign( token ); // We must manipulate m_susers in the lock to prevent concurrent update // from other threads. m_susers[token].push_back( sd->getWeakRef() ); // now that the session is assigned, we are free to manipulate it outside the lock. m_mtx.unlock(); bCreated = false; } else { // create the session (fast) sd = createSession( sSID ); // assign to our maps m_smap[sSID] = sd; m_susers[token].push_back( sd->getWeakRef() ); // assign the session sd->assign( token ); // try to resume after unlock m_mtx.unlock(); bCreated = true; } // can we resume this session? if( ! sd->resume() ) { // all useless work. m_mtx.lock(); m_smap.erase( sSID ); sd->clearRefs(); m_mtx.unlock(); //If the session was created, we should have done it. if( ! bCreated ) { sd->setInvalid(); } else { delete sd; sd = 0; } } return sd; }