示例#1
0
//Holds game logic together
int Game::OnStart() {
	//Initialize the game
	if (OnInit() == false) {
        return -1;
    }

	SDL_Event Event;

	//While game is running 
	while (running) {
		while (gameType == 0 && running) {
			while (SDL_PollEvent(&Event)) {
				OnEvent(&Event);
			}
			//meanwhile show menu
			showMenu();
		}
		while (SDL_PollEvent(&Event)) {
			//Handle user input
			OnEvent(&Event);
		}
		OnLoop();
		OnRender();
	}
 
    OnCleanUp();
 
    return 0;
};
示例#2
0
void Thread::Create()
{
	prctl(PR_SET_NAME, name_.c_str());
	OnInit();
	OnLoop();
	OnStop();
}
示例#3
0
int CApp::OnExecute(){

    if (OnInit() == false){
        return -1;
    }

    SDL_Event Event;

    while(Running){

        while(SDL_PollEvent(&Event)){

            OnEvent(&Event);

        }

        OnLoop();
        OnRender();

    }


    OnCleanup();

    return 0;
}
示例#4
0
//------------------------------------------------------------------------------
int CApp::OnExecute() {
    if(OnInit() == false) {
        return -1;
    }

    SDL_Event Event;

    while(Running) {
        if(AIenabled && CurrentPlayer && GameState == GAME_STATE_RUNNING)
        {
            GameClick(AIMove());
        }

        while(SDL_PollEvent(&Event)) {
            OnEvent(&Event);
        }

        OnLoop();
        OnRender();
    }

    OnCleanup();

    return 0;
}
示例#5
0
文件: app.cpp 项目: davidsiaw/kubus
int App::OnExecute()
{
    if(OnInit() == false)
    {
        return -1;
    }

	controller->Initialize();

    SDL_Event Event;
    while(running)
    {
        Scene* scene = controller->GetCurrentScene();
		if (scene == NULL)
		{
			break;
		}

        if(SDL_PollEvent(&Event))
        {
            OnEvent(scene, &Event);
        }

        OnLoop(scene);
        OnRender(scene);
    }

    OnCleanup();

    return 0;
}
示例#6
0
int CInstance_Menu_MJ::OnExecute()
{
  if(!Init())
  {
    cerr << ERROR_STR_INIT << " MENU_MJ" << endl;
    return ERROR_CODE_GENERAL;
  }

  int frame = 0;
  CTemporizador fps;

  int salida = I_SALIDA;

  while(i_running)
  {
    fps.empezar();
    while(SDL_PollEvent(&event))
    {
      OnEvent(salida);
    }
    OnLoop(salida);
    OnRender();

    frame++;
    if((fps.getTicks() < (1000 / FRAMES_PER_SECOND)))
      SDL_Delay((1000 / FRAMES_PER_SECOND ) - fps.getTicks());
  }

  Close();

  return salida;
}
示例#7
0
int Application::OnExecute() {
	std::string finalMessage;
	
	try {
		Timer fpsManager;

		OnInit();
		
		while (isRunning) {
			fpsManager.Start();

			while (SDL_PollEvent(&eventHandled)) {
				OnEvent(&eventHandled);
			}
			
			OnLoop();
			OnRender();

			fpsManager.FrameRate();
		}
		
		OnCleanUp();
	} catch (const SDLException& sdlException) {
		finalMessage.append("<SDL Error>");
		finalMessage.append(" => ");
		finalMessage.append(sdlException.WhatHappens());

		Logger::WriteMessageInLogFile(finalMessage.c_str());
		return -1;
	} catch (const TTFException& ttfException) {
		finalMessage.append("<TTF Error>");
		finalMessage.append(" => ");
		finalMessage.append(ttfException.WhatHappens());

		Logger::WriteMessageInLogFile(finalMessage.c_str());
		return -1;
	} catch (const MixerException& mixerException) {
		finalMessage.append("<Mixer Error>");
		finalMessage.append(" => ");
		finalMessage.append(mixerException.WhatHappens());

		Logger::WriteMessageInLogFile(finalMessage.c_str());
		return -1;
	} catch (const GenericException& exception) {
		Logger::WriteMessageInLogFile(exception.WhatHappens());
		return -1;
	}
	
	return 0;
}
示例#8
0
void KGWin32App::Run()
{
    m_bLoop = TRUE;

    SetTimerFrame(1000);

    while (m_bLoop) 
    {
        DWORD dwResult = MsgWaitForMultipleObjectsEx(EVENT_TOTAL, m_Events, INFINITE, QS_ALLEVENTS, 0);
        switch (dwResult - WAIT_OBJECT_0) 
        {
        case EVENT_TIMER:
            if (m_bEnabled)
                m_bLoop = OnLoop();
            break;
        case EVENT_RENDER:
            OnPaint();
            break;
        case EVENT_TOTAL: 
            {
                MSG msg;
                while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                {
                    if (msg.message == WM_QUIT) 
                    {
                        OnMsgProc(WM_QUIT, 0, 0);
                        m_bLoop = FALSE;
                    }
                    else
                    {
                        TranslateMessage(&msg);

                        if (m_hwndEmbedWebPage != NULL && m_hWnd != msg.hwnd && 
                            msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)
                        {
                            SendMessage(m_hwndEmbedWebPage, msg.message, msg.wParam, msg.lParam);
                        }

                        DispatchMessage(&msg);
                    }
                }
                break;
            }
        }
    }

    Exit();
}
示例#9
0
//Main Loop for the whole application
int MainApp::OnExecute()
{
        //Did we initilize correcrlt
		if(OnInit() == false)
		{
			return -1;
		}

		SDL_Event Event; //holding for events from SDL

        //While we are running
		while (Running)
		{
		    //check we did not hit our max millisecond Hz
		     if(!MainRenderTarget.FrameRateControl.TargetRateHit())
             {

                //Get latest events
                while (SDL_PollEvent(&Event))
                {
                    //Update Events
                    OnEvent(&Event);
                }


                //Update game logic
                OnLoop();

                //Draw
                OnRender();

			//MainRenderTarget.Render();
            }
            else
			{
			    //if we reached our target Hz sleep for one millisecond
				Sleep(1);
			}


		}

        //clean everything up
		OnCleanup();

		return 0;
}
示例#10
0
//--------------------------------------------------------------------------------
bool Game::Loop()
{

	assert(m_pkRenderer);
	m_pkRenderer->StartFrame();

	m_pkRenderer->Draw();

	if (OnLoop()){
		return true;
	}

	m_pkRenderer->EndFrame();
	
	return false;

}
示例#11
0
	int Gravity::OnExecute()  {
		if (OnInit() == false) {
			cerr << "Failed to initialize." << endl;
			return -1;
		}

		SDL_Event Event;
		while (isRunning) {
			while (SDL_PollEvent(&Event)) {
				OnEvent(&Event);
			}

			OnLoop();
			OnRender();
		}

		OnCleanup();
		return 0;
	}
