Files
pokerth/src/net/sessionmanager.h
T
lotodore fa7af40a49 Fixed a very nasty bug concerning the sender thread. SOCKETs were assumed to be kind of unique, but Windows tends to return the socket number of a socket which was just closed as new socket number in accept. This led to very strange behavior when the server was flooded with inits, because the sender thread still had entries for this socket number (which were not removed because they should just fail).
No longer use socket as key in maps, instead, use the session id. Only use the session id in the sender thread, "resolve" it to the socket only in the moment when it is needed. Outstanding requests will be detected to have an invalid session id then.
Also, as side effect, fixed an issue with two callback classes which were named the same and caused unexpected behavior.
2007-10-28 12:53:54 +00:00

90 lines
3.3 KiB
C++

/***************************************************************************
* Copyright (C) 2007 by Lothar May *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/* Thread safe server session manager. */
#ifndef _SESSIONMANAGER_H_
#define _SESSIONMANAGER_H_
#include <net/sessiondata.h>
#include <playerdata.h>
#include <core/thread.h>
#include <boost/function.hpp>
#include <map>
#include <string>
class SenderThread;
class NetPacket;
struct SessionWrapper
{
SessionWrapper() {}
SessionWrapper(boost::shared_ptr<SessionData> s, boost::shared_ptr<PlayerData> p)
: sessionData(s), playerData(p) {}
boost::shared_ptr<SessionData> sessionData;
boost::shared_ptr<PlayerData> playerData;
};
class SessionManager
{
public:
SessionManager();
virtual ~SessionManager();
bool HasSessions() const;
void AddSession(boost::shared_ptr<SessionData> sessionData); // new Sessions without player data
void AddSession(SessionWrapper session);
void SetSessionPlayerData(SessionId session, boost::shared_ptr<PlayerData> playerData);
void RemoveSession(SessionId session);
SessionWrapper Select(unsigned timeoutMsec);
SessionWrapper GetSessionByPlayerName(const std::string playerName) const;
SessionWrapper GetSessionByUniquePlayerId(unsigned uniqueId) const;
bool GetSocketForSession(SessionId session, SOCKET &outSocket);
PlayerDataList GetPlayerDataList() const;
PlayerIdList GetPlayerIdList() const;
bool IsPlayerConnected(const std::string &playerName) const;
bool IsPlayerConnected(unsigned uniqueId) const;
void ForEach(boost::function<void (SessionWrapper)> func);
unsigned CountReadySessions() const;
void ResetAllReadyFlags();
void Clear();
unsigned GetRawSessionCount();
void SendToAllSessions(SenderThread &sender, boost::shared_ptr<NetPacket> packet, SessionData::State state);
void SendToAllButOneSessions(SenderThread &sender, boost::shared_ptr<NetPacket> packet, SessionId except, SessionData::State state);
protected:
typedef std::map<SessionId, SessionWrapper> SessionMap;
private:
SessionMap m_sessionMap;
mutable boost::mutex m_sessionMapMutex;
};
#endif