- attempt to fix network game play 'stuttering'

This commit is contained in:
Mark Vejvoda
2011-11-25 05:37:55 +00:00
parent c6b7d3991e
commit e2135f76eb
5 changed files with 96 additions and 82 deletions

View File

@@ -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<bool,Socket*> 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<bool,Socket*> ConnectionSlot::getSocketInfo() {
pair<bool,Socket*> 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;

View File

@@ -147,6 +147,7 @@ public:
bool isReady() const {return ready;}
virtual Socket* getSocket();
pair<bool,Socket*> getSocketInfo();
virtual void close();
//virtual bool getFogOfWar();

View File

@@ -747,7 +747,7 @@ void ServerInterface::checkForCompletedClients(std::map<int,bool> & mapSlotSigna
}
}
void ServerInterface::checForLaggingClients(std::map<int,bool> &mapSlotSignalledList,
void ServerInterface::checkForLaggingClients(std::map<int,bool> &mapSlotSignalledList,
std::map<int,ConnectionSlotEvent> &eventList,
std::map<PLATFORM_SOCKET,bool> &socketTriggeredList,
std::vector <string> &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<int,ConnectionSlotEvent> eventList;
std::map<int,bool> 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<int,ConnectionSlotEvent> eventList;
std::map<int,bool> mapSlotSignalledList;
checForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList);
checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList);
}
//printf("\nServerInterface::update -- G\n");

View File

@@ -204,7 +204,7 @@ private:
protected:
void signalClientsToRecieveData(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList, std::map<int,ConnectionSlotEvent> & eventList, std::map<int,bool> & mapSlotSignalledList);
void checkForCompletedClients(std::map<int,bool> & mapSlotSignalledList,std::vector <string> &errorMsgList,std::map<int,ConnectionSlotEvent> &eventList);
void checForLaggingClients(std::map<int,bool> &mapSlotSignalledList, std::map<int,ConnectionSlotEvent> &eventList, std::map<PLATFORM_SOCKET,bool> &socketTriggeredList,std::vector <string> &errorMsgList);
void checkForLaggingClients(std::map<int,bool> &mapSlotSignalledList, std::map<int,ConnectionSlotEvent> &eventList, std::map<PLATFORM_SOCKET,bool> &socketTriggeredList,std::vector <string> &errorMsgList);
void executeNetworkCommandsFromClients();
void dispatchPendingChatMessages(std::vector <string> &errorMsgList);
};

View File

@@ -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<char*>(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<char*>(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<char*>(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) {