示例#12
0
int AscentApp::OnExecute() {
	if (!OnInit())
		return -1;

	SDL_Event event;

	while (running) {
		Uint32 lstart = SDL_GetTicks();
		while (SDL_PollEvent(&event))
			OnEvent(&event);
		OnLoop();
		OnRender();
		Uint32 lend = SDL_GetTicks();
		if ((lend - lstart) < LOOP_TIME)
			SDL_Delay(LOOP_TIME - (lend - lstart));
	}

	OnCleanup();
	return 0;
}
示例#13
0
//------------------------------------------------------------------------------
int CMenu::OnExecute() {
	Running = 1;
    if(OnInit() == false) {
        return -1;
    }

    SDL_Event Event;
    while(Running==1) {
        while(SDL_PollEvent(&Event)) {
            OnEvent(&Event);
        }

        OnLoop();
        OnRender();
    }

    OnCleanup();

    return Running;
}
示例#14
0
void CMQTTClient::Run (void)
{
	while (1)
	{
		if (m_ConnectStatus != MQTTStatusDisconnected)
		{
			Receiver ();
			Sender ();
			KeepAliveHandler ();

			CScheduler::Get ()->MsSleep (50);
		}
		else
		{
			CScheduler::Get ()->MsSleep (200);
		}

		OnLoop ();
	}
}
示例#15
0
int Field::OnExecute()
{
	if(OnInit() == false)
		return -1;

	SDL_Event 	Event;

	int 		ticks, 
				delta_ticks, 
				delay_time;

	bool 		opponent_move = true,
				ball_move_x = true,
				ball_move_y = true;


	while(Running)
	{
		ticks = SDL_GetTicks();

		while(SDL_PollEvent(&Event))
			OnEvent(&Event);

		OnLoop(&opponent_move, &ball_move_x, &ball_move_y);

		OnRender();

		
		delta_ticks = SDL_GetTicks() - ticks;
		delay_time = (100/6) - delta_ticks;

		if(delay_time > 0)
		{
			SDL_Delay(delay_time);
		}
	}

	OnCleanup();

	return 0;
}
示例#16
0
int Game::OnExecute()
{
	if (!OnInit()) {
		return -1;
	}
	Running = true;
	Paused = false;

	SDL_Event Event;
	
	while(Running) {
		while(SDL_PollEvent(&Event)) {
			OnEvent(&Event);
		}
		if (!Paused) {
			OnLoop();
			OnRender();
		}
	}

	return 0;
}
int Game::OnExecute(char* argv[])
{
	if (OnInit() == false)
		return -1;

	printf("Go Engine Go!\n\n");

	SDL_Event event;

	while (StillBreathing)
	{
		while (SDL_PollEvent(&event))
			OnEvent(&event);

		OnLoop();
		OnRender();
	}

	OnCleanup();

	return 0;
}
示例#18
0
int GFX::OnExecute()
{
    if(OnInit() == false)
        return -1;

    while (m_app->IsOpened())
    {
        sf::Event e;
        while (m_app->GetEvent(e))
            OnEvent(e);

        OnLoop();
        OnRender();

        while (m_app->GetEvent(e))
            OnEvent(e);
    }

    OnCleanup();

    return 1;
}
示例#19
0
		int Frontend::OnExecute()
		{
			if (OnInit() == false) return -1;

			SDL_Event event;

			std::cout << "Execution started.\n";
			while (Running == true)
			{
				while (SDL_PollEvent(&event))
				{
					OnEvent(&event);
				}

				OnLoop();
				OnRender();
			}
		
			OnCleanUp();

			return 0;
		}
