Esempio n. 1
0
bool JudgeTask::match()
{
    ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId);
    logger->logTrace(OJStr("[JudgeTask] start match..."));

    MatcherPtr matcher = MatcherFactory::create(false, OJStr(""));
    matcher->run(answerOutputFile_, userOutputFile_);

    if(matcher->isAccept())
    {
        output_.Result = AppConfig::JudgeCode::Accept;
    }
    else if(matcher->isPresentError())
    {
        output_.Result = AppConfig::JudgeCode::PresentError;
    }
    else if(matcher->isWrongAnswer())
    {
        output_.Result = AppConfig::JudgeCode::WrongAnswer;
    }
    else if(matcher->isSystemError())
    {
        output_.Result = AppConfig::JudgeCode::SystemError;
    }

    return matcher->isAccept();
}
Esempio n. 2
0
namespace CompileArg
{
    const OJInt32_t limitTime = 20000;
    const OJInt32_t limitMemory = 32*1024*1024;

    const OJInt32_t javaLimitTime = 20000;
    const OJInt32_t javaLimitMemory = 128*1024*1024;

    const OJString gcc = OJStr("gcc %s -o %s -O2 -Wall -lm --static -std=c99 -DONLINE_JUDGE");
    const OJString gPlus = OJStr("g++ %s -o %s -O2 -Wall -lm --static -DONLINE_JUDGE");
    const OJString java = OJStr("javac -J-Xms32m -J-Xmx256m %s");
}
Esempio n. 3
0
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);

}
Esempio n. 4
0
void JudgeTask::init(OJInt32_t judgeID)
{
    judgeID_ = judgeID;

    OJString codeExt = getLanguageExt(Input.Language);
    OJString exeExt = getExcuterExt(Input.Language);

    FormatString(codeFile_, OJStr("work/%d/Main.%s"), judgeID_, codeExt.c_str());
    FormatString(exeFile_, OJStr("work/%d/Main.%s"), judgeID_, exeExt.c_str());
    FormatString(compileFile_, OJStr("work/%d/compile.txt"), judgeID_);
    FormatString(userOutputFile_, OJStr("work/%d/output.txt"), judgeID_);

    FileTool::WriteFile(Input.UserCode, codeFile_);
}
Esempio n. 5
0
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();
}
Esempio n. 6
0
bool JudgeTask::compile()
{
    ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId);
    logger->logTrace(OJStr("[JudgeTask] start compile..."));
    
    CompilerPtr compiler = CompilerFactory::create(Input.Language);
    compiler->run(codeFile_, exeFile_, compileFile_);

    if(compiler->isAccept())
    {
        output_.Result = AppConfig::JudgeCode::Accept;
    }
    else if(compiler->isSystemError())
    {
        output_.Result = AppConfig::JudgeCode::SystemError;
    }
    else if(compiler->isCompileError())
    {
        output_.Result = AppConfig::JudgeCode::CompileError;
        
        std::vector<OJChar_t> buffer;
        if(FileTool::ReadFile(buffer, compileFile_) && !buffer.empty())
        {
            output_.CompileError = &buffer[0];
        }
    }

    return compiler->isAccept();
}
Esempio n. 7
0
    bool WindowsUser::createProcess(
        LPCTSTR lpApplicationName,
        LPTSTR lpCommandLine,
        LPSECURITY_ATTRIBUTES lpProcessAttributes,
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        BOOL bInheritHandles,
        DWORD dwCreationFlags,
        LPVOID lpEnvironment,
        LPCTSTR lpCurrentDirectory,
        LPSTARTUPINFO lpStartupInfo,
        LPPROCESS_INFORMATION lpProcessInformation)
    {
        if (!CreateProcessAsUser(tokenHandle_,
            lpApplicationName,
            lpCommandLine,
            lpProcessAttributes,
            lpThreadAttributes,
            bInheritHandles,
            dwCreationFlags,
            lpEnvironment,
            lpCurrentDirectory,
            lpStartupInfo,
            lpProcessInformation))
        {
            OutputErrorMsg(OJStr("CreateProcessAsUser faild"));
            return false;
        }

        return true;
    }
