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; }
SessionManager::SessionList SessionManager::SessionMapToList(SessionMap &map) { SessionList list; for (SessionMap::iterator it=map.begin(); it!=map.end(); it++) { list.push_back(it->second); } return list; }
void Disconnect(ServerSession::Ptr pSession, DISCONNECT_REASON reason) { SessionList::iterator found = _sessions.find(pSession->GetId()); if (found != _sessions.end()) { std::cout << "disconnect " << pSession->GetId() << " reason:" << reason << std::endl; _disconnectHandler(pSession, reason); _sessions.erase(found); } }
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 ); } }
void OnAccept(ServerSession::Ptr pNewSession, const boost::system::error_code& error) { if (error) { std::cout << error << std::endl; if (error == error::bad_descriptor) // WSAEBADF=10009 { // このケースですぐにasync_acceptすると、 // OnAcceptを抜けた後に現在のio_service::pollがそのイベントを実行し、 // io_service::pollから帰ってこなくなる。 } throw error; // のでとりあえず例外を投げて終了させる。 } else { pNewSession->_id = _nextSessionId++; _sessions.insert(std::make_pair(pNewSession->GetId(), pNewSession)); _connectHandler(pNewSession); ServerSession::AsyncRead(pNewSession); } // 引き続き他の接続を待機。 Listen(); }
void MonitoringData::enumerate(SessionList& sessions, const char* user_name) { // Return IDs for all known (and permitted) sessions for (ULONG offset = alignOffset(sizeof(Header)); offset < shared_memory->getHeader()->used;) { UCHAR* const ptr = (UCHAR*) shared_memory->getHeader() + offset; const Element* const element = (Element*) ptr; const ULONG length = alignOffset(sizeof(Element) + element->length); offset += length; if (!user_name || !strcmp(element->userName, user_name)) sessions.add(element->attId); } }
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; }