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;
 }
Example #3
0
	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);
		}
	}
Example #4
0
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;
	}
}
Example #5
0
// 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 );
        }
    }
Example #7
0
	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();
	}
Example #8
0
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;
    }