mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-30 08:34:16 +01:00
Attempt to detect connections that are duplicates by checking if that
socket is already in a connection. This doesn't seem to always work, and I may be leaking cref instances when it does, so needs debugging still.
This commit is contained in:
parent
3c16f9781d
commit
7a24d40d1f
5 changed files with 53 additions and 37 deletions
|
@ -34,7 +34,7 @@ SVNINFO = svnversion.txt
|
||||||
|
|
||||||
OBJ = $(patsubst %.cpp,%.o,$(SRC))
|
OBJ = $(patsubst %.cpp,%.o,$(SRC))
|
||||||
LDFLAGS += -pthread -g -lmcheck $(STATIC)
|
LDFLAGS += -pthread -g -lmcheck $(STATIC)
|
||||||
CPPFLAGS += -DSPAWN_SELF -g -Wall \
|
CPPFLAGS += -DSPAWN_SELF -DRELAY_HEARTBEAT -g -Wall \
|
||||||
-DSVN_REV=\"$(shell cat $(SVNINFO) 2>/dev/null || svnversion -n ..)\"
|
-DSVN_REV=\"$(shell cat $(SVNINFO) 2>/dev/null || svnversion -n ..)\"
|
||||||
|
|
||||||
# turn on semaphore debugging
|
# turn on semaphore debugging
|
||||||
|
|
|
@ -114,19 +114,24 @@ CookieRef::~CookieRef()
|
||||||
void
|
void
|
||||||
CookieRef::_Connect( int socket, HostID hid, int nPlayersH, int nPlayersT )
|
CookieRef::_Connect( int socket, HostID hid, int nPlayersH, int nPlayersT )
|
||||||
{
|
{
|
||||||
CRefMgr::Get()->Associate( socket, this );
|
if ( CRefMgr::Get()->Associate( socket, this ) ) {
|
||||||
if ( hid == HOST_ID_NONE ) {
|
if ( hid == HOST_ID_NONE ) {
|
||||||
hid = nextHostID();
|
hid = nextHostID();
|
||||||
logf( XW_LOGINFO, "assigned host id: %x", hid );
|
logf( XW_LOGINFO, "assigned host id: %x", hid );
|
||||||
|
} else {
|
||||||
|
logf( XW_LOGINFO, "NOT assigned host id; why?" );
|
||||||
|
}
|
||||||
|
pushConnectEvent( socket, hid, nPlayersH, nPlayersT );
|
||||||
|
handleEvents();
|
||||||
|
} else {
|
||||||
|
logf( XW_LOGINFO, "dropping connect event; already connected" );
|
||||||
}
|
}
|
||||||
pushConnectEvent( socket, hid, nPlayersH, nPlayersT );
|
|
||||||
handleEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CookieRef::_Reconnect( int socket, HostID hid, int nPlayersH, int nPlayersT )
|
CookieRef::_Reconnect( int socket, HostID hid, int nPlayersH, int nPlayersT )
|
||||||
{
|
{
|
||||||
CRefMgr::Get()->Associate( socket, this );
|
(void)CRefMgr::Get()->Associate( socket, this );
|
||||||
/* MutexLock ml( &m_EventsMutex ); */
|
/* MutexLock ml( &m_EventsMutex ); */
|
||||||
pushReconnectEvent( socket, hid, nPlayersH, nPlayersT );
|
pushReconnectEvent( socket, hid, nPlayersH, nPlayersT );
|
||||||
handleEvents();
|
handleEvents();
|
||||||
|
@ -135,6 +140,7 @@ CookieRef::_Reconnect( int socket, HostID hid, int nPlayersH, int nPlayersT )
|
||||||
void
|
void
|
||||||
CookieRef::_Disconnect( int socket, HostID hostID )
|
CookieRef::_Disconnect( int socket, HostID hostID )
|
||||||
{
|
{
|
||||||
|
logf( XW_LOGINFO, "%s(socket=%d, hostID=%d)", __func__, socket, hostID );
|
||||||
CRefMgr::Get()->Disassociate( socket, this );
|
CRefMgr::Get()->Disassociate( socket, this );
|
||||||
|
|
||||||
CRefEvent evt;
|
CRefEvent evt;
|
||||||
|
@ -225,6 +231,7 @@ CookieRef::notifyDisconn( const CRefEvent* evt )
|
||||||
void
|
void
|
||||||
CookieRef::removeSocket( int socket )
|
CookieRef::removeSocket( int socket )
|
||||||
{
|
{
|
||||||
|
logf( XW_LOGINFO, "%s(%d)", __func__, socket );
|
||||||
int count;
|
int count;
|
||||||
{
|
{
|
||||||
/* RWWriteLock rwl( &m_sockets_rwlock ); */
|
/* RWWriteLock rwl( &m_sockets_rwlock ); */
|
||||||
|
|
|
@ -95,7 +95,7 @@ CookieRef*
|
||||||
CRefMgr::FindOpenGameFor( const char* cORn, bool isCookie,
|
CRefMgr::FindOpenGameFor( const char* cORn, bool isCookie,
|
||||||
HostID hid, int nPlayersH, int nPlayersT )
|
HostID hid, int nPlayersH, int nPlayersT )
|
||||||
{
|
{
|
||||||
logf( XW_LOGINFO, "FindOpenGameFor with %s", cORn );
|
logf( XW_LOGINFO, "%s(%s)", __func__, cORn );
|
||||||
CookieRef* cref = NULL;
|
CookieRef* cref = NULL;
|
||||||
RWReadLock rwl( &m_cookieMapRWLock );
|
RWReadLock rwl( &m_cookieMapRWLock );
|
||||||
|
|
||||||
|
@ -202,17 +202,26 @@ CRefMgr::getMakeCookieRef_locked( const char* cORn, bool isCookie, HostID hid,
|
||||||
return cref;
|
return cref;
|
||||||
} /* getMakeCookieRef_locked */
|
} /* getMakeCookieRef_locked */
|
||||||
|
|
||||||
void
|
bool
|
||||||
CRefMgr::Associate( int socket, CookieRef* cref )
|
CRefMgr::Associate( int socket, CookieRef* cref )
|
||||||
{
|
{
|
||||||
|
bool isNew = false;
|
||||||
MutexLock ml( &m_SocketStuffMutex );
|
MutexLock ml( &m_SocketStuffMutex );
|
||||||
SocketMap::iterator iter = m_SocketStuff.find( socket );
|
SocketMap::iterator iter = m_SocketStuff.find( socket );
|
||||||
if ( iter != m_SocketStuff.end() ) {
|
/* This isn't enough. Must provide a way to reuse sockets should a
|
||||||
logf( XW_LOGINFO, "replacing existing cref/threadID pair for socket %d", socket );
|
genuinely different connection appear. Now maybe we already remove
|
||||||
|
this reference when a socket is closed. Test this! Or assert
|
||||||
|
something here. Bottom line: need to swallow repeated/duplicate
|
||||||
|
connect messages from same host. */
|
||||||
|
if ( iter == m_SocketStuff.end() ) {
|
||||||
|
SocketStuff* stuff = new SocketStuff( cref );
|
||||||
|
m_SocketStuff.insert( pair< int, SocketStuff* >( socket, stuff ) );
|
||||||
|
isNew = true;
|
||||||
|
} else {
|
||||||
|
logf( XW_LOGERROR, "Already have cref/threadID pair for socket %d; "
|
||||||
|
"error???", socket );
|
||||||
}
|
}
|
||||||
|
return isNew;
|
||||||
SocketStuff* stuff = new SocketStuff( cref );
|
|
||||||
m_SocketStuff.insert( pair< int, SocketStuff* >( socket, stuff ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -69,7 +69,7 @@ class CRefMgr {
|
||||||
void UnlockAll() { pthread_rwlock_unlock( &m_cookieMapRWLock ); }
|
void UnlockAll() { pthread_rwlock_unlock( &m_cookieMapRWLock ); }
|
||||||
|
|
||||||
/* Track sockets independent of cookie refs */
|
/* Track sockets independent of cookie refs */
|
||||||
void Associate( int socket, CookieRef* cref );
|
bool Associate( int socket, CookieRef* cref );
|
||||||
void Disassociate( int socket, CookieRef* cref );
|
void Disassociate( int socket, CookieRef* cref );
|
||||||
pthread_mutex_t* GetWriteMutexForSocket( int socket );
|
pthread_mutex_t* GetWriteMutexForSocket( int socket );
|
||||||
void RemoveSocketRefs( int socket );
|
void RemoveSocketRefs( int socket );
|
||||||
|
@ -170,7 +170,7 @@ class SafeCref {
|
||||||
bool HandleHeartbeat( HostID id, int socket ) {
|
bool HandleHeartbeat( HostID id, int socket ) {
|
||||||
if ( IsValid() ) {
|
if ( IsValid() ) {
|
||||||
m_cref->_HandleHeartbeat( id, socket );
|
m_cref->_HandleHeartbeat( id, socket );
|
||||||
return true
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ XWThreadPool::Stop()
|
||||||
void
|
void
|
||||||
XWThreadPool::AddSocket( int socket )
|
XWThreadPool::AddSocket( int socket )
|
||||||
{
|
{
|
||||||
logf( XW_LOGINFO, "AddSocket(%d)", socket );
|
logf( XW_LOGINFO, "%s(%d)", __func__, socket );
|
||||||
{
|
{
|
||||||
RWWriteLock ml( &m_activeSocketsRWLock );
|
RWWriteLock ml( &m_activeSocketsRWLock );
|
||||||
m_activeSockets.push_back( socket );
|
m_activeSockets.push_back( socket );
|
||||||
|
@ -166,6 +166,7 @@ XWThreadPool::CloseSocket( int socket )
|
||||||
bool
|
bool
|
||||||
XWThreadPool::get_process_packet( int socket )
|
XWThreadPool::get_process_packet( int socket )
|
||||||
{
|
{
|
||||||
|
bool success = false;
|
||||||
short packetSize;
|
short packetSize;
|
||||||
assert( sizeof(packetSize) == 2 );
|
assert( sizeof(packetSize) == 2 );
|
||||||
|
|
||||||
|
@ -173,26 +174,25 @@ XWThreadPool::get_process_packet( int socket )
|
||||||
sizeof(packetSize), MSG_WAITALL );
|
sizeof(packetSize), MSG_WAITALL );
|
||||||
if ( nRead != 2 ) {
|
if ( nRead != 2 ) {
|
||||||
killSocket( socket, "nRead != 2" );
|
killSocket( socket, "nRead != 2" );
|
||||||
return false;
|
} else {
|
||||||
|
packetSize = ntohs( packetSize );
|
||||||
|
|
||||||
|
if ( packetSize < 0 || packetSize > MAX_MSG_LEN ) {
|
||||||
|
killSocket( socket, "packetSize wrong" );
|
||||||
|
} else {
|
||||||
|
unsigned char buf[MAX_MSG_LEN];
|
||||||
|
nRead = recv( socket, buf, packetSize, MSG_WAITALL );
|
||||||
|
|
||||||
|
if ( nRead != packetSize ) {
|
||||||
|
killSocket( socket, "nRead != packetSize" );
|
||||||
|
} else {
|
||||||
|
logf( XW_LOGINFO, "read %d bytes", nRead );
|
||||||
|
|
||||||
|
logf( XW_LOGINFO, "calling m_pFunc" );
|
||||||
|
success = (*m_pFunc)( buf, packetSize, socket );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packetSize = ntohs( packetSize );
|
|
||||||
if ( packetSize < 0 || packetSize > MAX_MSG_LEN ) {
|
|
||||||
killSocket( socket, "packetSize wrong" );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char buf[MAX_MSG_LEN];
|
|
||||||
nRead = recv( socket, buf, packetSize, MSG_WAITALL );
|
|
||||||
if ( nRead != packetSize ) {
|
|
||||||
killSocket( socket, "nRead != packetSize" );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
logf( XW_LOGINFO, "read %d bytes\n", nRead );
|
|
||||||
|
|
||||||
logf( XW_LOGINFO, "calling m_pFunc" );
|
|
||||||
bool success = (*m_pFunc)( buf, packetSize, socket );
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
} /* get_process_packet */
|
} /* get_process_packet */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue