bool RemoveFile(const OJString &filename) { if (IsFileExist(filename)) { fs::path fullpath(filename); sys::error_code err; bool res = fs::remove(fullpath, err); if (!(sys::errc::success == err)) { ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); OJString msg(GetOJString("[filetool] - IMUST::RemoveFile - remove failed: ")); msg += filename; msg += GetOJString(" - "); msg += String2OJString(err.message()); logger->logError(msg); return false; } return res; } return true; }
bool MakeDir(const OJString &path) { if (!IsDirExist(path)) { fs::path fullpath(path); sys::error_code err; bool res = fs::create_directory(fullpath, err); if (!(sys::errc::success == err)) { ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); OJString msg(GetOJString("[filetool] - IMUST::MakeDir - make dir failed: ")); msg += path; msg += GetOJString(" - "); msg += String2OJString(err.message()); logger->logError(msg); return false; } return res; } return true; }
bool WindowsProcessInOut::createOutputFile() { SAFE_CLOSE_HANDLE_AND_RESET(outputFileHandle_); if (outputFileName_.empty())//如果文件名为空,表示不需要此句柄 return true; SECURITY_ATTRIBUTES saAttr = {0}; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; outputFileHandle_ = CreateFileW(outputFileName_.c_str(), GENERIC_WRITE, FILE_SHARE_READ, &saAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == outputFileHandle_) { ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); OJString msg(GetOJString("[process] - createOutputFile - can't create output file: ")); msg += outputFileName_; logger->logError(msg); outputFileHandle_ = NULL; } return outputFileHandle_ != NULL; }
bool DBManager::run() { assert(sqlDriver_->valid() && "[DBManager]sql driver not valid!"); ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); if(!readTasks()) { logger->logError(GetOJString("[DBManager]read task faild!") + sqlDriver_->getErrorString()); return false; } if(!writeFinishedTask()) { logger->logError(GetOJString("[DBManager]write task faild!") + sqlDriver_->getErrorString()); return false; } return true; }
void JudgeThread::operator()() { ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); OJString infoBuffer; FormatString(infoBuffer, OJStr("work/%d"), id_); FileTool::MakeDir(infoBuffer); FormatString(infoBuffer, OJStr("[JudgeThread][%d]start..."), id_); logger->logTrace(infoBuffer); while (!g_sigExit) { IMUST::TaskPtr pTask; //从任务队列取任务 workingTaskMgr_->lock(); if(workingTaskMgr_->hasTask()) { pTask = workingTaskMgr_->popTask(); } workingTaskMgr_->unlock(); if(!pTask)//没有任务 { OJSleep(1000); continue; } pTask->init(id_); if(!pTask->run()) { FormatString(infoBuffer, OJStr("[JudgeThread][%d]System Error!Judge thread will exit!"), id_); logger->logError(infoBuffer); break; } //添加到完成队列 finisheTaskMgr_->lock(); finisheTaskMgr_->addTask(pTask); finisheTaskMgr_->unlock(); OJSleep(10);//防止线程过度繁忙 } FormatString(infoBuffer, OJStr("[JudgeThread][%d]end."), id_); logger->logTrace(infoBuffer); }
bool JudgeTask::excute() { ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); logger->logTrace(OJStr("[JudgeTask] start excute...")); OJString infoBuffer; if(!FileTool::IsFileExist(exeFile_)) { FormatString(infoBuffer, OJStr("[JudgeTask] not found exe file! %s."), exeFile_); logger->logError(infoBuffer); output_.Result = AppConfig::JudgeCode::SystemError; return false; } ExcuterPtr excuter = ExcuterFactory::create(Input.Language); excuter->run(exeFile_, answerInputFile_, userOutputFile_, Input.LimitTime, Input.LimitMemory); if(excuter->isAccept()) { output_.Result = AppConfig::JudgeCode::Accept; } else if(excuter->isSystemError()) { output_.Result = AppConfig::JudgeCode::SystemError; } else if(excuter->isOutputOutOfLimited()) { output_.Result = AppConfig::JudgeCode::OutputLimited; } else if(excuter->isTimeOutOfLimited()) { output_.Result = AppConfig::JudgeCode::TimeLimitExceed; } else if(excuter->isMemoryOutOfLimited()) { output_.Result = AppConfig::JudgeCode::MemoryLimitExceed; } else if(excuter->isRuntimeError()) { output_.Result = AppConfig::JudgeCode::RuntimeError; } output_.RunTime = excuter->getRunTime(); output_.RunMemory = excuter->getRunMemory(); return excuter->isAccept(); }
bool InitAppConfig() { #define READ_APP_CONFIG(fun, tag, value) \ if(!root->fun(OJStr(tag), value)) \ { \ logger->logError(OJStr("[config] - IMUST::AppConfig::InitAppConfig: read tag faild! ")##OJStr(tag)); \ return false; \ } ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); logger->logTrace(GetOJString("[config] - IMUST::AppConfig::InitAppConfig")); XmlPtr root = XmlFactory::getXml(GetOJString("RapidXml")); if(!root->load(OJStr("config.xml"))) { logger->logError(OJStr("[config] - load config file faild! ")); return false; } root = root->read(OJStr("AppConfig")); if(!root) { logger->logError(OJStr("[config] - read tag 'AppConfig' faild! ")); return false; } READ_APP_CONFIG(readInt32, "CpuInfo/NumberOfCore", CpuInfo::NumberOfCore); READ_APP_CONFIG(readString, "MySql/Ip", MySql::Ip); READ_APP_CONFIG(readInt32, "MySql/Port", MySql::Port); READ_APP_CONFIG(readString, "MySql/User", MySql::User); READ_APP_CONFIG(readString, "MySql/Password", MySql::Password); READ_APP_CONFIG(readString, "MySql/DBName", MySql::DBName); READ_APP_CONFIG(readBool, "Compiler/HasMsC", Compiler::HasMsC); READ_APP_CONFIG(readBool, "Compiler/HasMsCxx", Compiler::HasMsCxx); READ_APP_CONFIG(readBool, "Compiler/HasGcc", Compiler::HasGcc); READ_APP_CONFIG(readBool, "Compiler/HasGxx", Compiler::HasGxx); READ_APP_CONFIG(readBool, "Compiler/HasPascal", Compiler::HasPascal); READ_APP_CONFIG(readBool, "Compiler/HasJava", Compiler::HasJava); READ_APP_CONFIG(readBool, "Compiler/HasCs", Compiler::HasCs); READ_APP_CONFIG(readBool, "Compiler/HasPython", Compiler::HasPython); READ_APP_CONFIG(readInt32, "JudgeCode/Pending", JudgeCode::Pending); READ_APP_CONFIG(readInt32, "JudgeCode/Rejudge", JudgeCode::Rejudge); READ_APP_CONFIG(readInt32, "JudgeCode/Compiling", JudgeCode::Compiling); READ_APP_CONFIG(readInt32, "JudgeCode/Accept", JudgeCode::Accept); READ_APP_CONFIG(readInt32, "JudgeCode/PresentError", JudgeCode::PresentError); READ_APP_CONFIG(readInt32, "JudgeCode/WrongAnswer", JudgeCode::WrongAnswer); READ_APP_CONFIG(readInt32, "JudgeCode/TimeLimitExceed", JudgeCode::TimeLimitExceed); READ_APP_CONFIG(readInt32, "JudgeCode/MemoryLimitExceed", JudgeCode::MemoryLimitExceed); READ_APP_CONFIG(readInt32, "JudgeCode/OutputLimited", JudgeCode::OutputLimited); READ_APP_CONFIG(readInt32, "JudgeCode/RuntimeError", JudgeCode::RuntimeError); READ_APP_CONFIG(readInt32, "JudgeCode/CompileError", JudgeCode::CompileError); READ_APP_CONFIG(readInt32, "JudgeCode/CompileTimeError", JudgeCode::CompileTimeError); READ_APP_CONFIG(readInt32, "JudgeCode/CompileOK", JudgeCode::CompileOK); READ_APP_CONFIG(readInt32, "JudgeCode/SystemError", JudgeCode::SystemError); READ_APP_CONFIG(readInt32, "JudgeCode/UnknownError", JudgeCode::UnknownError); READ_APP_CONFIG(readString, "Path/TestDataPath", Path::TestDataPath); READ_APP_CONFIG(readBool, "WindowsUser/Enable", WindowsUser::Enable); READ_APP_CONFIG(readString, "WindowsUser/Name", WindowsUser::Name); READ_APP_CONFIG(readString, "WindowsUser/Password", WindowsUser::Password); #undef READ_APP_CONFIG return true; }
OJInt32_t WindowsProcess::create(const OJString &cmd, const OJInt32_t timeLimit, const OJInt32_t memoryLimit, bool startImmediately) { ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); { logger->logTraceX(OJStr("[process] - create - CMD='%s' T=%dms, M=%dbytes"), cmd.c_str(), timeLimit, memoryLimit); } if(!createInputFile()) { logger->logError(OJStr("[process] - create - can't creat inputFile")); return -1; } if(!createOutputFile()) { logger->logError(OJStr("[process] - create - can't creat outputFile")); return -1; } if (!jobHandle_.create(useToExcuter_)) { logger->logError(OJStr("[process] - create - can't creat job")); return -1; } if (!jobHandle_.setLimit(timeLimit, memoryLimit)) { logger->logError(OJStr("[process] - create - set job limit failed")); return -1; } OJChar_t cmdline[1024]; wcscpy_s(cmdline, cmd.c_str()); STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); ZeroMemory(&pi, sizeof(pi)); si.cb = sizeof(si); si.wShowWindow = SW_HIDE;//隐藏窗口 si.hStdInput = inputFileHandle_; si.hStdOutput = si.hStdError = outputFileHandle_; si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; //使用handel项和wShowWindow项。 DWORD createFlag = CREATE_SUSPENDED | CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB; bool res = createProcess( NULL, // No module name (use command line). cmdline, // Command line. NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. TRUE, // Set handle inheritance to ... createFlag, // creation flags. NULL, // Use parent 's environment block. NULL, // Use parent 's starting directory. &si, // Pointer to STARTUPINFO structure. &pi); // Pointer to PROCESS_INFORMAT\ION structure. if (!res) { logger->logErrorX(OJStr("[process] - can't creat process. last error: %u"), GetLastError()); return -1; } alive_ = true; processHandle_ = pi.hProcess; threadHandle_ = pi.hThread; if(startImmediately) return start(); return 1; }
void JudgeTask::doRun() { ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); OJString infoBuffer; FormatString(infoBuffer, OJStr("[JudgeTask] task %d"), Input.SolutionID); logger->logInfo(infoBuffer); //编译 if(!compile()) { return; } //搜索测试数据 OJString path; FormatString(path, OJStr("%s/%d"), AppConfig::Path::TestDataPath.c_str(), Input.ProblemID); DebugMessage(OJStr("[JudgeTask] %d search path: %s"), Input.SolutionID, path.c_str()); //TODO: 根据是否specialJudge,决定搜索.out还是.in文件。 FileTool::FileNameList fileList; FileTool::GetSpecificExtFiles(fileList, path, OJStr(".out"), true); OJUInt32_t testCount = fileList.size(); if(testCount <= 0)//没有测试数据 { output_.Result = AppConfig::JudgeCode::SystemError; FormatString(infoBuffer, OJStr("[JudgeTask] not found test data for solution %d problem %d."), Input.SolutionID, Input.ProblemID); logger->logError(infoBuffer); return; } //测试多组数据 OJUInt32_t accepted = 0; for(OJUInt32_t i=0; i<testCount; ++i) { answerOutputFile_ = fileList[i]; answerInputFile_ = FileTool::RemoveFileExt(answerOutputFile_); answerInputFile_ += OJStr(".in"); DebugMessage(OJStr("[JudgeTask] %d input file: %s"), Input.SolutionID, answerInputFile_.c_str()); DebugMessage(OJStr("[JudgeTask] %d output file: %s"), Input.SolutionID, answerOutputFile_.c_str()); if(!safeRemoveFile(userOutputFile_)) { output_.Result = AppConfig::JudgeCode::SystemError; break; } if(!excute()) { break; } if(!match()) { break; } ++accepted; } output_.PassRate = float(accepted)/testCount; }