diff --git a/xwords4/relay/cref.cpp b/xwords4/relay/cref.cpp index eb83f60ed..d888e6398 100644 --- a/xwords4/relay/cref.cpp +++ b/xwords4/relay/cref.cpp @@ -81,7 +81,7 @@ SocketsIterator::Next() void CookieRef::ReInit( const char* cookie, const char* connName, CookieID id, - int langCode, int nPlayers ) + int langCode, int nPlayers, int nAlreadyHere ) { m_cookie = cookie==NULL?"":cookie; m_connName = connName==NULL?"":connName; @@ -90,7 +90,7 @@ CookieRef::ReInit( const char* cookie, const char* connName, CookieID id, m_curState = XWS_INITED; m_nextHostID = HOST_ID_SERVER; m_nPlayersSought = nPlayers; - m_nPlayersHere = 0; + m_nPlayersHere = nAlreadyHere; m_locking_thread = 0; m_starttime = uptime(); m_gameFull = false; @@ -112,10 +112,10 @@ CookieRef::ReInit( const char* cookie, const char* connName, CookieID id, CookieRef::CookieRef( const char* cookie, const char* connName, CookieID id, - int langCode, int nPlayers ) + int langCode, int nPlayersT, int nAlreadyHere ) { pthread_mutex_init( &m_mutex, NULL ); - ReInit( cookie, connName, id, langCode, nPlayers ); + ReInit( cookie, connName, id, langCode, nPlayersT, nAlreadyHere ); } CookieRef::~CookieRef() @@ -269,18 +269,6 @@ CookieRef::SocketForHost( HostID dest ) return socket; } -/* The idea here is: have we never seen the XW_ST_ALLCONNECTED state. This - needs to include any states reachable from XW_ST_ALLCONNECTED from which - recovery back to XW_ST_ALLCONNECTED is possible. This is used to decide - whether to admit a connection based on its cookie -- whether that coookie - should join an existing cref or get a new one? */ -bool -CookieRef::NeverFullyConnected() -{ - return m_curState != XWS_ALLCONND - && m_curState != XWS_MISSING; -} - bool CookieRef::GameOpen( const char* cookie ) { @@ -521,22 +509,6 @@ CookieRef::pushLastSocketGoneEvent() m_eventQueue.push_back( evt ); } -void -CookieRef::checkHaveRoom( const CRefEvent* evt ) -{ - CRefEvent newEvt; - - assert ( m_nPlayersSought > 0 ); - if ( m_nPlayersSought < m_nPlayersHere + evt->u.con.nPlayersH ) { - newEvt.type = XWE_TOO_MANY; - newEvt.u.rmsock.socket = evt->u.con.socket; - } else { - newEvt = *evt; - newEvt.type = XWE_HAVE_ROOM; - } - m_eventQueue.push_back( newEvt ); -} - void CookieRef::handleEvents() { @@ -558,10 +530,6 @@ CookieRef::handleEvents() switch( takeAction ) { - case XWA_CHECK_HAVE_ROOM: - checkHaveRoom( &evt ); - break; - case XWA_SEND_CONNRSP: if ( increasePlayerCounts( &evt, false ) ) { setAllConnectedTimer(); @@ -660,7 +628,7 @@ CookieRef::handleEvents() CRefMgr::Get()->IncrementFullCount(); cancelAllConnectedTimer(); sendAllHere( true ); - checkSomeMissing(); + /* checkSomeMissing(); */ break; case XWA_SNDALLHERE_2: @@ -1046,29 +1014,6 @@ CookieRef::sendAllHere( bool initial ) } } /* sendAllHere */ -void -CookieRef::checkSomeMissing( void ) -{ - logf( XW_LOGINFO, "%s", __func__ ); - /* int count = 0; */ - - /* vector::iterator iter; */ - /* for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) { */ - /* count += iter->m_nPlayersH; */ - /* } */ - /* /\* Don't really need the iterator above.... *\/ */ - /* assert( count == m_nPlayersHere ); */ - - logf( XW_LOGINFO, "%s; count=%d; nPlayersS=%d", __func__, - m_nPlayersHere, m_nPlayersSought ); - - assert( m_nPlayersHere <= m_nPlayersSought ); - if ( m_nPlayersHere < m_nPlayersSought ) { - CRefEvent evt( XWE_SOMEMISSING ); - m_eventQueue.push_back( evt ); - } -} - #define CONNNAME_DELIM ' ' /* ' ' so will wrap in browser */ /* Does my seed belong as part of existing connName */ bool diff --git a/xwords4/relay/cref.h b/xwords4/relay/cref.h index c855f62b0..e85150b75 100644 --- a/xwords4/relay/cref.h +++ b/xwords4/relay/cref.h @@ -68,9 +68,9 @@ class CookieRef { friend class CookieMapIterator; CookieRef( const char* cookie, const char* connName, CookieID id, - int langCode, int nPlayersH ); + int langCode, int nPlayersT, int nPlayersH ); void ReInit( const char* cookie, const char* connName, CookieID id, - int langCode, int nPlayers ); + int langCode, int nPlayers, int nAlreadyHere ); ~CookieRef(); void Clear(void); /* make clear it's unused */ @@ -94,7 +94,6 @@ class CookieRef { int GetHeartbeat() { return m_heatbeat; } int SocketForHost( HostID dest ); - bool NeverFullyConnected(); bool AlreadyHere( unsigned short seed, int socket ); bool GameOpen( const char* cookie ); diff --git a/xwords4/relay/crefmgr.cpp b/xwords4/relay/crefmgr.cpp index 18186af49..736a49e12 100644 --- a/xwords4/relay/crefmgr.cpp +++ b/xwords4/relay/crefmgr.cpp @@ -245,14 +245,17 @@ CRefMgr::getMakeCookieRef_locked( const char* cookie, HostID hid, int socket, */ char connNameBuf[MAX_CONNNAME_LEN+1] = {0}; + int alreadyHere = 0; CookieID cid = m_db->FindOpen( cookie, langCode, nPlayersT, nPlayersH, wantsPublic, - connNameBuf, sizeof(connNameBuf) ); + connNameBuf, sizeof(connNameBuf), + &alreadyHere ); if ( cid > 0 ) { cref = getCookieRef_impl( cid ); } else { cid = nextCID( NULL ); - cref = AddNew( cookie, connNameBuf, cid, langCode, nPlayersT ); + cref = AddNew( cookie, connNameBuf, cid, langCode, + nPlayersT, alreadyHere ); if ( !connNameBuf[0] ) { /* didn't exist in DB */ m_db->AddNew( cookie, cref->ConnName(), cid, langCode, nPlayersT, wantsPublic || makePublic ); @@ -274,15 +277,16 @@ CRefMgr::getMakeCookieRef_locked( const char* connName, HostID hid, int socket, /* fetch these from DB */ char cookie[MAX_INVITE_LEN+1]; int langCode; - int nPlayersT; + int nPlayersT = 0; + int nAlreadyHere = 0; CookieID cid = m_db->FindGame( connName, cookie, sizeof(cookie), - &langCode, &nPlayersT ); + &langCode, &nPlayersT, &nAlreadyHere ); if ( 0 != cid ) { /* already open */ cref = getCookieRef_impl( cid ); } else { CookieID cid = nextCID( NULL ); - cref = AddNew( cookie, connName, cid, langCode, nPlayersT ); + cref = AddNew( cookie, connName, cid, langCode, nPlayersT, nAlreadyHere ); m_db->AddCID( connName, cid ); } return cref; @@ -435,7 +439,7 @@ CRefMgr::heartbeatProc( void* closure ) CookieRef* CRefMgr::AddNew( const char* cookie, const char* connName, CookieID id, - int langCode, int nPlayers ) + int langCode, int nPlayers, int nAlreadyHere ) { if ( 0 == connName[0] ) { connName = NULL; @@ -451,10 +455,11 @@ CRefMgr::AddNew( const char* cookie, const char* connName, CookieID id, if ( !!ref ) { logf( XW_LOGVERBOSE1, "using from free list" ); - ref->ReInit( cookie, connName, id, langCode, nPlayers ); + ref->ReInit( cookie, connName, id, langCode, nPlayers, nAlreadyHere ); } else { logf( XW_LOGVERBOSE1, "calling constructor" ); - ref = new CookieRef( cookie, connName, id, langCode, nPlayers ); + ref = new CookieRef( cookie, connName, id, langCode, nPlayers, + nAlreadyHere ); } ref->assignConnName(); diff --git a/xwords4/relay/crefmgr.h b/xwords4/relay/crefmgr.h index 74e921f87..4c646d42e 100644 --- a/xwords4/relay/crefmgr.h +++ b/xwords4/relay/crefmgr.h @@ -151,7 +151,7 @@ class CRefMgr { bool checkCookieRef_locked( CookieRef* cref ); CookieRef* getCookieRef_impl( CookieID cookieID ); CookieRef* AddNew( const char* cookie, const char* connName, CookieID id, - int langCode, int nPlayers ); + int langCode, int nPlayers, int nAlreadyHere ); CookieRef* FindOpenGameFor( const char* cookie, const char* connName, HostID hid, int socket, int nPlayersH, int nPlayersS, int gameSeed, int langCode, diff --git a/xwords4/relay/dbmgr.cpp b/xwords4/relay/dbmgr.cpp index 9e86c700f..cb5bfb2e0 100644 --- a/xwords4/relay/dbmgr.cpp +++ b/xwords4/relay/dbmgr.cpp @@ -90,8 +90,8 @@ DBMgr::AddNew( const char* cookie, const char* connName, CookieID cid, logf( XW_LOGINFO, "passing %s", buf ); execSql( buf ); #else - const char* command = "INSERT INTO games (cookie, connName, ntotal, nhere, lang) " - "VALUES( $1, $2, $3, $4, $5 )"; + const char* command = "INSERT INTO games (cookie, connName, ntotal, " + "nJoined, lang) VALUES( $1, $2, $3, $4, $5 )"; char nPlayersTBuf[4]; char langBuf[4]; @@ -114,11 +114,11 @@ DBMgr::AddNew( const char* cookie, const char* connName, CookieID cid, CookieID DBMgr::FindGame( const char* connName, char* cookieBuf, int bufLen, - int* langP, int* nPlayersTP ) + int* langP, int* nPlayersTP, int* nPlayersHP ) { CookieID cid = 0; - const char* fmt = "SELECT cid, room, lang, nTotal from " TABLE_NAME + const char* fmt = "SELECT cid, room, lang, nTotal, nJoined FROM " TABLE_NAME " where connName = '%s' " "LIMIT 1"; char query[256]; @@ -131,6 +131,7 @@ DBMgr::FindGame( const char* connName, char* cookieBuf, int bufLen, snprintf( cookieBuf, bufLen, "%s", PQgetvalue( result, 0, 1 ) ); *langP = atoi( PQgetvalue( result, 0, 2 ) ); *nPlayersTP = atoi( PQgetvalue( result, 0, 3 ) ); + *nPlayersHP = atoi( PQgetvalue( result, 0, 4 ) ); } PQclear( result ); @@ -140,11 +141,12 @@ DBMgr::FindGame( const char* connName, char* cookieBuf, int bufLen, CookieID DBMgr::FindOpen( const char* cookie, int lang, int nPlayersT, int nPlayersH, - bool wantsPublic, char* connNameBuf, int bufLen ) + bool wantsPublic, char* connNameBuf, int bufLen, + int* nPlayersHP ) { CookieID cid = 0; - const char* fmt = "SELECT cid, connName FROM " TABLE_NAME " " + const char* fmt = "SELECT cid, connName, nJoined FROM " TABLE_NAME " " "WHERE room = '%s' " "AND lang = %d " "AND nTotal = %d " @@ -160,6 +162,7 @@ DBMgr::FindOpen( const char* cookie, int lang, int nPlayersT, int nPlayersH, if ( 1 == PQntuples( result ) ) { cid = atoi( PQgetvalue( result, 0, 0 ) ); snprintf( connNameBuf, bufLen, "%s", PQgetvalue( result, 0, 1 ) ); + *nPlayersHP = atoi( PQgetvalue( result, 0, 2 ) ); /* cid may be 0, but should use game anyway */ } PQclear( result ); diff --git a/xwords4/relay/dbmgr.h b/xwords4/relay/dbmgr.h index 79aa6310f..f34bea367 100644 --- a/xwords4/relay/dbmgr.h +++ b/xwords4/relay/dbmgr.h @@ -36,10 +36,10 @@ class DBMgr { int langCode, int nPlayersT, bool isPublic ); CookieID FindGame( const char* connName, char* cookieBuf, int bufLen, - int* langP, int* nPlayersTP ); + int* langP, int* nPlayersTP, int* nPlayersHP ); CookieID FindOpen( const char* cookie, int lang, int nPlayersT, int nPlayersH, bool wantsPublic, - char* connNameBuf, int bufLen ); + char* connNameBuf, int bufLen, int* nPlayersHP ); void AddPlayers( const char* const connName, int nToAdd ); void RmPlayers( const char* const connName, int nToAdd ); diff --git a/xwords4/relay/states.cpp b/xwords4/relay/states.cpp index d510d3000..00244b480 100644 --- a/xwords4/relay/states.cpp +++ b/xwords4/relay/states.cpp @@ -72,6 +72,7 @@ static StateTable g_stateTable[] = { { XWS_ALLCONND, XWE_RECONNECT, XWA_SEND_RERSP, XWS_ALLCONND }, { XWS_ALLCONND, XWE_ALLHERE, XWA_NONE, XWS_ALLCONND }, +{ XWS_ALLCONND, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_ALLCONND }, /* { XWS_WAITMORE, XWE_GAMEFULL, XWA_SENDALLHERE, XWS_ALLCONND }, */ /* { XWS_WAITMORE, XWE_CHECKFULL, XWA_, XWS_WAITMORE }, */ @@ -85,21 +86,25 @@ static StateTable g_stateTable[] = { -{ XWS_CHK_ALLHERE, XWE_ALLHERE, XWA_SENDALLHERE, XWS_ALLCONND }, -{ XWS_ALLCONND, XWE_SOMEMISSING, XWA_NONE, XWS_MISSING }, -{ XWS_CHK_ALLHERE, XWE_SOMEMISSING, XWA_NONE, XWS_WAITMORE }, +/* { XWS_CHK_ALLHERE, XWE_ALLHERE, XWA_SENDALLHERE, XWS_ALLCONND }, */ +/* { XWS_ALLCONND, XWE_SOMEMISSING, XWA_NONE, XWS_ALLCONND }, */ +{ XWS_ALLCONND, XWE_ALLGONE, XWA_NONE, XWS_ALLCONND }, -{ XWS_ALLCONND, XWE_DISCONN, XWA_DISCONNECT, XWS_MISSING }, -{ XWS_WAITMORE, XWE_DISCONN, XWA_DISCONNECT, XWS_WAITMORE }, -{ XWS_MISSING, XWE_DISCONN, XWA_DISCONNECT, XWS_MISSING }, + + +/* { XWS_CHK_ALLHERE, XWE_SOMEMISSING, XWA_NONE, XWS_WAITMORE }, */ + +/* { XWS_ALLCONND, XWE_DISCONN, XWA_DISCONNECT, XWS_MISSING }, */ +/* { XWS_WAITMORE, XWE_DISCONN, XWA_DISCONNECT, XWS_WAITMORE }, */ +/* { XWS_MISSING, XWE_DISCONN, XWA_DISCONNECT, XWS_MISSING }, */ /* EMPTY means have messages to send but no connections. Time out and free memory after a while. BUT: don't I really want to keep these forever and free the oldest ones if memory usage realy does become a problem. There's no problem now! */ -{ XWS_WAITMORE, XWE_NOMORESOCKETS, XWA_NONE, XWS_WAITMORE }, -{ XWS_MISSING, XWE_NOMORESOCKETS, XWA_NOTE_EMPTY, XWS_MSGONLY }, -{ XWS_MSGONLY, XWE_NOMOREMSGS, XWA_NONE, XWS_DEAD }, +/* { XWS_WAITMORE, XWE_NOMORESOCKETS, XWA_NONE, XWS_WAITMORE }, */ +/* { XWS_MISSING, XWE_NOMORESOCKETS, XWA_NOTE_EMPTY, XWS_MSGONLY }, */ +/* { XWS_MSGONLY, XWE_NOMOREMSGS, XWA_NONE, XWS_DEAD }, */ /* { XWS_MSGONLY, XWE_NOMOREMSGS, XWA_NONE, XWS_DEAD }, */ { XWS_ANY, XWE_NOMORESOCKETS, XWA_NONE, XWS_DEAD }, @@ -110,13 +115,13 @@ static StateTable g_stateTable[] = { { XWS_INITED, XWE_RECONNECT, XWA_SEND_RERSP, XWS_WAITMORE }, { XWS_MSGONLY, XWE_RECONNECT, XWA_SEND_RERSP, XWS_WAITMORE }, -{ XWS_MISSING, XWE_RECONNECT, XWA_SEND_RERSP, XWS_CHK_ALLHERE_2 }, -{ XWS_CHK_ALLHERE_2, XWE_ALLHERE, XWA_SNDALLHERE_2, XWS_ALLCONND }, -{ XWS_CHK_ALLHERE_2, XWE_SOMEMISSING, XWA_NONE, XWS_MISSING }, +/* { XWS_MISSING, XWE_RECONNECT, XWA_SEND_RERSP, XWS_CHK_ALLHERE_2 }, */ +/* { XWS_CHK_ALLHERE_2, XWE_ALLHERE, XWA_SNDALLHERE_2, XWS_ALLCONND }, */ +/* { XWS_CHK_ALLHERE_2, XWE_SOMEMISSING, XWA_NONE, XWS_MISSING }, */ { XWS_WAITMORE, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_WAITMORE }, -{ XWS_ALLCONND, XWE_REMOVESOCKET, XWA_REMOVESOCK_2, XWS_MISSING }, -{ XWS_MISSING, XWE_REMOVESOCKET, XWA_REMOVESOCK_2, XWS_MISSING }, +/* { XWS_ALLCONND, XWE_REMOVESOCKET, XWA_REMOVESOCK_2, XWS_MISSING }, */ +/* { XWS_MISSING, XWE_REMOVESOCKET, XWA_REMOVESOCK_2, XWS_MISSING }, */ #ifdef RELAY_HEARTBEAT { XWS_ALLCONND, XWE_HEARTFAILED, XWA_HEARTDISCONN, XWS_MISSING }, @@ -131,17 +136,17 @@ static StateTable g_stateTable[] = { /* Connect timer */ { XWS_WAITMORE, XWE_CONNTIMER, XWA_TIMERDISCONN, XWS_DEAD }, -{ XWS_MISSING, XWE_CONNTIMER, XWA_NONE, XWS_MISSING }, +/* { XWS_MISSING, XWE_CONNTIMER, XWA_NONE, XWS_MISSING }, */ { XWS_ALLCONND, XWE_CONNTIMER, XWA_NONE, XWS_ALLCONND }, { XWS_WAITMORE, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_WAITMORE }, -{ XWS_ALLCONND, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_MISSING }, -{ XWS_MISSING, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_MISSING }, +/* { XWS_ALLCONND, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_MISSING }, */ +/* { XWS_MISSING, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_MISSING }, */ { XWS_DEAD, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_DEAD }, /* This is our bread-n-butter */ { XWS_ALLCONND, XWE_FORWARDMSG, XWA_FWD, XWS_ALLCONND }, -{ XWS_MISSING, XWE_FORWARDMSG, XWA_FWD, XWS_MISSING }, +/* { XWS_MISSING, XWE_FORWARDMSG, XWA_FWD, XWS_MISSING }, */ { XWS_DEAD, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_DEAD } @@ -184,12 +189,12 @@ stateString( XW_RELAY_STATE state ) CASESTR(XWS_WAITING_ACKS); CASESTR(XWS_ALLCONND); CASESTR(XWS_DEAD); - CASESTR(XWS_MISSING); + /* CASESTR(XWS_MISSING); */ CASESTR(XWS_MSGONLY); - CASESTR(XWS_CHK_ALLHERE); - CASESTR(XWS_CHK_ALLHERE_2); - CASESTR(XWS_CHKCOUNTS_INIT); - CASESTR(XWS_ROOMCHK); + /* CASESTR(XWS_CHK_ALLHERE); */ + /* CASESTR(XWS_CHK_ALLHERE_2); */ + /* CASESTR(XWS_CHKCOUNTS_INIT); */ + /* CASESTR(XWS_ROOMCHK); */ default: assert(0); } @@ -224,9 +229,9 @@ eventString( XW_RELAY_EVENT evt ) CASESTR(XWE_NOMOREMSGS); CASESTR(XWE_NOTIFYDISCON); CASESTR(XWE_ALLHERE); - CASESTR(XWE_SOMEMISSING); - CASESTR(XWE_TOO_MANY); - CASESTR(XWE_HAVE_ROOM); + /* CASESTR(XWE_SOMEMISSING); */ + /* CASESTR(XWE_TOO_MANY); */ + /* CASESTR(XWE_HAVE_ROOM); */ CASESTR(XWE_SHUTDOWN); default: diff --git a/xwords4/relay/states.h b/xwords4/relay/states.h index f5156827d..8d6175622 100644 --- a/xwords4/relay/states.h +++ b/xwords4/relay/states.h @@ -28,16 +28,16 @@ enum { XWS_NONE ,XWS_ANY /* wildcard */ - ,XWS_CHKCOUNTS_INIT /* from initial state, check if all players + /* ,XWS_CHKCOUNTS_INIT */ /* from initial state, check if all players are here. Success should be an error, actually: 1-device game. */ ,XWS_WAITING_ACKS - ,XWS_CHK_ALLHERE /* Need to see if all expected devices/players + /* ,XWS_CHK_ALLHERE */ /* Need to see if all expected devices/players are on board. */ - ,XWS_CHK_ALLHERE_2 /* same as above, but triggered by a reconnect + /* ,XWS_CHK_ALLHERE_2 */ /* same as above, but triggered by a reconnect rather than a connect request */ ,XWS_INITED /* Relay's running and the object's been @@ -54,14 +54,14 @@ enum { relay to do its work. This is the state we're in most of the time. */ - ,XWS_MISSING /* We've been fully connected before but lost + /* ,XWS_MISSING */ /* We've been fully connected before but lost somebody. Once [s]he's back we can be fully connected again. */ ,XWS_MSGONLY /* We have no connections but still messages to send */ - ,XWS_ROOMCHK /* do we have room for as many players as are + /* ,XWS_ROOMCHK */ /* do we have room for as many players as are being provided */ ,XWS_DEAD /* About to kill the object */ @@ -73,9 +73,10 @@ typedef enum { XWE_NONE ,XWE_ALLHERE /* notify that all expected players are arrived */ - ,XWE_SOMEMISSING /* notify that some expected players are still missing */ - ,XWE_HAVE_ROOM - ,XWE_TOO_MANY + /* ,XWE_SOMEMISSING */ /* notify that some expected players are still missing */ + ,XWE_ALLGONE + /* ,XWE_HAVE_ROOM */ + /* ,XWE_TOO_MANY */ ,XWE_DEVCONNECT /* A device is connecting using the cookie for */ /*,XWE_HOSTCONNECT*/ /* this object, as host or guest */