From 9daf6066a0a00f4682a4047d7504d044306c6084 Mon Sep 17 00:00:00 2001
From: Sam Moore <matches@ucc.asn.au>
Date: Sat, 17 Mar 2012 23:18:37 +0800
Subject: [PATCH] [PATCH] Fixed efficiency problem with manager program

I was using threads for timing out messages.
But apparently everyone knows you can just use select(2)
---
 judge/manager/game.cpp    | 19 ++++++++++++-------
 judge/manager/network.cpp | 26 ++++++++++++++++++++++++++
 judge/manager/program.cpp | 35 +++++++++++++++++++++++++++++++++--
 3 files changed, 71 insertions(+), 9 deletions(-)

diff --git a/judge/manager/game.cpp b/judge/manager/game.cpp
index 0e768c5..c1238f0 100644
--- a/judge/manager/game.cpp
+++ b/judge/manager/game.cpp
@@ -208,21 +208,23 @@ void Game::Wait(double wait)
 	if (wait <= 0)
 		return;
 
-	TimerThread timer(wait*1000000); //Wait in seconds
-	timer.Start();
+
+
 
 	#ifdef BUILD_GRAPHICS
+
+
 	if (!graphicsEnabled)
 	{
-		while (!timer.Finished());
-		timer.Stop();
+		usleep(1000000*wait); //Wait in seconds
 		return;
 	}
-	#endif //BUILD_GRAPHICS
 
+	TimerThread timer(wait*1000000); //Wait in seconds
+	timer.Start();
 	while (!timer.Finished())
 	{
-		#ifdef BUILD_GRAPHICS
+	
 		SDL_Event  event;
 		while (SDL_PollEvent(&event))
 		{
@@ -234,9 +236,12 @@ void Game::Wait(double wait)
 					break;
 			}
 		}
-		#endif //BUILD_GRAPHICS
 	}
 	timer.Stop();
+
+	#else
+	usleep(wait*1000000); //Wait in seconds
+	#endif //BUILD_GRAPHICS
 	
 }
 
diff --git a/judge/manager/network.cpp b/judge/manager/network.cpp
index e349fea..74929a7 100644
--- a/judge/manager/network.cpp
+++ b/judge/manager/network.cpp
@@ -150,6 +150,31 @@ bool Network::GetMessage(string & buffer, double timeout)
 		setbuf(file, NULL);
 	}
 
+	struct timeval tv;
+	fd_set readfds;
+	
+	tv.tv_sec = (int)(timeout);
+	tv.tv_usec = (timeout - (double)((int)timeout)) * 1000000;
+
+	FD_ZERO(&readfds);
+	FD_SET(sfd, &readfds);
+
+	select(sfd+1, &readfds, NULL, NULL, &tv);
+
+	if (!FD_ISSET(sfd, &readfds))
+		return false; //Timed out
+	//fprintf(stderr, "Got message!\n");
+	for (char c = fgetc(file); c != '\n' && (int)(c) != EOF; c = fgetc(file))
+	{	
+		//fprintf(stderr, "%c", c);
+		buffer += c;
+	}
+	//fprintf(stderr, "%s\n", buffer.c_str());
+	return true;
+
+
+	/* Old way, which is apparently terrible
+
 	assert(&buffer != NULL);
 	GetterThread getterThread(file, buffer);
 	assert(&(getterThread.buffer) != NULL);
@@ -180,6 +205,7 @@ bool Network::GetMessage(string & buffer, double timeout)
 	if (buffer.size() == 1 && buffer[0] == EOF)
 		return false;
 	return true;
+	*/
 
 
 }
diff --git a/judge/manager/program.cpp b/judge/manager/program.cpp
index 02c9cb8..5ea1591 100644
--- a/judge/manager/program.cpp
+++ b/judge/manager/program.cpp
@@ -10,6 +10,12 @@
 #include <string.h>
 #include <stdio.h>
 
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+
 using namespace std;
 
 
@@ -60,7 +66,7 @@ Program::Program(const char * executablePath) : input(NULL), output(NULL), pid(0
 	char **  arguments = NULL;
         if (args.size() > 0)
 	{
-		arguments = new char*[args.size()+2];
+		arguments = new char*[args.size()];
 		for (unsigned int i=0; i < args.size(); ++i)
 			arguments[i] = args[i];
 	}
@@ -221,6 +227,31 @@ bool Program::GetMessage(string & buffer, double timeout)
 	if (!Running() || timeout == 0)
 		return false;
 
+	struct timeval tv;
+	fd_set readfds;
+	
+	tv.tv_sec = (int)(timeout);
+	tv.tv_usec = (timeout - (double)((int)timeout)) * 1000000;
+	
+	int fd = fileno(input);
+
+	FD_ZERO(&readfds);
+	FD_SET(fd, &readfds);
+
+	select(fd+1, &readfds, NULL, NULL, &tv);
+
+	if (!FD_ISSET(fd, &readfds))
+		return false; //Timed out
+	//fprintf(stderr, "Got message!\n");
+	for (char c = fgetc(input); c != '\n' && (int)(c) != EOF; c = fgetc(input))
+	{	
+		//fprintf(stderr, "%c", c);
+		buffer += c;
+	}
+	//fprintf(stderr, "%s\n", buffer.c_str());
+	return true;
+
+	/* Old way, using threads, which apparently is terrible
 	assert(&buffer != NULL);
 	GetterThread getterThread(input, buffer);
 	assert(&(getterThread.buffer) != NULL);
@@ -251,7 +282,7 @@ bool Program::GetMessage(string & buffer, double timeout)
 	if (buffer.size() == 1 && buffer[0] == EOF)
 		return false;
 	return true;
-
+	*/
 
 }
 
-- 
GitLab