mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-07 20:46:17 +01:00
use a simple array rather than a vector to store currently connected
devices. It's simpler, searching for hid is faster, and it makes it easier to detect when we try to add the same device twice.
This commit is contained in:
parent
652a8ec905
commit
c9406c36ae
2 changed files with 179 additions and 145 deletions
|
@ -96,6 +96,7 @@ CookieRef::ReInit( const char* cookie, const char* connName, CookieID cid,
|
||||||
m_starttime = uptime();
|
m_starttime = uptime();
|
||||||
m_in_handleEvents = false;
|
m_in_handleEvents = false;
|
||||||
m_langCode = langCode;
|
m_langCode = langCode;
|
||||||
|
memset( &m_sockets, 0, sizeof(m_sockets) );
|
||||||
|
|
||||||
if ( RelayConfigs::GetConfigs()->GetValueFor( "SEND_DELAY_MILLIS",
|
if ( RelayConfigs::GetConfigs()->GetValueFor( "SEND_DELAY_MILLIS",
|
||||||
&m_delayMicros ) ) {
|
&m_delayMicros ) ) {
|
||||||
|
@ -133,12 +134,16 @@ CookieRef::~CookieRef()
|
||||||
vector<HostRec>::iterator iter;
|
vector<HostRec>::iterator iter;
|
||||||
{
|
{
|
||||||
RWWriteLock rwl( &m_socketsRWLock );
|
RWWriteLock rwl( &m_socketsRWLock );
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
AddrInfo addr = iter->m_addr;
|
HostRec* hr = m_sockets[ii];
|
||||||
if ( addr.isTCP() ) {
|
if ( NULL != hr ) {
|
||||||
tPool->CloseSocket( &addr );
|
const AddrInfo* addr = &hr->m_addr;
|
||||||
|
if ( addr->isTCP() ) {
|
||||||
|
tPool->CloseSocket( addr );
|
||||||
|
}
|
||||||
|
delete hr;
|
||||||
|
m_sockets[ii] = NULL;
|
||||||
}
|
}
|
||||||
m_sockets.erase( iter );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printSeeds(__func__);
|
printSeeds(__func__);
|
||||||
|
@ -313,10 +318,11 @@ CookieRef::HostForSocket( const AddrInfo* addr )
|
||||||
HostID hid = HOST_ID_NONE;
|
HostID hid = HOST_ID_NONE;
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
if ( iter->m_addr.equals( *addr ) ) {
|
if ( !!hr && hr->m_addr.equals( *addr ) ) {
|
||||||
hid = iter->m_hostID;
|
assert( hr->m_hostID == ii + 1 );
|
||||||
|
hid = hr->m_hostID;
|
||||||
assert( HOST_ID_NONE != hid );
|
assert( HOST_ID_NONE != hid );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -332,12 +338,10 @@ CookieRef::SocketForHost( HostID dest )
|
||||||
assert( dest != 0 ); /* don't use as lookup before assigned */
|
assert( dest != 0 ); /* don't use as lookup before assigned */
|
||||||
|
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
HostRec* hr = m_sockets[dest - 1];
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
if ( !!hr ) {
|
||||||
if ( iter->m_hostID == dest ) {
|
assert( hr->m_hostID == dest );
|
||||||
result = &iter->m_addr;
|
result = &hr->m_addr;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// logf( XW_LOGVERBOSE0, "returning socket=%d for hostid=%x", socket, dest );
|
// logf( XW_LOGVERBOSE0, "returning socket=%d for hostid=%x", socket, dest );
|
||||||
|
@ -352,14 +356,14 @@ CookieRef::AlreadyHere( unsigned short seed, const AddrInfo* addr,
|
||||||
bool here = false;
|
bool here = false;
|
||||||
|
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
here = iter->m_seed == seed; /* client already registered */
|
here = !!hr && hr->m_seed == seed; /* client already registered */
|
||||||
if ( here ) {
|
if ( here ) {
|
||||||
if ( !addr->equals(iter->m_addr) ) { /* not just a dupe packet */
|
if ( !addr->equals(hr->m_addr) ) { /* not just a dupe packet */
|
||||||
logf( XW_LOGINFO, "%s: seeds match; socket assumed closed",
|
logf( XW_LOGINFO, "%s: seeds match; socket assumed closed",
|
||||||
__func__ );
|
__func__ );
|
||||||
*prevHostID = iter->m_hostID;
|
*prevHostID = hr->m_hostID;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -378,19 +382,18 @@ CookieRef::AlreadyHere( HostID hid, unsigned short seed, const AddrInfo* addr,
|
||||||
bool here = false;
|
bool here = false;
|
||||||
|
|
||||||
RWWriteLock rwl( &m_socketsRWLock );
|
RWWriteLock rwl( &m_socketsRWLock );
|
||||||
vector<HostRec>::iterator iter;
|
HostRec* hr = m_sockets[hid-1];
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
if ( !!hr ) {
|
||||||
if ( iter->m_hostID == hid ) {
|
assert( hr->m_hostID == hid );
|
||||||
if ( seed != iter->m_seed ) {
|
if ( seed != hr->m_seed ) {
|
||||||
*spotTaken = true;
|
*spotTaken = true;
|
||||||
} else if ( addr->equals( iter->m_addr ) ) {
|
} else if ( addr->equals( hr->m_addr ) ) {
|
||||||
here = true; /* dup packet */
|
here = true; /* dup packet */
|
||||||
} else {
|
} else {
|
||||||
logf( XW_LOGINFO, "%s: hids match; nuking existing record "
|
logf( XW_LOGINFO, "%s: hids match; nuking existing record "
|
||||||
"for socket b/c assumed closed", __func__ );
|
"for socket b/c assumed closed", __func__ );
|
||||||
m_sockets.erase( iter );
|
delete hr;
|
||||||
}
|
m_sockets[hid-1] = NULL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,19 +421,20 @@ CookieRef::removeSocket( const AddrInfo* addr )
|
||||||
|
|
||||||
{
|
{
|
||||||
RWWriteLock rwl( &m_socketsRWLock );
|
RWWriteLock rwl( &m_socketsRWLock );
|
||||||
vector<HostRec>::iterator iter;
|
|
||||||
for ( iter = m_sockets.begin(); !found && iter != m_sockets.end();
|
for ( unsigned int ii = 0; !found && ii < VSIZE(m_sockets); ++ii ) {
|
||||||
++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
if ( iter->m_addr.equals( *addr ) ) {
|
if ( !!hr && hr->m_addr.equals( *addr ) ) {
|
||||||
if ( iter->m_ackPending ) {
|
if ( hr->m_ackPending ) {
|
||||||
logf( XW_LOGINFO,
|
logf( XW_LOGINFO,
|
||||||
"%s: Never got ack; removing hid %d from DB",
|
"%s: Never got ack; removing hid %d from DB",
|
||||||
__func__, iter->m_hostID );
|
__func__, hr->m_hostID );
|
||||||
DBMgr::Get()->RmDeviceByHid( ConnName(), iter->m_hostID );
|
DBMgr::Get()->RmDeviceByHid( ConnName(), hr->m_hostID );
|
||||||
m_nPlayersHere -= iter->m_nPlayersH;
|
m_nPlayersHere -= hr->m_nPlayersH;
|
||||||
cancelAckTimer( iter->m_hostID );
|
cancelAckTimer( hr->m_hostID );
|
||||||
}
|
}
|
||||||
m_sockets.erase(iter);
|
m_sockets[ii] = NULL;
|
||||||
|
delete hr;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,7 +445,7 @@ CookieRef::removeSocket( const AddrInfo* addr )
|
||||||
|
|
||||||
printSeeds(__func__);
|
printSeeds(__func__);
|
||||||
|
|
||||||
if ( m_sockets.size() == 0 ) {
|
if ( 0 == CountSockets() ) {
|
||||||
pushLastSocketGoneEvent();
|
pushLastSocketGoneEvent();
|
||||||
}
|
}
|
||||||
} /* removeSocket */
|
} /* removeSocket */
|
||||||
|
@ -457,6 +461,26 @@ CookieRef::HaveRoom( int nPlayers )
|
||||||
return haveRoom;
|
return haveRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CookieRef::CountSockets()
|
||||||
|
{
|
||||||
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
|
return CountSockets_locked();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CookieRef::CountSockets_locked()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
|
HostRec* hr = m_sockets[ii];
|
||||||
|
if ( !!hr ) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CookieRef::HasSocket( const AddrInfo* addr )
|
CookieRef::HasSocket( const AddrInfo* addr )
|
||||||
{
|
{
|
||||||
|
@ -473,9 +497,11 @@ CookieRef::GetAddrs()
|
||||||
{
|
{
|
||||||
vector<AddrInfo> result;
|
vector<AddrInfo> result;
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
result.push_back( iter->m_addr );
|
if ( !!hr ) {
|
||||||
|
result.push_back( hr->m_addr );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -485,10 +511,10 @@ CookieRef::HasSocket_locked( const AddrInfo* addr )
|
||||||
{
|
{
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for ( iter = m_sockets.begin(); !found && iter != m_sockets.end(); ++iter ) {
|
for ( unsigned int ii = 0; !found && ii < VSIZE(m_sockets); ++ii ) {
|
||||||
found = iter->m_addr.equals( *addr );
|
HostRec* hr = m_sockets[ii];
|
||||||
|
found = !!hr && hr->m_addr.equals( *addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
logf( XW_LOGINFO, "%s=>%d", __func__, found );
|
logf( XW_LOGINFO, "%s=>%d", __func__, found );
|
||||||
|
@ -929,28 +955,29 @@ CookieRef::increasePlayerCounts( CRefEvent* evt, bool reconn, HostID* hidp,
|
||||||
*devIDp = devID;
|
*devIDp = devID;
|
||||||
}
|
}
|
||||||
|
|
||||||
evt->u.con.srcID =
|
HostID hostid =
|
||||||
DBMgr::Get()->AddDevice( ConnName(), evt->u.con.srcID,
|
DBMgr::Get()->AddDevice( ConnName(), evt->u.con.srcID,
|
||||||
evt->u.con.clientVersion, nPlayersH, seed,
|
evt->u.con.clientVersion, nPlayersH, seed,
|
||||||
addr, devID, reconn );
|
addr, devID, reconn );
|
||||||
|
evt->u.con.srcID = hostid;
|
||||||
HostID hostid = evt->u.con.srcID;
|
|
||||||
if ( NULL != hidp ) {
|
if ( NULL != hidp ) {
|
||||||
*hidp = hostid;
|
*hidp = hostid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first add the rec here, whether it'll get ack'd or not */
|
/* first add the rec here, whether it'll get ack'd or not */
|
||||||
|
int count = CountSockets();
|
||||||
logf( XW_LOGINFO, "%s: remembering pair: hostid=%x, "
|
logf( XW_LOGINFO, "%s: remembering pair: hostid=%x, "
|
||||||
"(size=%d)", __func__, hostid, m_sockets.size());
|
"(size=%d)", __func__, hostid, count );
|
||||||
|
|
||||||
assert( m_sockets.size() < 4 );
|
assert( count < 4 );
|
||||||
|
|
||||||
{
|
{
|
||||||
RWWriteLock rwl( &m_socketsRWLock );
|
RWWriteLock rwl( &m_socketsRWLock );
|
||||||
HostRec hr( hostid, addr, nPlayersH, seed, !reconn );
|
HostRec* hr = new HostRec( hostid, addr, nPlayersH, seed, !reconn );
|
||||||
logf( XW_LOGINFO, "%s: adding socket rec with ts %lx", __func__,
|
logf( XW_LOGINFO, "%s: adding socket rec with ts %lx", __func__,
|
||||||
addr->created() );
|
addr->created() );
|
||||||
m_sockets.push_back( hr );
|
assert( NULL == m_sockets[hostid-1] );
|
||||||
|
m_sockets[hostid-1] = hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
printSeeds(__func__);
|
printSeeds(__func__);
|
||||||
|
@ -972,16 +999,14 @@ CookieRef::updateAck( HostID hostID, bool keep )
|
||||||
|
|
||||||
{
|
{
|
||||||
RWWriteLock rwl( &m_socketsRWLock );
|
RWWriteLock rwl( &m_socketsRWLock );
|
||||||
vector<HostRec>::iterator iter;
|
HostRec* hr = m_sockets[hostID-1];
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
if ( !!hr && hr->m_ackPending ) {
|
||||||
if ( iter->m_ackPending && iter->m_hostID == hostID ) {
|
assert( hr->m_hostID == hostID );
|
||||||
if ( keep ) {
|
if ( keep ) {
|
||||||
iter->m_ackPending = false;
|
hr->m_ackPending = false;
|
||||||
DBMgr::Get()->NoteAckd( ConnName(), hostID );
|
DBMgr::Get()->NoteAckd( ConnName(), hostID );
|
||||||
} else {
|
} else {
|
||||||
nonKeeper = &iter->m_addr;
|
nonKeeper = &hr->m_addr;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1244,11 +1269,13 @@ CookieRef::notifyOthers( const AddrInfo* addr, XWRelayMsg msg, XWREASON why )
|
||||||
|
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
const AddrInfo* other = &iter->m_addr;
|
if ( !!hr ) {
|
||||||
|
const AddrInfo* other = &hr->m_addr;
|
||||||
if ( !other->equals( *addr ) ) {
|
if ( !other->equals( *addr ) ) {
|
||||||
send_msg( other, iter->m_hostID, msg, why, false );
|
send_msg( other, hr->m_hostID, msg, why, false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* notifyOthers */
|
} /* notifyOthers */
|
||||||
|
@ -1311,12 +1338,11 @@ CookieRef::sendAllHere( bool initial )
|
||||||
|
|
||||||
{
|
{
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
HostRec* hr = m_sockets[dest-1];
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
if ( !!hr ) {
|
||||||
if ( iter->m_hostID == dest ) {
|
assert( hr->m_hostID == dest );
|
||||||
sent = send_with_length( &iter->m_addr, dest, buf, bufp-buf, true );
|
sent = send_with_length( &hr->m_addr, dest, buf,
|
||||||
break;
|
bufp-buf, true );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !sent ) {
|
if ( !sent ) {
|
||||||
|
@ -1344,9 +1370,10 @@ CookieRef::disconnectSockets( XWREASON why )
|
||||||
{
|
{
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
const AddrInfo* addr = &iter->m_addr;
|
if ( !!hr ) {
|
||||||
|
const AddrInfo* addr = &hr->m_addr;
|
||||||
if ( addr->socket() != 0 ) {
|
if ( addr->socket() != 0 ) {
|
||||||
disconnectSocket( addr, why );
|
disconnectSocket( addr, why );
|
||||||
} else {
|
} else {
|
||||||
|
@ -1354,6 +1381,7 @@ CookieRef::disconnectSockets( XWREASON why )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CookieRef::disconnectSocket( const AddrInfo* addr, XWREASON why )
|
CookieRef::disconnectSocket( const AddrInfo* addr, XWREASON why )
|
||||||
|
@ -1372,9 +1400,11 @@ CookieRef::removeDevice( const CRefEvent* const evt )
|
||||||
dbmgr->KillGame( ConnName(), evt->u.devgone.hid );
|
dbmgr->KillGame( ConnName(), evt->u.devgone.hid );
|
||||||
|
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
notifyGameDead( &iter->m_addr );
|
if ( !!hr ) {
|
||||||
|
notifyGameDead( &hr->m_addr );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1387,25 +1417,22 @@ CookieRef::noteHeartbeat( const CRefEvent* evt )
|
||||||
|
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
RWWriteLock rwl( &m_socketsRWLock );
|
RWWriteLock rwl( &m_socketsRWLock );
|
||||||
vector<HostRec>::iterator iter;
|
HostRec* hr = m_sockets[id-1];
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
if ( !!hr ) {
|
||||||
if ( iter->m_hostID == id ) {
|
assert( hr->m_hostID == id );
|
||||||
if ( iter->m_addr.equals(addr) ) {
|
if ( hr->m_addr.equals(addr) ) {
|
||||||
logf( XW_LOGVERBOSE1, "upping m_lastHeartbeat from %d to %d",
|
logf( XW_LOGVERBOSE1, "upping m_lastHeartbeat from %d to %d",
|
||||||
iter->m_lastHeartbeat, uptime() );
|
hr->m_lastHeartbeat, uptime() );
|
||||||
iter->m_lastHeartbeat = uptime();
|
hr->m_lastHeartbeat = uptime();
|
||||||
} else {
|
} else {
|
||||||
/* PENDING If the message came on an unexpected socket, kill the
|
/* PENDING If the message came on an unexpected socket, kill the
|
||||||
connection. An attack is the most likely explanation. But:
|
connection. An attack is the most likely explanation. But:
|
||||||
now it's happening after a crash and clients reconnect. */
|
now it's happening after a crash and clients reconnect. */
|
||||||
logf( XW_LOGERROR, "wrong socket record for HostID %x; "
|
logf( XW_LOGERROR, "wrong socket record for HostID %x; "
|
||||||
"wanted %d, found %d", id, addr.socket(), iter->m_addr.socket() );
|
"wanted %d, found %d", id, addr.socket(),
|
||||||
|
hr->m_addr.socket() );
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( iter == m_sockets.end() ) {
|
|
||||||
logf( XW_LOGERROR, "no socket for HostID %x", id );
|
logf( XW_LOGERROR, "no socket for HostID %x", id );
|
||||||
}
|
}
|
||||||
} /* noteHeartbeat */
|
} /* noteHeartbeat */
|
||||||
|
@ -1460,15 +1487,17 @@ CookieRef::printSeeds( const char* caller )
|
||||||
uint16_t bits = 0;
|
uint16_t bits = 0;
|
||||||
|
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
HostID hostID = iter->m_hostID;
|
if ( !!hr ) {
|
||||||
|
HostID hostID = hr->m_hostID;
|
||||||
assert( 0 == (bits & (1 << hostID)) );
|
assert( 0 == (bits & (1 << hostID)) );
|
||||||
bits |= 1 << hostID;
|
bits |= 1 << hostID;
|
||||||
len += snprintf( &buf[len], sizeof(buf)-len, "[%d]%.4x(%d)/%d/%c ",
|
len += snprintf( &buf[len], sizeof(buf)-len, "[%d]%.4x(%d)/%d/%c ",
|
||||||
iter->m_hostID, iter->m_seed,
|
hr->m_hostID, hr->m_seed,
|
||||||
iter->m_seed, iter->m_addr.socket(),
|
hr->m_seed, hr->m_addr.socket(),
|
||||||
iter->m_ackPending?'a':'A' );
|
hr->m_ackPending?'a':'A' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
logf( XW_LOGINFO, "%s: seeds/sockets/ack'd after %s(): %s", __func__, caller, buf );
|
logf( XW_LOGINFO, "%s: seeds/sockets/ack'd after %s(): %s", __func__, caller, buf );
|
||||||
}
|
}
|
||||||
|
@ -1520,17 +1549,19 @@ CookieRef::_PrintCookieInfo( string& out )
|
||||||
|
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
snprintf( buf, sizeof(buf), "Hosts connected=%d; cur time = %ld\n",
|
snprintf( buf, sizeof(buf), "Hosts connected=%d; cur time = %ld\n",
|
||||||
m_sockets.size(), uptime() );
|
CountSockets(), uptime() );
|
||||||
out += buf;
|
out += buf;
|
||||||
|
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
|
if ( !!hr ) {
|
||||||
snprintf( buf, sizeof(buf), " HostID=%d; socket=%d;last hbeat=%ld\n",
|
snprintf( buf, sizeof(buf), " HostID=%d; socket=%d;last hbeat=%ld\n",
|
||||||
iter->m_hostID, iter->m_addr.socket(),
|
hr->m_hostID, hr->m_addr.socket(),
|
||||||
iter->m_lastHeartbeat );
|
hr->m_lastHeartbeat );
|
||||||
out += buf;
|
out += buf;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} /* PrintCookieInfo */
|
} /* PrintCookieInfo */
|
||||||
|
|
||||||
|
@ -1539,23 +1570,23 @@ CookieRef::_FormatHostInfo( string* hostIds, string* seeds, string* addrs )
|
||||||
{
|
{
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
RWReadLock rrl( &m_socketsRWLock );
|
RWReadLock rrl( &m_socketsRWLock );
|
||||||
vector<HostRec>::const_iterator iter;
|
for ( unsigned int ii = 0; ii < VSIZE(m_sockets); ++ii ) {
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
HostRec* hr = m_sockets[ii];
|
||||||
|
if ( !!hr ) {
|
||||||
if ( !!hostIds ) {
|
if ( !!hostIds ) {
|
||||||
char buf[8];
|
char buf[8];
|
||||||
snprintf( buf, sizeof(buf), "%d ", iter->m_hostID );
|
snprintf( buf, sizeof(buf), "%d ", hr->m_hostID );
|
||||||
*hostIds += buf;
|
*hostIds += buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !!seeds ) {
|
if ( !!seeds ) {
|
||||||
char buf[6];
|
char buf[6];
|
||||||
snprintf( buf, sizeof(buf), "%.4X ", iter->m_seed );
|
snprintf( buf, sizeof(buf), "%.4X ", hr->m_seed );
|
||||||
*seeds += buf;
|
*seeds += buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !!addrs ) {
|
if ( !!addrs ) {
|
||||||
int socket = iter->m_addr.socket();
|
int socket = hr->m_addr.socket();
|
||||||
sockaddr_in name;
|
sockaddr_in name;
|
||||||
socklen_t siz = sizeof(name);
|
socklen_t siz = sizeof(name);
|
||||||
if ( 0 == getpeername( socket, (struct sockaddr*)&name, &siz) ) {
|
if ( 0 == getpeername( socket, (struct sockaddr*)&name, &siz) ) {
|
||||||
|
@ -1566,3 +1597,4 @@ CookieRef::_FormatHostInfo( string* hostIds, string* seeds, string* addrs )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ public:
|
||||||
class CookieRef {
|
class CookieRef {
|
||||||
public:
|
public:
|
||||||
vector<AddrInfo> GetAddrs( void );
|
vector<AddrInfo> GetAddrs( void );
|
||||||
|
static const int MAX_DEVICES = 4;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* These classes have access to CookieRef. All others should go through
|
/* These classes have access to CookieRef. All others should go through
|
||||||
|
@ -98,7 +99,8 @@ class CookieRef {
|
||||||
|
|
||||||
bool HaveRoom( int nPlayers );
|
bool HaveRoom( int nPlayers );
|
||||||
|
|
||||||
int CountSockets() { return m_sockets.size(); }
|
int CountSockets();
|
||||||
|
int CountSockets_locked(); /* needed? */
|
||||||
bool HasSocket( const AddrInfo* addr );
|
bool HasSocket( const AddrInfo* addr );
|
||||||
bool HasSocket_locked( const AddrInfo* addr );
|
bool HasSocket_locked( const AddrInfo* addr );
|
||||||
const char* Cookie() const { return m_cookie.c_str(); }
|
const char* Cookie() const { return m_cookie.c_str(); }
|
||||||
|
@ -278,7 +280,7 @@ class CookieRef {
|
||||||
/* Track sockets (= current connections with games on devices) in this
|
/* Track sockets (= current connections with games on devices) in this
|
||||||
game. There will never be more than four of these */
|
game. There will never be more than four of these */
|
||||||
pthread_rwlock_t m_socketsRWLock;
|
pthread_rwlock_t m_socketsRWLock;
|
||||||
vector<HostRec> m_sockets;
|
HostRec* m_sockets[MAX_DEVICES];
|
||||||
|
|
||||||
int m_heartbeat; /* might change per carrier or something. */
|
int m_heartbeat; /* might change per carrier or something. */
|
||||||
string m_cookie; /* cookie used for initial connections */
|
string m_cookie; /* cookie used for initial connections */
|
||||||
|
|
Loading…
Add table
Reference in a new issue