From e2135f76ebd6356b316e7b48a3c1ed039aa78fc6 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Fri, 25 Nov 2011 05:37:55 +0000 Subject: [PATCH] - attempt to fix network game play 'stuttering' --- source/glest_game/network/connection_slot.cpp | 48 ++++--- source/glest_game/network/connection_slot.h | 1 + .../glest_game/network/server_interface.cpp | 8 +- source/glest_game/network/server_interface.h | 2 +- .../sources/platform/posix/socket.cpp | 119 +++++++++--------- 5 files changed, 96 insertions(+), 82 deletions(-) diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index 8823afcac..ac898f207 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -299,8 +299,9 @@ void ConnectionSlot::updateSlot(ConnectionSlotEvent *event) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); if((serverInterface->getGameHasBeenInitiated() == false || - (this->getSocket() != NULL && socketTriggered == true))) { - if(this->isConnected() == false || socketTriggered == true) { + //(this->getSocket() != NULL && socketTriggered == true))) { + socketTriggered == true)) { + if(socketTriggered == true || this->isConnected() == false) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); @@ -334,7 +335,8 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - if(this->getSocket() == NULL) { + pair socketInfo = this->getSocketInfo(); + if(socketInfo.second == NULL) { if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false; if(networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false; if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false; @@ -359,7 +361,9 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); + Socket *newSocket = serverInterface->getServerSocket()->accept(); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] called accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); if(newSocket != NULL) { // Set Socket as non-blocking @@ -416,7 +420,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); //send intro message when connected - if(this->isConnected() == true) { + if(hasData == true && this->isConnected() == true) { //RandomGen random; //sessionKey = random.randRange(-100000, 100000); srand(time(NULL) / (this->playerIndex + 1)); @@ -455,7 +459,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(this->isConnected()) { + if(socketInfo.first == true) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); @@ -1040,18 +1044,6 @@ void ConnectionSlot::close() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__); } -bool ConnectionSlot::hasValidSocketId() { - //bool result = (this->getSocket() != NULL && this->getSocket()->getSocketId() > 0); - //return result; - bool result = false; - MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); - if(socket != NULL && socket->getSocketId() > 0) { - result = true; - } - return result; - -} - Mutex * ConnectionSlot::getServerSynchAccessor() { return (serverInterface != NULL ? serverInterface->getServerSynchAccessor() : NULL); } @@ -1115,6 +1107,18 @@ void ConnectionSlot::clearPendingNetworkCommandList() { safeMutexSlot.ReleaseLock(); } +bool ConnectionSlot::hasValidSocketId() { + //bool result = (this->getSocket() != NULL && this->getSocket()->getSocketId() > 0); + //return result; + bool result = false; + MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); + if(socket != NULL && socket->getSocketId() > 0) { + result = true; + } + return result; + +} + bool ConnectionSlot::isConnected() { bool result = false; MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); @@ -1133,6 +1137,16 @@ PLATFORM_SOCKET ConnectionSlot::getSocketId() { return result; } +pair ConnectionSlot::getSocketInfo() { + pair result; + MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); + result.first = (socket != NULL && socket->isConnected()); + result.second = socket; + + return result; + +} + Socket* ConnectionSlot::getSocket() { MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); return socket; diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index 4836cd3bd..3a133240a 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -147,6 +147,7 @@ public: bool isReady() const {return ready;} virtual Socket* getSocket(); + pair getSocketInfo(); virtual void close(); //virtual bool getFogOfWar(); diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index d5528803b..4d9aece41 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -747,7 +747,7 @@ void ServerInterface::checkForCompletedClients(std::map & mapSlotSigna } } -void ServerInterface::checForLaggingClients(std::map &mapSlotSignalledList, +void ServerInterface::checkForLaggingClients(std::map &mapSlotSignalledList, std::map &eventList, std::map &socketTriggeredList, std::vector &errorMsgList) { @@ -994,7 +994,7 @@ void ServerInterface::update() { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); // Step #3 check clients for any lagging scenarios and try to deal with them - checForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); + checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #4\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); @@ -1018,7 +1018,7 @@ void ServerInterface::update() { //std::map eventList; std::map mapSlotSignalledList; - checForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); + checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); } if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); @@ -1030,7 +1030,7 @@ void ServerInterface::update() { std::map eventList; std::map mapSlotSignalledList; - checForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); + checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); } //printf("\nServerInterface::update -- G\n"); diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 624de90ec..4f3b2d9c2 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -204,7 +204,7 @@ private: protected: void signalClientsToRecieveData(std::map & socketTriggeredList, std::map & eventList, std::map & mapSlotSignalledList); void checkForCompletedClients(std::map & mapSlotSignalledList,std::vector &errorMsgList,std::map &eventList); - void checForLaggingClients(std::map &mapSlotSignalledList, std::map &eventList, std::map &socketTriggeredList,std::vector &errorMsgList); + void checkForLaggingClients(std::map &mapSlotSignalledList, std::map &eventList, std::map &socketTriggeredList,std::vector &errorMsgList); void executeNetworkCommandsFromClients(); void dispatchPendingChatMessages(std::vector &errorMsgList); }; diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index 4c4fd74f3..72707f9c4 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -1090,13 +1090,13 @@ int Socket::send(const void *data, int dataSize) { if(isSocketValid() == true) { errno = 0; - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); - if(this->inSocketDestructor == true) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); - return -1; - } - inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); - safeMutexSocketDestructorFlag.ReleaseLock(); +// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); +// if(this->inSocketDestructor == true) { +// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); +// return -1; +// } +// inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); +// safeMutexSocketDestructorFlag.ReleaseLock(); MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,CODE_AT_LINE); @@ -1128,13 +1128,13 @@ int Socket::send(const void *data, int dataSize) { if(isConnected() == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data); - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); - if(this->inSocketDestructor == true) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); - return -1; - } - inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); - safeMutexSocketDestructorFlag.ReleaseLock(); +// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); +// if(this->inSocketDestructor == true) { +// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); +// return -1; +// } +// inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); +// safeMutexSocketDestructorFlag.ReleaseLock(); MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,CODE_AT_LINE); #ifdef __APPLE__ @@ -1177,13 +1177,13 @@ int Socket::send(const void *data, int dataSize) { if(isConnected() == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data); - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); - if(this->inSocketDestructor == true) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); - return -1; - } - inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); - safeMutexSocketDestructorFlag.ReleaseLock(); +// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); +// if(this->inSocketDestructor == true) { +// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); +// return -1; +// } +// inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); +// safeMutexSocketDestructorFlag.ReleaseLock(); MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,CODE_AT_LINE); const char *sendBuf = (const char *)data; @@ -1242,13 +1242,13 @@ int Socket::receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet) { ssize_t bytesReceived = 0; if(isSocketValid() == true) { - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); - if(this->inSocketDestructor == true) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); - return -1; - } - inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); - safeMutexSocketDestructorFlag.ReleaseLock(); +// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); +// if(this->inSocketDestructor == true) { +// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); +// return -1; +// } +// inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); +// safeMutexSocketDestructorFlag.ReleaseLock(); MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); @@ -1271,13 +1271,13 @@ int Socket::receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet) { break; } else if(Socket::isReadable() == true) { - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); - if(this->inSocketDestructor == true) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); - return -1; - } - inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); - safeMutexSocketDestructorFlag.ReleaseLock(); +// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); +// if(this->inSocketDestructor == true) { +// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); +// return -1; +// } +// inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); +// safeMutexSocketDestructorFlag.ReleaseLock(); MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); @@ -1329,17 +1329,16 @@ int Socket::peek(void *data, int dataSize,bool mustGetData) { if(isSocketValid() == true) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); - if(this->inSocketDestructor == true) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); - return -1; - } - inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); - safeMutexSocketDestructorFlag.ReleaseLock(); +// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); +// if(this->inSocketDestructor == true) { +// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); +// return -1; +// } +// inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); +// safeMutexSocketDestructorFlag.ReleaseLock(); //MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize)); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&dataSynchAccessorRead,mutexOwnerId); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); @@ -1369,16 +1368,16 @@ int Socket::peek(void *data, int dataSize,bool mustGetData) { */ if(Socket::isReadable() == true) { - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); - if(this->inSocketDestructor == true) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); - return -1; - } - inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); - safeMutexSocketDestructorFlag.ReleaseLock(); +// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); +// if(this->inSocketDestructor == true) { +// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); +// return -1; +// } +// inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); +// safeMutexSocketDestructorFlag.ReleaseLock(); //MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize)); - MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + string("_") + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); safeMutex.ReleaseLock(); @@ -1456,7 +1455,7 @@ bool Socket::isReadable() { //inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); //safeMutexSocketDestructorFlag.ReleaseLock(); - MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); + //MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); i= select((int)sock + 1, &set, NULL, NULL, &tv); } if(i < 0) { @@ -1493,7 +1492,7 @@ bool Socket::isWritable() { //inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); //safeMutexSocketDestructorFlag.ReleaseLock(); - MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,CODE_AT_LINE); + //MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,CODE_AT_LINE); i = select((int)sock + 1, NULL, &set, NULL, &tv); } bool result = false; @@ -1518,12 +1517,12 @@ bool Socket::isWritable() { bool Socket::isConnected() { if(isSocketValid() == false) return false; - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); - if(this->inSocketDestructor == true) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); - return false; - } - inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); +// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); +// if(this->inSocketDestructor == true) { +// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); +// return false; +// } +// inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); //if the socket is not writable then it is not conencted if(isWritable() == false) {