- attempt to fix disconnect and thread lock for in game connect games

This commit is contained in:
Mark Vejvoda 2013-02-26 07:05:46 +00:00
parent 8815a4422d
commit 45b8cf21a4
3 changed files with 91 additions and 64 deletions

View File

@ -199,6 +199,10 @@ void ConnectionSlotThread::execute() {
MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE);
int eventCount = eventList.size();
//printf("Slot thread slotIndex: %d eventCount: %d\n",slotIndex,eventCount);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount);
if(eventCount > 0) {
ConnectionSlotEvent eventCopy;
eventCopy.eventId = -1;
@ -220,9 +224,13 @@ void ConnectionSlotThread::execute() {
if(eventCopy.eventId > 0) {
ExecutingTaskSafeWrapper safeExecutingTaskMutex(this);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount,(int)eventCopy.eventId);
//printf("#1 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId);
//this->slotInterface->slotUpdateTask(&eventCopy);
this->slotUpdateTask(&eventCopy);
setTaskCompleted(eventCopy.eventId);
//printf("#2 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId);
}
}
else {
@ -406,10 +414,10 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) {
if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false;
this->setReceivedDataSynchCheck(false);
if(serverInterface->getGameHasBeenInitiated() == true &&
serverInterface->getAllowInGameConnections() == true) {
//if(serverInterface->getGameHasBeenInitiated() == true &&
// serverInterface->getAllowInGameConnections() == true) {
//printf("Checking for new client connection on slot, checkForNewClients: %d this->canAcceptConnections: %d\n",checkForNewClients,this->canAcceptConnections);
}
//}
// Is the listener socket ready to be read?
if(checkForNewClients == true && this->canAcceptConnections == true) {
@ -417,7 +425,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(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getOpenSlotCount());
bool hasOpenSlots = (serverInterface->getOpenSlotCount() > 0);
//bool hasOpenSlots = (serverInterface->getOpenSlotCount() > 0);
bool hasOpenSlots = 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());
@ -425,10 +434,10 @@ 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(serverInterface->getGameHasBeenInitiated() == true &&
serverInterface->getAllowInGameConnections() == true) {
//if(serverInterface->getGameHasBeenInitiated() == true &&
// serverInterface->getAllowInGameConnections() == true) {
//printf("Checking for new client connection on slot, hasData: %d\n",hasData);
}
//}
if(hasData == true) {
@ -1393,7 +1402,7 @@ void ConnectionSlot::close() {
//printf("Closing slot for playerIndex = %d updateServerListener = %d ready = %d\n",playerIndex,updateServerListener,ready);
if(updateServerListener == true && ready == false) {
if(updateServerListener == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s LINE: %d]\n",__FILE__,__FUNCTION__,__LINE__);
serverInterface->updateListen();
}

View File

@ -783,10 +783,10 @@ void ServerInterface::updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> &
if(Socket::isSocketValid(&clientSocket) == true) {
socketTriggeredList[clientSocket] = false;
}
else if(this->getGameHasBeenInitiated() == true &&
this->getAllowInGameConnections() == true) {
socketTriggeredList[clientSocket] = false;
}
//else if(this->getGameHasBeenInitiated() == true &&
// this->getAllowInGameConnections() == true) {
// socketTriggeredList[clientSocket] = false;
//}
}
}
}
@ -880,14 +880,17 @@ void ServerInterface::signalClientsToRecieveData(std::map<PLATFORM_SOCKET,bool>
if(Socket::isSocketValid(&clientSocket)) {
socketTriggered = socketTriggeredList[clientSocket];
}
else if(this->getGameHasBeenInitiated() == true &&
this->getAllowInGameConnections() == true) {
socketTriggeredList[clientSocket] = true;
socketTriggered = socketTriggeredList[clientSocket];
}
//else if(this->getGameHasBeenInitiated() == true &&
// this->getAllowInGameConnections() == true) {
//socketTriggeredList[clientSocket] = true;
//socketTriggered = socketTriggeredList[clientSocket];
//}
}
ConnectionSlotEvent &event = eventList[i];
mapSlotSignalledList[i] = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event);
bool socketSignalled = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event);
if(connectionSlot != NULL && socketTriggered == true) {
mapSlotSignalledList[i] = socketSignalled;
}
}
}
}
@ -896,6 +899,8 @@ void ServerInterface::checkForCompletedClients(std::map<int,bool> & mapSlotSigna
std::vector <string> &errorMsgList,
std::map<int,ConnectionSlotEvent> &eventList) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
const bool newThreadManager = Config::getInstance().getBool("EnableNewThreadManager","false");
if(newThreadManager == true) {
@ -933,6 +938,8 @@ void ServerInterface::checkForCompletedClients(std::map<int,bool> & mapSlotSigna
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
time_t waitForThreadElapsed = time(NULL);
std::map<int,bool> slotsCompleted;
for(bool threadsDone = false;
@ -989,6 +996,7 @@ void ServerInterface::checkForCompletedClients(std::map<int,bool> & mapSlotSigna
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerInterface::checkForLaggingClients(std::map<int,bool> &mapSlotSignalledList,
@ -1336,10 +1344,10 @@ void ServerInterface::update() {
std::map<int,ConnectionSlotEvent> eventList;
bool hasData = Socket::hasDataToRead(socketTriggeredList);
if(this->getGameHasBeenInitiated() == true &&
this->getAllowInGameConnections() == true) {
//if(this->getGameHasBeenInitiated() == true &&
// this->getAllowInGameConnections() == true) {
//printf("Checking for new client connections socketTriggeredList.size(): %d hasData: %d\n",socketTriggeredList.size(),hasData);
}
//}
if(hasData) if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] hasData == true\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
@ -1354,35 +1362,43 @@ 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",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
// Step #2 check all connection slot worker threads for completed status
checkForCompletedClients(mapSlotSignalledList,errorMsgList, eventList);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #3\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(gameHasBeenInitiated == false || hasData == true) {
// Step #2 check all connection slot worker threads for completed status
checkForCompletedClients(mapSlotSignalledList,errorMsgList, eventList);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #3\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #3 check clients for any lagging scenarios and try to deal with them
checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #4\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #3 check clients for any lagging scenarios and try to deal with them
checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #4\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #4 dispatch network commands to the pending list so that they are done in proper order
executeNetworkCommandsFromClients();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #5\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #4 dispatch network commands to the pending list so that they are done in proper order
executeNetworkCommandsFromClients();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #5\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #5 dispatch pending chat messages
dispatchPendingChatMessages(errorMsgList);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #5 dispatch pending chat messages
dispatchPendingChatMessages(errorMsgList);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
dispatchPendingMarkCellMessages(errorMsgList);
dispatchPendingUnMarkCellMessages(errorMsgList);
dispatchPendingMarkCellMessages(errorMsgList);
dispatchPendingUnMarkCellMessages(errorMsgList);
dispatchPendingHighlightCellMessages(errorMsgList);
dispatchPendingHighlightCellMessages(errorMsgList);
}
else if(gameHasBeenInitiated == true &&
difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_GRACE_PERIOD) {
//printf("Skip network data process because hasData == false\n");
std::map<int,bool> mapSlotSignalledList;
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",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
}
@ -1390,9 +1406,7 @@ void ServerInterface::update() {
difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_GRACE_PERIOD) {
//printf("\nServerInterface::update -- E1\n");
//std::map<int,ConnectionSlotEvent> eventList;
std::map<int,bool> mapSlotSignalledList;
checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList);
}
@ -2155,27 +2169,29 @@ void ServerInterface::checkListenerSlots() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
for(int i= 0; i < GameConstants::maxPlayers; ++i) {
int factionIndex = gameSettings.getFactionIndexForStartLocation(i);
MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i));
ConnectionSlot *connectionSlot= slots[i];
// Open slots for joining in progress game
if(connectionSlot == NULL &&
gameSettings.getFactionControl(factionIndex) != ctClosed &&
if(gameSettings.getFactionControl(factionIndex) != ctClosed &&
gameSettings.getFactionControl(factionIndex) != ctHuman) {
printf("Opening slot for in game connections, slot: %d, factionindex: %d name: %s\n",i,factionIndex,gameSettings.getFactionTypeName(factionIndex).c_str());
addSlot(i);
connectionSlot = slots[i];
if(useInGameBlockingClientSockets == true) {
connectionSlot->getSocket()->setBlock(true);
MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i));
ConnectionSlot *connectionSlot= slots[i];
// Open slots for joining in progress game
if(connectionSlot == NULL) {
printf("Opening slot for in game connections, slot: %d, factionindex: %d name: %s\n",i,factionIndex,gameSettings.getFactionTypeName(factionIndex).c_str());
addSlot(i);
connectionSlot = slots[i];
if(useInGameBlockingClientSockets == true) {
connectionSlot->getSocket()->setBlock(true);
}
connectionSlot->setCanAcceptConnections(true);
}
else if(connectionSlot != NULL &&
connectionSlot->getCanAcceptConnections() == false &&
connectionSlot->isConnected() == false) {
printf("Removing slot for in game connections, slot: %d, factionindex: %d name: %s\n",i,factionIndex,gameSettings.getFactionTypeName(factionIndex).c_str());
this->removeSlot(i);
}
connectionSlot->setCanAcceptConnections(true);
}
else if(connectionSlot != NULL &&
connectionSlot->getCanAcceptConnections() == false &&
connectionSlot->isConnected() == false &&
gameSettings.getFactionControl(factionIndex) != ctClosed &&
gameSettings.getFactionControl(factionIndex) != ctHuman) {
this->removeSlot(i);
}
}
}

View File

@ -980,7 +980,7 @@ bool Socket::hasDataToRead(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList)
{
bool bResult = false;
if(socketTriggeredList.size() > 0)
if(socketTriggeredList.empty() == false)
{
/* Watch stdin (fd 0) to see when it has input. */
fd_set rfds;
@ -1545,12 +1545,14 @@ int Socket::peek(void *data, int dataSize,bool mustGetData,int *pLastSocketError
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 SOCKET appears to be invalid [%d]\n",__FILE__,__FUNCTION__,__LINE__,sock);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 SOCKET appears to be invalid [%d] lastSocketError [%d] err [%d] mustGetData [%d]\n",__FILE__,__FUNCTION__,__LINE__,sock,lastSocketError,err,mustGetData);
}
//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(err <= 0) {
int iErr = lastSocketError;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTING SOCKET for socket [%d], err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,socket,err,getLastSocketErrorFormattedText(&iErr).c_str());
//printf("Peek #3 err = %d\n",err);
//lastSocketError = getLastSocketError();
if(mustGetData == true || lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) {