void SessionManager::Shutdown() { //TRACE("_sessions: %d, _nbconnect_sessions: %d", _sessions.size(), _nbconnect_sessions.size()); // close all session SessionList list = SessionMapToList(_sessions); for (SessionList::iterator it=list.begin(); it!=list.end(); it++) { // delete session ISession *session = *it; _sessions.erase(session->getid()); session->OnDisconnect(this); delete session; } // clean up non-blocking connection session list = SessionMapToList(_nbconnect_sessions); for (SessionList::iterator it=list.begin(); it!=list.end(); it++) { // because session not connected, so don't call OnDisconnect delete *it; } _nbconnect_sessions.clear(); // delete session _delete_sessions.clear(); // close listen socket _listen.release(); // clear session factory m_pFactoryServSession = NULL; _nfds = INVALID_SOCKET; }
void SessionPool::closeAll(SessionList& sessionList) { SessionList::iterator it = sessionList.begin(); for (; it != sessionList.end();) { try { (*it)->session->session()->close(); } catch (...) { } it = sessionList.erase(it); if (_nSessions > 0) --_nSessions; } }
// 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::Broadcast(const char *buf, int len, const ISession *pExclude) { // only session in _session ready to broadcast SessionList list = SessionMapToList(_sessions); for (SessionList::iterator it=list.begin(); it!=list.end(); it++) { if (pExclude != NULL && (*it) == pExclude) { continue; } (*it)->send( buf, len ); } }
int SessionManager::Poll(struct timeval &timeout) { SetupFdset(); int ret = ::select( _nfds+1, _read_set, _write_set, _error_set, &timeout); if (ret > 0) { // new connection comes ? if (_listen.is_valid() && _read_set.is_set( _listen.query_socket() ) ) { DEBUG("new session"); NewSession(); } SessionList list = SessionMapToList(_sessions); // poll read session for (SessionList::iterator it=list.begin(); it!=list.end(); it++) { ISession *session = *it; SOCKET s = session->query_socket(); if (_read_set.is_set(s)) { // notify the listener int nReturn = session->do_recv(); if (nReturn <= 0 ) { DEBUG("session close connection"); if (nReturn == SOCKET_ERROR) { ERROR("socket wrong and close connection"); session->OnError(this, WSAGetLastError(), "socket wrong and close connection" ); } // delete session _sessions.erase(session->getid()); session->OnDisconnect(this); delete session; } else { session->OnRead(this); } } } //for // poll write and error session list = SessionMapToList(_nbconnect_sessions); for (SessionList::iterator it=list.begin(); it!=list.end(); it++) { ISession *session = *it; SOCKET s = session->query_socket(); if (_error_set.is_set(s)) // error { _nbconnect_sessions.erase(session->getid()); ERROR("connection non-blocking socket error"); session->OnError(this, WSAGetLastError(), "connection non-blocking socket error"); delete session; } else if (_write_set.is_set(s)) // write { // check error (when socket error it become writeable on linux) // so must check. int err = 0; socklen_t errlen = sizeof(err); ::getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &errlen); if (err) { _nbconnect_sessions.erase(session->getid()); ERROR("connection non-blocking socket error"); session->OnError(this, WSAGetLastError(), "connection non-blocking socket error"); delete session; } else { // delete from non-blocking connection session _nbconnect_sessions.erase(session->getid()); _sessions[session->getid()] = session; session->OnConnect(this); } } } //for // delete session of _delete_sessions for (SessionMap::iterator it=_delete_sessions.begin(); it!=_delete_sessions.end(); it++) { int id = it->first; ISession *session = it->second; if (_sessions.count(id) > 0) { // delete session _sessions.erase(id); session->OnDisconnect(this); delete session; } else if (_nbconnect_sessions.count(id) > 0) { // just delete session _nbconnect_sessions.erase(id); delete session; } } //for _delete_sessions.clear(); } // if return ret; }