mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-17 18:12:01 +01:00
first checked in. primative, but works.
This commit is contained in:
parent
50d8c1067b
commit
73104819bd
2 changed files with 236 additions and 0 deletions
178
xwords4/relay/cref.cpp
Normal file
178
xwords4/relay/cref.cpp
Normal file
|
@ -0,0 +1,178 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <assert.h>
|
||||
|
||||
#include "cref.h"
|
||||
#include "xwrelay.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static CookieMap gCookieMap;
|
||||
|
||||
int CookieRef::ms_nextConnectionID = 1000;
|
||||
|
||||
CookieRef*
|
||||
get_make_cookieRef( char* cookie )
|
||||
{
|
||||
string s(cookie);
|
||||
CookieMap::iterator iter = gCookieMap.find(s);
|
||||
if ( iter != gCookieMap.end() ) {
|
||||
logf( "ref found for cookie %s", cookie );
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
CookieRef* ref = new CookieRef();
|
||||
gCookieMap.insert( pair<string, CookieRef*>(s, ref ) );
|
||||
return ref;
|
||||
}
|
||||
|
||||
CookieRef*
|
||||
get_cookieRef( unsigned short cookieID )
|
||||
{
|
||||
CookieMap::iterator iter = gCookieMap.begin();
|
||||
while ( iter != gCookieMap.end() ) {
|
||||
CookieRef* ref = iter->second;
|
||||
if ( ref->GetConnID() == cookieID ) {
|
||||
return ref;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
return NULL;
|
||||
} /* get_cookieRef */
|
||||
|
||||
static void
|
||||
ForgetCref( CookieRef* cref )
|
||||
{
|
||||
CookieMap::iterator iter = gCookieMap.begin();
|
||||
while ( iter != gCookieMap.end() ) {
|
||||
CookieRef* ref = iter->second;
|
||||
if ( ref == cref ) {
|
||||
logf( "erasing cref" );
|
||||
gCookieMap.erase( iter );
|
||||
break;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
assert( iter != gCookieMap.end() ); /* didn't find it */
|
||||
}
|
||||
|
||||
typedef map< int, pair<CookieRef*, pthread_t> > SocketMap;
|
||||
static SocketMap gSocketStuff;
|
||||
|
||||
void
|
||||
Associate( int socket, CookieRef* cref )
|
||||
{
|
||||
SocketMap::iterator iter = gSocketStuff.find( socket );
|
||||
if ( iter == gSocketStuff.end() ) {
|
||||
logf( "replacing existing cref/threadID pair for socket %d", socket );
|
||||
}
|
||||
|
||||
pthread_t self = pthread_self();
|
||||
pair<CookieRef*,pthread_t> pr( cref, self );
|
||||
gSocketStuff.insert( pair< int, pair< CookieRef*,pthread_t > >
|
||||
( socket, pr ) );
|
||||
} /* Associate */
|
||||
|
||||
static CookieRef*
|
||||
getCookieRefForSocket( int socket )
|
||||
{
|
||||
SocketMap::iterator iter = gSocketStuff.find( socket );
|
||||
if ( iter != gSocketStuff.end() ) {
|
||||
pair<CookieRef*,pthread_t>pr = iter->second;
|
||||
return pr.first;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RemoveSocketRefs( int socket )
|
||||
{
|
||||
CookieRef* cref = getCookieRefForSocket( socket );
|
||||
cref->Remove( socket );
|
||||
|
||||
SocketMap::iterator iter = gSocketStuff.find( socket );
|
||||
assert( iter != gSocketStuff.end() );
|
||||
gSocketStuff.erase( iter );
|
||||
|
||||
if ( cref->CountSockets() == 0 ) {
|
||||
ForgetCref( cref );
|
||||
delete cref;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* CookieRef class
|
||||
*****************************************************************************/
|
||||
|
||||
CookieRef::CookieRef()
|
||||
{
|
||||
m_connectionID = ms_nextConnectionID++; /* needs a mutex!!! */
|
||||
}
|
||||
|
||||
CookieRef::~CookieRef()
|
||||
{
|
||||
logf( "CookieRef for %d being deleted", m_connectionID );
|
||||
}
|
||||
|
||||
void
|
||||
CookieRef::Associate( int socket, HostID srcID )
|
||||
{
|
||||
assert( srcID != HOST_ID_NONE );
|
||||
logf( "remembering pair: hostid=%x, socket=%d", srcID, socket );
|
||||
m_hostSockets.insert( pair<HostID,int>(srcID,socket) );
|
||||
}
|
||||
|
||||
int
|
||||
CookieRef::SocketForHost( HostID dest )
|
||||
{
|
||||
int socket;
|
||||
map<HostID,int>::iterator iter = m_hostSockets.find( dest );
|
||||
if ( iter == m_hostSockets.end() ) {
|
||||
socket = -1;
|
||||
} else {
|
||||
socket = iter->second;
|
||||
logf( "socketForHost(%x) => %d", dest, socket );
|
||||
}
|
||||
logf( "returning socket=%d for hostid=%x", socket, dest );
|
||||
return socket;
|
||||
}
|
||||
|
||||
void
|
||||
CookieRef::Remove( int socket )
|
||||
{
|
||||
map<HostID,int>::iterator iter = m_hostSockets.begin();
|
||||
while ( iter != m_hostSockets.end() ) {
|
||||
if ( iter->second == socket ) {
|
||||
m_hostSockets.erase(iter);
|
||||
break;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ CookieMapIterator
|
||||
CookieRef::GetCookieNameIterator()
|
||||
{
|
||||
CookieMapIterator iter;
|
||||
return iter;
|
||||
}
|
||||
|
||||
|
||||
CookieMapIterator:: CookieMapIterator()
|
||||
: _iter( gCookieMap.begin() )
|
||||
{
|
||||
}
|
||||
|
||||
const char*
|
||||
CookieMapIterator::Next()
|
||||
{
|
||||
const char* str = NULL;
|
||||
if ( _iter != gCookieMap.end() ) {
|
||||
str = _iter->first.c_str();
|
||||
++_iter;
|
||||
}
|
||||
return str;
|
||||
}
|
58
xwords4/relay/cref.h
Normal file
58
xwords4/relay/cref.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
|
||||
#ifndef _CREF_H_
|
||||
#define _CREF_H_
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "xwrelay_priv.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CookieMapIterator; /* forward */
|
||||
|
||||
class CookieRef {
|
||||
|
||||
public:
|
||||
CookieRef();
|
||||
~CookieRef();
|
||||
|
||||
/* Within this cookie, remember that this hostID and socket go together.
|
||||
If the hostID is HOST_ID_SERVER, it's the server. */
|
||||
void Associate( int socket, HostID srcID );
|
||||
short GetHeartbeat() { return 60; }
|
||||
short GetConnID() { return m_connectionID; }
|
||||
int SocketForHost( HostID dest );
|
||||
void Remove( int socket );
|
||||
int CountSockets() { return m_hostSockets.size(); }
|
||||
|
||||
static CookieMapIterator GetCookieNameIterator();
|
||||
|
||||
private:
|
||||
map<HostID,int> m_hostSockets;
|
||||
/* HostID m_clientHostIDs[3]; */
|
||||
/* int m_sockets[3]; */
|
||||
/* int m_serverSocket; */
|
||||
/* int m_nClients; */
|
||||
unsigned short m_connectionID;
|
||||
|
||||
static int ms_nextConnectionID;
|
||||
};
|
||||
|
||||
typedef map<string,CookieRef*> CookieMap;
|
||||
|
||||
class CookieMapIterator {
|
||||
public:
|
||||
CookieMapIterator();
|
||||
~CookieMapIterator() {}
|
||||
const char* Next();
|
||||
private:
|
||||
CookieMap::const_iterator _iter;
|
||||
};
|
||||
|
||||
CookieRef* get_make_cookieRef( char* cookie );
|
||||
CookieRef* get_cookieRef( unsigned short cookieID );
|
||||
void Associate( int socket, CookieRef* cref );
|
||||
void RemoveSocketRefs( int socket );
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue