From 9daf6066a0a00f4682a4047d7504d044306c6084 Mon Sep 17 00:00:00 2001 From: Sam Moore 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 #include +#include +#include +#include +#include + + 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; - + */ } -- 2.20.1