bool WindowsUserProcess::createProcess(
        LPCTSTR lpApplicationName,
        LPTSTR lpCommandLine,
        LPSECURITY_ATTRIBUTES lpProcessAttributes,
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        BOOL bInheritHandles,
        DWORD dwCreationFlags,
        LPVOID lpEnvironment,
        LPCTSTR lpCurrentDirectory,
        LPSTARTUPINFO lpStartupInfo,
        LPPROCESS_INFORMATION lpProcessInformation)
{
    if (!userPtr_)
    {
        throw(std::runtime_error("Invalid windows user !"));
    }

    lpStartupInfo->lpDesktop = OJStr("winsta0\\default");//设置交互桌面

    return userPtr_->createProcess(
        lpApplicationName,
        lpCommandLine,
        lpProcessAttributes,
        lpThreadAttributes,
        bInheritHandles,
        dwCreationFlags,
        lpEnvironment,
        lpCurrentDirectory,
        lpStartupInfo,
        lpProcessInformation);
}
Esempio n. 9
0
namespace CompileArg
{
    const OJInt32_t limitTime = 20000;
    const OJInt32_t limitMemory = 128*1024*1024;

    const OJString cmd = OJStr("gcc %s -o %s -O2 -Wall -lm --static -std=c99 -DONLINE_JUDGE");
}
Esempio n. 10
0
bool SetCurPath(const OJString & path)
{
    bool ret = !!::SetCurrentDirectory(path.c_str());
    
    DEBUG_MSG_VS(OJStr("Current Work Directory: %s"), getCurPath().c_str());
    return ret;
}
Esempio n. 11
0
//获得文件扩展名
OJString getLanguageExt(OJInt32_t language)
{
    if(language == AppConfig::Language::C)
    {
        return OJStr("c");
    }
    else if(language == AppConfig::Language::Cxx)
    {
        return OJStr("cpp");
    }
    else if(language == AppConfig::Language::Java)
    {
        return OJStr("java");
    }

    return OJStr("unknown");
}
Esempio n. 12
0
    bool WindowsUser::setPrivilege(
        LPCTSTR lpszPrivilege,  // name of privilege to enable/disable
        BOOL bEnablePrivilege   // to enable or disable privilege
        ) 
    {
        TOKEN_PRIVILEGES tp;
        LUID luid;

        if ( !LookupPrivilegeValue( 
            NULL,            // lookup privilege on local system
            lpszPrivilege,   // privilege to lookup 
            &luid ) )        // receives LUID of privilege
        {
            OutputErrorMsg(OJStr("LookupPrivilegeValue error ")); 
            return false; 
        }

        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        if (bEnablePrivilege)
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        else
            tp.Privileges[0].Attributes = 0;

        // Enable the privilege or disable all privileges.

        if ( !AdjustTokenPrivileges(
            tokenHandle_, 
            FALSE, 
            &tp, 
            sizeof(TOKEN_PRIVILEGES), 
            (PTOKEN_PRIVILEGES) NULL, 
            (PDWORD) NULL) )
        { 
            OutputErrorMsg(OJStr("AdjustTokenPrivileges failded")); 
            return false; 
        } 

        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        {
            OutputErrorMsg(OJStr("The token does not have the specified privilege. "));
            return false;
        } 

        return true;
    }