示例#20
0
int game::OnExecute() {
    if(OnInit() == false) {
        return -1;
    }
    if(LoadContent() == false)
    {
        return -1;
    }


    while(Running) {
        while(SDL_PollEvent(&Event)) {
            OnEvent(&Event);
        }

        OnLoop();
        OnRender();
    }

    OnCleanup();

    return 0;
}
示例#21
0
int CApp::Execute() {
    if (!OnInit()) return -1;

    //jokela::Timer timer(FPS);

    SDL_Event Event;

    //timer.Start();

    while (Running) {
        while (SDL_PollEvent(&Event)) {
            OnEvent(&Event);
        }

        if (true/*timer.ReadyForNextFrame()*/) {
            OnLoop();
            OnRender();
        }
    }

    OnCleanup();

    return 0;
}
DWORD WINAPI STREAMSRVTCPLoopCliThrProc(LPVOID lpParam)	{
#else
void* STREAMSRVTCPLoopCliThrProc(void* lpParam)	{
#endif

	int EndThread = 0;
	struct CLITHRPARAMS	{
		SRVTCP* pSRVTCP; 
		SOCKET ClientSocket;
		int (*OnLoop)(SRVTCP*, SOCKET, void*);
		void* OnLoopParams;
		int (*OnNewCli)(SRVTCP*, SOCKET, void*);
		void* OnNewCliParams;
	};
	struct CLITHRPARAMS* pParams = (struct CLITHRPARAMS*)lpParam;

	// Copy of the thread parameters in local variables
	SRVTCP* pSRVTCP = pParams->pSRVTCP;
	SOCKET ClientSocket = pParams->ClientSocket;
	int (*OnLoop)(SRVTCP*, SOCKET, void*) = pParams->OnLoop;
	void* OnLoopParams = pParams->OnLoopParams;
	int (*OnNewCli)(SRVTCP*, SOCKET, void*) = pParams->OnNewCli;
	void* OnNewCliParams = pParams->OnNewCliParams;


	// Updates the number of client connections
	EnterCriticalSection(&pSRVTCP->CSNbConnections);
	pSRVTCP->NbConnections++;
	LeaveCriticalSection(&pSRVTCP->CSNbConnections);

	// For the newly accepted client socket, does user-defined actions
	if (OnNewCli(pSRVTCP, ClientSocket, OnNewCliParams) != EXIT_SUCCESS)	{ // On error, disconnects the client

		ShutdownTCP(&ClientSocket, SD_BOTH);
		DisconnectTCP(&ClientSocket);
		// Updates the number of client connections
		EnterCriticalSection(&pSRVTCP->CSNbConnections);
		pSRVTCP->NbConnections--;
		LeaveCriticalSection(&pSRVTCP->CSNbConnections);
		return 0; 
	}

	// Main loop
	do
	{
		// Does user-defined actions
		if (OnLoop(pSRVTCP, ClientSocket, OnLoopParams) != EXIT_SUCCESS)	{ // On error, disconnects the client

			ShutdownTCP(&ClientSocket, SD_BOTH);
			DisconnectTCP(&ClientSocket);
			// Updates the number of client connections
			EnterCriticalSection(&pSRVTCP->CSNbConnections);
			pSRVTCP->NbConnections--;
			LeaveCriticalSection(&pSRVTCP->CSNbConnections);
			return 0; 
		}

		mSleep(100);
		memcpy_ts(&EndThread, &pSRVTCP->EndThread, sizeof(int), &pSRVTCP->CSEndThread); // Thread-safe copy
	} while (!EndThread);

	ShutdownTCP(&ClientSocket, SD_BOTH);
	DisconnectTCP(&ClientSocket);
	// Updates the number of client connections
	EnterCriticalSection(&pSRVTCP->CSNbConnections);
	pSRVTCP->NbConnections--;
	LeaveCriticalSection(&pSRVTCP->CSNbConnections);

	return 0; 
} 
示例#23
0
/*
 * Loop循环
 */
int TCPServer_Run(TCPServer* pServer)
{
	// step 1: listen()函数
	int iSocket = TCPServer_Listen(pServer);
	if(iSocket < 0)
	{
		XLOG_ERROR(pServer->pLogger, "Listen() fail: iRet=%d", iSocket);
		return -1;
	}

	// step 2: 主循环
	for(;;)
	{
		// a、处理循环timeout逻辑
		OnLoop();

		// b、等待事件到来
		int iActiveNum = Epoller_WaitEvent(pServer->pEpoller, pServer->iTimeOut);
		if(iActiveNum < 0)
		{
			continue;
		}
		
		// c、处理激活事件
		for(int i=0; i<iActiveNum; i++)
		{
			int iFlag = 0;
			int iReadySock = Epoller_GetReadyFd(pServer->pEpoller, i, &iFlag);
			if(iReadySock > 0)
			{
				// 错误事件处理
				if(iFlag & EVENT_ERROR)
				{
					TCPServer_Exception(iReadySock);
					continue;
				}

				// 读事件处理
				if(iFlag & EVENT_READ)
				{
					if(iReadySock == pServer->iServSocket)
					{
						TCPServer_Accept(pServer);
					}
					else
					{
						TCPServer_Input(pServer, iReadySock);
					}
					continue;
				}
				
				// 写事件处理
				if(iFlag & EVENT_WRITE)
				{
					TCPServer_Output(pServer);
					continue;
				}
			}
		}
	}
}
DWORD WINAPI REQSRVTCPThrProc(LPVOID lpParam)	{
#else
void* REQSRVTCPThrProc(void* lpParam)	{
#endif

	int EndThread = 0;
	struct THRPARAMS	{
		SRVTCP* pSRVTCP; 
		int (*OnLoop)(SRVTCP*, SOCKET, void*);
		void* OnLoopParams;
		int (*OnNewCli)(SRVTCP*, SOCKET, void*);
		void* OnNewCliParams;
		int (*OnCliReq)(SRVTCP*, SOCKET, void*);
		void* OnCliReqParams;
		int TooManyConnectionsAction;
	};
	struct THRPARAMS* pParams = (struct THRPARAMS*)lpParam;
	int NbConnections = 0;

	// Copy of the thread parameters in local variables
	SRVTCP* pSRVTCP = pParams->pSRVTCP;
	int (*OnLoop)(SRVTCP*, SOCKET, void*) = pParams->OnLoop;
	void* OnLoopParams = pParams->OnLoopParams;
	int (*OnNewCli)(SRVTCP*, SOCKET, void*) = pParams->OnNewCli;
	void* OnNewCliParams = pParams->OnNewCliParams;
	int (*OnCliReq)(SRVTCP*, SOCKET, void*) = pParams->OnCliReq;
	void* OnCliReqParams = pParams->OnCliReqParams;
	int TooManyConnectionsAction = pParams->TooManyConnectionsAction;

	fd_set tmpset = {0}; // fd_set modified by select()
	fd_set tmpset1 = {0};
	fd_set tmpset2 = {0};
	SOCKET_DATA* sd = NULL;
	SOCKET_DATA* sd_tmp = NULL;
	struct timeval timeout = {SELECT_SEC_TIMEOUT_SRVTCP, SELECT_USEC_TIMEOUT_SRVTCP}; // Timeout for select()
	SOCKET ClientSocket = INVALID_SOCKET; // New client socket to add to the fd_set and its associated fd_list
	int iResult = SOCKET_ERROR;
	SOCKET_DATA* sd2 = NULL;
	SOCKET_DATA* sd2_tmp = NULL;
	long OldestTime = GetTickCount();


	// Main loop of the server.
	// First, does user-defined actions for every client sockets (for example, sending some data).
	// Then, waits for data to read from the client sockets and does user-defined actions to
	// handle this data.
	// There is an exception when there is available data on the server socket. It is a client that 
	// is requesting a connection. User-defined actions can be done in case of a successful new connection.
	do
	{
		if (OnLoop != NULL)	{ // Fo every client socket, does user-defined actions
			sd = pSRVTCP->sock_list.first->next; // Excludes the server socket which is the first
			while (sd)	{
				// Does user-defined actions
				if (OnLoop(pSRVTCP, sd->sock, OnLoopParams) != EXIT_SUCCESS)	{ // On error, disconnects the client
					ShutdownTCP(&sd->sock, SD_BOTH);
					DisconnectTCP(&sd->sock);
					sd_tmp = sd->next;
					FD_REMOVE(sd, &pSRVTCP->sock_list, &pSRVTCP->sock_set);
					sd = sd_tmp;
					// Update the number of clients currently connected
					NbConnections = pSRVTCP->sock_list.fd_count - 1;
					memcpy_ts(&pSRVTCP->NbConnections, &NbConnections, sizeof(int), &pSRVTCP->CSNbConnections); // Thread-safe copy
					continue; // Without continue we would miss the next element
				}
				sd = sd->next;
			}
		}

		// Copies the fd_set in a temporary variable that may be modified by select()
		// to indicate which sockets are readable
		memcpy(&tmpset, &pSRVTCP->sock_set, sizeof(pSRVTCP->sock_set));

		// Timeout for select()
		timeout.tv_sec = SELECT_SEC_TIMEOUT_SRVTCP; 
		timeout.tv_usec = SELECT_USEC_TIMEOUT_SRVTCP; 

		// Waits for the readability of a socket in the fd_set, with a timeout of 100 ms
		iResult = select(pSRVTCP->sock_list.max_socket+1, &tmpset, NULL, NULL, &timeout);

		if (iResult == SOCKET_ERROR)	{
			// Checks the validity of every socket and disconnects those which are bad
			sd = pSRVTCP->sock_list.first->next; // Excludes the server socket which is the first
			while (sd)	{ 
				// Initialize 2 temporary fd_set which contain only one socket
				FD_ZERO(&tmpset1);FD_ZERO(&tmpset2); 
				FD_SET(sd->sock, &tmpset1);FD_SET(sd->sock, &tmpset2);
				timeout.tv_sec = 0; 
				timeout.tv_usec = 0; 
				if (select((int)sd->sock+1, &tmpset1, &tmpset2, NULL, &timeout) == SOCKET_ERROR)	{ // On error, disconnects the client
					ShutdownTCP(&sd->sock, SD_BOTH);
					DisconnectTCP(&sd->sock);
					sd_tmp = sd->next;
					FD_REMOVE(sd, &pSRVTCP->sock_list, &pSRVTCP->sock_set);
					sd = sd_tmp;
					FD_CLR(sd->sock, &tmpset1);FD_CLR(sd->sock, &tmpset2);
					// Update the number of clients currently connected
					NbConnections = pSRVTCP->sock_list.fd_count - 1;
					memcpy_ts(&pSRVTCP->NbConnections, &NbConnections, sizeof(int), &pSRVTCP->CSNbConnections); // Thread-safe copy
					continue; // Without continue we would miss the next element
				}
				FD_CLR(sd->sock, &tmpset1);FD_CLR(sd->sock, &tmpset2);
				sd = sd->next;
			}
			continue;
		}

		if (iResult == 0)	{ // The timeout on select() occured
			continue;
		}

		// Checks every socket of the fd_list associated with the fd_set
		sd = pSRVTCP->sock_list.first; 
		while(sd)	{

			if (FD_ISSET(sd->sock, &tmpset))	{ // This socket is in tmp_set (modified by select()), so it is readable
				if (sd->sock == pSRVTCP->ListenSocket)	{ // New incoming connection (the server socket should be the first in the fd_list)
					if (
						(AcceptTCP(pSRVTCP->ListenSocket, &ClientSocket) == EXIT_SUCCESS)&&
						(SetSockOptTCP(ClientSocket, 1, 10000) == EXIT_SUCCESS) // Setting timeouts for the client socket
						)	
					{
						// Adds it to the fd_set and its associated fd_list
						if (FD_ADD(ClientSocket, &pSRVTCP->sock_list, &pSRVTCP->sock_set) != EXIT_SUCCESS)	{
							if (TooManyConnectionsAction == REMOVE_UNUSED)	{ // Removes an unused socket (the one that was not used for the longest time)
								sd2 = pSRVTCP->sock_list.first->next; // Excludes the server socket from the search
								OldestTime = sd2->LastUsedTime;
								// Looks for the oldest time
								while (sd2)	{
									OldestTime = min(sd2->LastUsedTime, OldestTime);
									sd2 = sd2->next;
								}
								sd2 = pSRVTCP->sock_list.first->next; // Excludes the server socket from the search
								// Removes the socket corresponding to the oldest time
								while (sd2)	{
									if (sd2->LastUsedTime == OldestTime)	{
										ShutdownTCP(&sd2->sock, SD_BOTH);
										DisconnectTCP(&sd2->sock);
										sd2_tmp = sd2->next;
										FD_REMOVE(sd2, &pSRVTCP->sock_list, &pSRVTCP->sock_set);
										sd2 = sd2_tmp;
										// Update the number of clients currently connected
										NbConnections = pSRVTCP->sock_list.fd_count - 1;
										memcpy_ts(&pSRVTCP->NbConnections, &NbConnections, sizeof(int), &pSRVTCP->CSNbConnections); // Thread-safe copy
										break;
									}
									else	{
										sd2 = sd2->next;
									}
								}
								// Retries to add the client socket
								if (FD_ADD(ClientSocket, &pSRVTCP->sock_list, &pSRVTCP->sock_set) != EXIT_SUCCESS)	{
									// Disconnects immediately the client as it can not be handled
									ShutdownTCP(&ClientSocket, SD_BOTH);
									DisconnectTCP(&ClientSocket);
								}
								else	{ // The new client socket was successfully added
									// Update the number of clients currently connected
									NbConnections = pSRVTCP->sock_list.fd_count - 1;
									memcpy_ts(&pSRVTCP->NbConnections, &NbConnections, sizeof(int), &pSRVTCP->CSNbConnections); // Thread-safe copy
									if (OnNewCli != NULL)	{ // For the newly accepted client socket, does user-defined actions
										if (OnNewCli(pSRVTCP, ClientSocket, OnNewCliParams) != EXIT_SUCCESS)	{ // On error, disconnects the new client
											// Looks for the SOCKET_DATA corresponding to the new client socket
											sd2 = pSRVTCP->sock_list.first->next; // Excludes the server socket from the search
											while (sd2)	{
												if (sd2->sock == ClientSocket)	{
													ShutdownTCP(&sd2->sock, SD_BOTH);
													DisconnectTCP(&sd2->sock);
													sd2_tmp = sd2->next;
													FD_REMOVE(sd2, &pSRVTCP->sock_list, &pSRVTCP->sock_set);
													sd2 = sd2_tmp;
													// Update the number of clients currently connected
													NbConnections = pSRVTCP->sock_list.fd_count - 1;
													memcpy_ts(&pSRVTCP->NbConnections, &NbConnections, sizeof(int), &pSRVTCP->CSNbConnections); // Thread-safe copy
													break;
												}
												else	{
													sd2 = sd2->next;
												}
											}
										}
									}
								}
							}
							else	{
								// Disconnects immediately the client
								ShutdownTCP(&ClientSocket, SD_BOTH);
								DisconnectTCP(&ClientSocket);
							}
						}
						else	{ // The new client socket was successfully added
							// Update the number of clients currently connected
							NbConnections = pSRVTCP->sock_list.fd_count - 1;
							memcpy_ts(&pSRVTCP->NbConnections, &NbConnections, sizeof(int), &pSRVTCP->CSNbConnections); // Thread-safe copy
							if (OnNewCli != NULL)	{ // For the newly accepted client socket, does user-defined actions
								if (OnNewCli(pSRVTCP, ClientSocket, OnNewCliParams) != EXIT_SUCCESS)	{ // On error, disconnects the new client
									// Looks for the SOCKET_DATA corresponding to the new client socket
									sd2 = pSRVTCP->sock_list.first->next; // Excludes the server socket from the search
									while (sd2)	{
										if (sd2->sock == ClientSocket)	{
											ShutdownTCP(&sd2->sock, SD_BOTH);
											DisconnectTCP(&sd2->sock);
											sd2_tmp = sd2->next;
											FD_REMOVE(sd2, &pSRVTCP->sock_list, &pSRVTCP->sock_set);
											sd2 = sd2_tmp;
											// Update the number of clients currently connected
											NbConnections = pSRVTCP->sock_list.fd_count - 1;
											memcpy_ts(&pSRVTCP->NbConnections, &NbConnections, sizeof(int), &pSRVTCP->CSNbConnections); // Thread-safe copy
											break;
										}
										else	{
											sd2 = sd2->next;
										}
									}
								}
							}
						}
					}
				}
				else { // If we are here, the socket is a client and was already accepted before
					sd->LastUsedTime = GetTickCount();
					if (OnCliReq != NULL)	{ // Fo the current client socket, does user-defined actions
						if (OnCliReq(pSRVTCP, sd->sock, OnCliReqParams) != EXIT_SUCCESS)	{ // On error, disconnects the client
							ShutdownTCP(&sd->sock, SD_BOTH);
							DisconnectTCP(&sd->sock);
							sd_tmp = sd->next;
							FD_REMOVE(sd, &pSRVTCP->sock_list, &pSRVTCP->sock_set);
							sd = sd_tmp;
							// Update the number of clients currently connected
							NbConnections = pSRVTCP->sock_list.fd_count - 1;
							memcpy_ts(&pSRVTCP->NbConnections, &NbConnections, sizeof(int), &pSRVTCP->CSNbConnections); // Thread-safe copy
							continue; // Without continue we would miss the next element
						}
					}
				}
			}

			sd = sd->next;
		}
		mSleep(100);
		memcpy_ts(&EndThread, &pSRVTCP->EndThread, sizeof(int), &pSRVTCP->CSEndThread); // Thread-safe copy
	} while (!EndThread);

	return 0; 
}