Esempio n. 13
0
OJString getExcuterExt(OJInt32_t language)
{
    if(language == AppConfig::Language::C)
    {
        return OJStr("exe");
    }
    else if(language == AppConfig::Language::Cxx)
    {
        return OJStr("exe");
    }
    else if(language == AppConfig::Language::Java)
    {
        return OJStr("class");
    }

    return OJStr("unknown");
}
Esempio n. 14
0
bool CCompiler::run(
    const OJString & codeFile,
    const OJString & exeFile,
    const OJString & compileFile)
{
    OJString cmdLine;
    FormatString(cmdLine, CompileArg::cmd.c_str(), codeFile.c_str(), exeFile.c_str());
    
    IMUST::WindowsProcess wp(OJStr(""), compileFile);
    wp.create(cmdLine, CompileArg::limitTime, CompileArg::limitMemory);
    result_ = wp.getExitCodeEx();

    return isAccept();
}
Esempio n. 15
0
/* 延迟删除文件。
当某子进程尚未完全退出时,他占用的文件再次被打开或删除,都会失败。故作延迟,等待一段时间。
如果文件始终无法删除,将表示该子进程无法退出,这将是一个致命错误,评判线程应当结束。 */
bool safeRemoveFile(const OJString & file)
{
    OJString infoBuffer;

    for(OJInt32_t i=0; i<10; ++i)//尝试删除10次
    {
        if(FileTool::RemoveFile(file))
        {
            return true;
        }
        OJSleep(1000);

        FormatString(infoBuffer, OJStr("safeRemoveFile '%s' faild with %d times. code:%d"), 
            file.c_str(), i+1, GetLastError());
        LoggerFactory::getLogger(LoggerId::AppInitLoggerId)->logError(infoBuffer);
    }

    return false;
}
Esempio n. 16
0
void JavaExcuter::run(
    const OJString & exeFile,
    const OJString & inputFile,
    const OJString & outputFile,
    OJInt32_t limitTime,
    OJInt32_t limitMemory
    )
{
    OJString exePath = FileTool::GetFilePath(exeFile);
    OJString exeFileName = FileTool::GetFileName(exeFile);//get only name

    OJString cmdBuffer;
    FormatString(cmdBuffer, OJStr("java -cp %s %s"), exePath.c_str(), exeFileName.c_str());

    ProcessPtr wp = ProcessFactory::create(ProcessType::Excuter, inputFile, outputFile);
    wp->create(cmdBuffer, limitTime*30, limitMemory*10);
    result_ = wp->getResult();
    runTime_ = wp->getRunTime();
    runMemory_ = wp->getRunMemory();
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
    Thread::~Thread()
    {
        delete threadProxy_;

        WatchTool::WatchCount(OJStr("core/numThread"), NumThread, -1);
    }
Esempio n. 19
0
namespace WindowsUser
{
    bool        Enable      = true;
    OJString    Name        = OJStr("acmer");
    OJString    Password    = OJStr("imustacm");
}
Esempio n. 20
0
    void Thread::start_thread()
    {
        threadProxy_ = new ThreadProxy(fun_.get());

        WatchTool::WatchCount(OJStr("core/numThread"), NumThread, +1);
    }
Esempio n. 21
0
    bool WindowsUser::login(const OJString & userName, const OJString & domain, const OJString & password)
    {
        assert(tokenHandle_==NULL && "wrong call!");

        // Log the client on to the local computer.

        if (!LogonUser(
            userName.c_str(),
            domain.c_str(),
            password.c_str(),
            LOGON32_LOGON_INTERACTIVE,
            LOGON32_PROVIDER_DEFAULT,
            &tokenHandle_) ) 
        {
            tokenHandle_ = NULL;
            OutputErrorMsg(OJStr("LogonUser failed "));
            return false;
        }

        // Save a handle to the caller's current window station.


        HWINSTA hwinstaSave = GetProcessWindowStation();
        if (hwinstaSave == NULL)
        {
            OutputErrorMsg(OJStr("GetProcessWindowStation failed "));
            return false;
        }

        // Get a handle to the interactive window station.

        winstaHandle_ = OpenWindowStation(
            OJStr("winsta0"),               // the interactive window station 
            FALSE,                       // handle is not inheritable
            READ_CONTROL | WRITE_DAC);   // rights to read/write the DACL

        if (winstaHandle_ == NULL) 
        {
            OutputErrorMsg(OJStr("OpenWindowStation failed!"));
            return false;
        }

        // To get the correct default desktop, set the caller's 
        // window station to the interactive window station.

        if (!SetProcessWindowStation(winstaHandle_))
        {
            OutputErrorMsg(OJStr("SetProcessWindowStation 1 failed "));
            return false;
        }

        // Get a handle to the interactive desktop.

        deskHandle_ = OpenDesktop(
            OJStr("default"),     // the interactive window station 
            0,             // no interaction with other desktop processes
            FALSE,         // handle is not inheritable
            READ_CONTROL | // request the rights to read and write the DACL
            WRITE_DAC | 
            DESKTOP_WRITEOBJECTS | 
            DESKTOP_READOBJECTS);

        // Restore the caller's window station.

        if (!SetProcessWindowStation(hwinstaSave)) 
        {
            OutputErrorMsg(OJStr("SetProcessWindowStation 2 failed "));
            return false;
        }

        if (deskHandle_ == NULL)
        {
            OutputErrorMsg(OJStr("OpenDesktop failed"));
            return false;
        }

        // Get the SID for the client's logon session.

        if (!getLogonSID(tokenHandle_, &pSid_)) 
        {
            OutputErrorMsg(OJStr("GetLogonSID failed "));
            return false;
        }

        // Allow logon SID full access to interactive window station.

        if (! addAceToWindowStation(winstaHandle_, pSid_) ) 
        {
            OutputErrorMsg(OJStr("AddAceToWindowStation failed "));
            return false;
        }

        // Allow logon SID full access to interactive desktop.

        if (! addAceToDesktop(deskHandle_, pSid_) ) 
        {
            OutputErrorMsg(OJStr("AddAceToDesktop failed "));
            return false;
        }

        // Impersonate client to ensure access to executable file.

        if (! ImpersonateLoggedOnUser(tokenHandle_) ) 
        {
            OutputErrorMsg(OJStr("ImpersonateLoggedOnUser failed "));
            return false;
        }

        return true;
    }
Esempio n. 22
0
OJInt32_t WindowsProcess::start()
{
    ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId);

    //加到作业中
	if (!jobHandle_.assinProcess(processHandle_))
    {
        logger->logErrorX(OJStr("[process] - can't assign process to job! error:%u"), GetLastError());
        kill();
        return -1;
    }

    //启动线程
    ResumeThread(threadHandle_);
    
    //关闭不使用的句柄。让进程执行完毕后立即退出。
    SAFE_CLOSE_HANDLE_AND_RESET(threadHandle_);
    SAFE_CLOSE_HANDLE_AND_RESET(inputFileHandle_)
    SAFE_CLOSE_HANDLE_AND_RESET(outputFileHandle_)

    result_ = AppConfig::JudgeCode::Accept;

	DWORD ExecuteResult = -1;  
	ULONG completeKey;  
	LPOVERLAPPED processInfo;  
	bool done = false;  
	while(!done)  
	{
        if(!jobHandle_.getState(ExecuteResult, completeKey, processInfo))
        {
            DEBUG_MSG(OJStr("get job State faild!"));
            OJSleep(1);
            continue;
        }

        DWORD dwCode = (DWORD)processInfo;

		switch (ExecuteResult)   
		{  
		case JOB_OBJECT_MSG_NEW_PROCESS:    
            //DEBUG_MSG_VS(OJStr("[WindowsProcess]new process: %u"), dwCode);
			break;

		case JOB_OBJECT_MSG_END_OF_JOB_TIME: //job超时
            DEBUG_MSG(OJStr("[WindowsProcess]Job time limit reached")); 
            result_ = AppConfig::JudgeCode::TimeLimitExceed;  
			done = true;  
			break;

		case JOB_OBJECT_MSG_END_OF_PROCESS_TIME:   //线程超时
			DEBUG_MSG(OJStr("[WindowsProcess]process time limit reached"));
            result_ = AppConfig::JudgeCode::TimeLimitExceed;
			done = true;  
			break;

		case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT:   //进程内存超限
            DEBUG_MSG(OJStr("[WindowsProcess]Process exceeded memory limit"));  
            result_ = AppConfig::JudgeCode::MemoryLimitExceed;  
			done = true;  
			break;

        case JOB_OBJECT_MSG_JOB_MEMORY_LIMIT: //job内存超限
            {
                OJInt32_t mem = getRunMemory();  
                DebugMessage(OJStr("[WindowsProcess]exceeded job memory limit with %dkb"), mem);
                result_ = AppConfig::JudgeCode::MemoryLimitExceed; 
                done = true;  
            }
			break;  

		case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT:  //超出运行的进程数量
            DEBUG_MSG(OJStr("[WindowsProcess]Too many active processes in job"));
            result_ = AppConfig::JudgeCode::RuntimeError;
            done = true;
			break;

		case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:  
            DEBUG_MSG(OJStr("[WindowsProcess]Job contains no active processes")); 
			done = true;  
			break;

		case JOB_OBJECT_MSG_EXIT_PROCESS: //进程退出
            //DEBUG_MSG_VS(OJStr("[WindowsProcess]Process %u exit."), dwCode);
            if(::GetProcessId(processHandle_) == dwCode)
			{
                done = true;
            }
			break;  

		case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: //进程异常结束
            DEBUG_MSG(OJStr("[WindowsProcess]Process terminated abnormally"));
            result_ = AppConfig::JudgeCode::RuntimeError;  
			done = true;  
			break;  

		default:  
            DEBUG_MSG(OJStr("[WindowsProcess]Unknown notification"));
            result_ = AppConfig::JudgeCode::UnknownError; 
			break;
		}
	}  
    
    {
        FILETIME ftime, temp;
        ::GetProcessTimes(processHandle_, &temp, &temp, &temp, &ftime);

        ULARGE_INTEGER time2;
        time2.LowPart = ftime.dwLowDateTime;
        time2.HighPart = ftime.dwHighDateTime;

        runTime_ = time2.QuadPart / 10000;
    }
    
    {
        PROCESS_MEMORY_COUNTERS info;
        ::GetProcessMemoryInfo(processHandle_, &info, sizeof(info));

        runMemory_ = info.PeakPagefileUsage;
    }

    while(!jobHandle_.terminate())//强制关闭作业
    {
        DEBUG_MSG(OJStr("Terminate job faild!"));
        OJSleep(10);
    }

    alive_ = false;//进程结束

    //正常退出。即不是超时等状况。
    if(result_ == AppConfig::JudgeCode::Accept)
    {
        DWORD code = getExitCode();//获取进程返回值,以判断进程是否执行成功。
        if(code != 0)
        {
            result_ = AppConfig::JudgeCode::RuntimeError;
            DEBUG_MSG_VS(OJStr("process exit with code : %u, last error: %u"), 
                code, GetLastError());
        }
    }

    SAFE_CLOSE_HANDLE_AND_RESET(processHandle_);

	return 0;  
}
Esempio n. 23
0
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;
}
Esempio n. 24
0
namespace Statement
{
const OJString TestSql = OJStr("update solution set result = 4");

const OJString SelectSolution2 = OJStr("SELECT solution_id, problem_id, user_id, language ")
    OJStr("FROM `solution` WHERE result=%d or result=%d and solution_id>1904 limit 5");

const OJString SelectProblem1 = OJStr("SELECT time_limit, memory_limit ")
    OJStr("FROM problem WHERE problem_id =%d");

const OJString SelectCode1 = OJStr("SELECT `source` FROM `source_code` WHERE `solution_id`=%d");

const OJString SelectCustomInput1 = OJStr("SELECT `input_text` from custominput WHERE `solution_id`=%d");

const OJString UpdateSolutionCompiling2 = OJStr("UPDATE `solution` SET `result`=%d, `judgetime`=NOW() ")
	OJStr("WHERE `solution_id` = %d");

const OJString UpdateSolutionResult5 = OJStr("UPDATE `solution` SET `result`=%d, ")
    OJStr("`time`=%d, `memory`=%d, `judgetime`=NOW(), `pass_rate`=%f ")
    OJStr("WHERE `solution_id` = %d");

const OJString DeleteCompile1 = OJStr("DELETE FROM `compileinfo` WHERE `solution_id`=%d");
const OJString InsertCompile2 = OJStr("INSERT INTO `compileinfo`(solution_id, error)VALUES(%d, \"%s\")");

const OJString DeleteRuntime1 = OJStr("DELETE FROM `runtimeinfo` WHERE `solution_id`=%d");
const OJString InsertRuntime2 = OJStr("INSERT INTO `runtimeinfo`(solution_id, error)VALUES(%d, \"%s\")");


const OJString UpdateUserSolved3 = OJStr("UPDATE `users` SET `solved`=")
    OJStr("(SELECT count(DISTINCT `problem_id`) FROM `solution` ")
    OJStr("WHERE `user_id`=\'%s\' AND `result`=%d) ")
    OJStr("WHERE `user_id`=\'%s\'");

const OJString UpdateUserSubmit2 = OJStr("UPDATE `users` SET `submit`=")
    OJStr("(SELECT count(*) FROM `solution` WHERE `user_id`=\'%s\') ")
    OJStr("WHERE `user_id`=\'%s\'");

const OJString UpdateProblemAccept3 = OJStr("UPDATE `problem` SET `accepted`=")
    OJStr("(SELECT count(*) FROM `solution` WHERE `problem_id`=\'%d\' AND `result`=\'%d\') ")
    OJStr("WHERE `problem_id`=\'%d\'");

const OJString UpdateProblemSubmit2 = OJStr("UPDATE `problem` SET `submit`=")
    OJStr("(SELECT count(*) FROM `solution` WHERE `problem_id`=\'%d\')")
    OJStr("WHERE `problem_id`=\'%d\'");


}
Esempio n. 25
0
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;
}
Esempio n. 26
0
bool WindowsJob::setLimit(const OJInt32_t timeLimit,
                        const OJInt32_t memoryLimit)
{
    ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId);

    //限制时间,单位为100ns。 1ms = 10的6次方ns = 10000 * 100ns。
    OJInt64_t   limitTime       = timeLimit * 10000;    // ms->100ns
    int         limitMemory     = memoryLimit;   //bytes

    if (limitMemory <= 0)	                //超出int范围了
        limitMemory = 128 * 1024 * 1024;    //默认128M

    //设置基本限制信息
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION subProcessLimitRes;
    ZeroMemory(&subProcessLimitRes, sizeof(subProcessLimitRes));

    JOBOBJECT_BASIC_LIMIT_INFORMATION & basicInfo = subProcessLimitRes.BasicLimitInformation;
    basicInfo.LimitFlags = \
        JOB_OBJECT_LIMIT_PRIORITY_CLASS | /*限制job优先级*/  \
        JOB_OBJECT_LIMIT_PROCESS_TIME | /*限制job时间*/ \
        JOB_OBJECT_LIMIT_PROCESS_MEMORY | /*限制job内存*/   \
        JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | /*遇到异常,让进程直接死掉。*/\
        JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | /*进程跟随job一起关闭*/\
        JOB_OBJECT_LIMIT_BREAKAWAY_OK;

    if(useToExcuter_)
    {
        basicInfo.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
        basicInfo.ActiveProcessLimit = 1;
    }

    basicInfo.PriorityClass = NORMAL_PRIORITY_CLASS;      //优先级为默认
    basicInfo.PerProcessUserTimeLimit.QuadPart = limitTime;
    subProcessLimitRes.ProcessMemoryLimit = limitMemory;

    if (!setInformation(JobObjectExtendedLimitInformation, &subProcessLimitRes, sizeof(subProcessLimitRes)))
    {
        logger->logErrorX(OJStr("[process] - setLimit - can't set job extend info! error:%u"),
            GetLastError());
        return false;
    }
        
    //让完成端口发出时间限制的消息
    JOBOBJECT_END_OF_JOB_TIME_INFORMATION timeReport;
    ZeroMemory(&timeReport, sizeof(timeReport));
    timeReport.EndOfJobTimeAction = JOB_OBJECT_POST_AT_END_OF_JOB;//时间到了,通过管道发出信息。

    if (!setInformation(JobObjectEndOfJobTimeInformation, &timeReport, sizeof(JOBOBJECT_END_OF_JOB_TIME_INFORMATION)))
    {
        logger->logErrorX(OJStr("[process] - setLimit - can't set job end info! error:%u"), GetLastError());
        return false;
    }

    //UI限制。禁止访问一些资源。
    JOBOBJECT_BASIC_UI_RESTRICTIONS subProcessLimitUi;
    ZeroMemory(&subProcessLimitUi, sizeof(subProcessLimitUi));
    subProcessLimitUi.UIRestrictionsClass = JOB_OBJECT_UILIMIT_ALL;

    if (!setInformation(JobObjectBasicUIRestrictions, &subProcessLimitUi, sizeof(subProcessLimitUi)))
    {
        logger->logErrorX(OJStr("[process] - setLimit - can't set job limit info! error:%u"), GetLastError());
        return false;
    }

    //将作业关联到完成端口,以确定其运行情况,及退出的原因。完成端口可理解为管道,job和应用程序分别位于管道的两端。
    //应用程序可以通过管道,查询job的工作状态。
    s_mutex_.lock();
    ULONG id = ++s_id_;
    s_mutex_.unlock();

    //创建完成端口
    iocpHandle_ = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, id, 0);
    if (NULL == iocpHandle_)
    {
        logger->logErrorX(OJStr("[process] - setLimit - create IOCP failed! error:%u"),
            GetLastError());
        return false;
    }
    JOBOBJECT_ASSOCIATE_COMPLETION_PORT jobCP;
    ZeroMemory(&jobCP, sizeof(jobCP));
    jobCP.CompletionKey = (PVOID)id;
    jobCP.CompletionPort = iocpHandle_;
    if (!setInformation(JobObjectAssociateCompletionPortInformation, &jobCP, sizeof(jobCP)))
    {
        logger->logErrorX(OJStr("[process] - setLimit - can't set job CompletionPort info! error:%d"),
            GetLastError());
        return false;
    }

    return true;
}