示例#1
0
async def _compiler_build(compiler, code, time_limit_ns, memory_limit_bytes,
                          process_limit):
    loop = get_event_loop()
    sandbox = await _sandbox_pool.get()
    try:
        await compiler.prepare(sandbox, code.encode())
        output_file = path.join(sandbox.in_dir, 'output')
        mkfifo(output_file)
        cgroup_sock = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK)
        cgroup_sock.bind(path.join(sandbox.in_dir, 'cgroup'))
        cgroup_sock.listen()
        build_task = loop.create_task(
            compiler.build(sandbox,
                           output_file='/in/output',
                           cgroup_file='/in/cgroup'))
        others_task = gather(
            read_pipe(output_file, _MAX_OUTPUT),
            wait_cgroup(cgroup_sock, build_task, time_limit_ns,
                        memory_limit_bytes, process_limit))
        package, status = await build_task
        output, (time_usage_ns, memory_usage_bytes) = await others_task
        return package, output.decode(encoding='utf-8', errors='replace'), \
               time_usage_ns, memory_usage_bytes
    finally:
        _sandbox_pool.put_nowait(sandbox)
示例#2
0
文件: case.py 项目: tc-imba/jd4
 async def judge(self, package):
     loop = get_event_loop()
     sandbox, = await get_sandbox(1)
     try:
         executable = await package.install(sandbox, self.execute_args)
         stdin_file = path.join(sandbox.in_dir, 'stdin')
         mkfifo(stdin_file)
         stdout_file = path.join(sandbox.in_dir, 'stdout')
         mkfifo(stdout_file)
         stderr_file = path.join(sandbox.in_dir, 'stderr')
         mkfifo(stderr_file)
         with socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK) as cgroup_sock:
             cgroup_sock.bind(path.join(sandbox.in_dir, 'cgroup'))
             cgroup_sock.listen()
             execute_task = loop.create_task(executable.execute(
                 sandbox,
                 stdin_file='/in/stdin',
                 stdout_file='/in/stdout',
                 stderr_file='/in/stderr',
                 cgroup_file='/in/cgroup'))
             others_task = gather(
                 loop.run_in_executor(None, self.do_input, stdin_file),
                 loop.run_in_executor(None, self.do_output, stdout_file),
                 read_pipe(stderr_file, MAX_STDERR_SIZE),
                 wait_cgroup(cgroup_sock,
                             execute_task,
                             self.time_limit_ns,
                             self.time_limit_ns,
                             self.memory_limit_bytes,
                             self.process_limit))
             execute_status = await execute_task
             _, correct, stderr, (time_usage_ns, memory_usage_bytes) = \
                 await others_task
         if memory_usage_bytes >= self.memory_limit_bytes:
             status = STATUS_MEMORY_LIMIT_EXCEEDED
             score = 0
         elif time_usage_ns >= self.time_limit_ns:
             status = STATUS_TIME_LIMIT_EXCEEDED
             score = 0
         elif execute_status:
             status = STATUS_RUNTIME_ERROR
             score = 0
         elif not correct:
             status = STATUS_WRONG_ANSWER
             score = 0
         else:
             status = STATUS_ACCEPTED
             score = self.score
         return status, score, time_usage_ns, memory_usage_bytes, stderr
     finally:
         put_sandbox(sandbox)
示例#3
0
 async def judge(self, sandbox, package):
     loop = get_event_loop()
     executable = await package.install(sandbox)
     stdin_file = path.join(sandbox.in_dir, 'stdin')
     mkfifo(stdin_file)
     stdout_file = path.join(sandbox.in_dir, 'stdout')
     mkfifo(stdout_file)
     stderr_file = path.join(sandbox.in_dir, 'stderr')
     mkfifo(stderr_file)
     cgroup_file = path.join(sandbox.in_dir, 'cgroup')
     execute_task = loop.create_task(executable.execute(
         sandbox,
         stdin_file='/in/stdin',
         stdout_file='/in/stdout',
         stderr_file='/in/stderr',
         cgroup_file='/in/cgroup'))
     _, correct, stderr, execute_status, (time_usage_ns, memory_usage_bytes) = await gather(
         loop.run_in_executor(None, self.do_stdin, stdin_file),
         loop.run_in_executor(None, self.do_stdout, stdout_file),
         read_pipe(stderr_file, MAX_STDERR_SIZE),
         execute_task,
         wait_cgroup(cgroup_file,
                     execute_task,
                     self.time_limit_ns,
                     self.memory_limit_bytes,
                     self.process_limit))
     if memory_usage_bytes >= self.memory_limit_bytes:
         status = STATUS_MEMORY_LIMIT_EXCEEDED
         score = 0
     elif time_usage_ns >= self.time_limit_ns:
         status = STATUS_TIME_LIMIT_EXCEEDED
         score = 0
     elif execute_status:
         status = STATUS_RUNTIME_ERROR
         score = 0
     elif not correct:
         status = STATUS_WRONG_ANSWER
         score = 0
     else:
         status = STATUS_ACCEPTED
         score = self.score
     return status, score, time_usage_ns, memory_usage_bytes, stderr
示例#4
0
文件: case.py 项目: tc-imba/jd4
    async def judge(self, user_package):
        loop = get_event_loop()
        judge_package, message, _, _ = await build(
            self.judge_lang,
            await loop.run_in_executor(None, lambda: self.open_judge().read()))
        if not judge_package:
            return STATUS_SYSTEM_ERROR, 0, 0, 0, message
        user_sandbox, judge_sandbox = await get_sandbox(2)
        try:
            async def prepare_user_sandbox():
                await user_sandbox.reset()
                return await user_package.install(user_sandbox)

            async def prepare_judge_sandbox():
                await judge_sandbox.reset()
                return await judge_package.install(judge_sandbox)

            user_executable, judge_executable = \
                await gather(prepare_user_sandbox(), prepare_judge_sandbox())
            user_stdin_file = path.join(user_sandbox.in_dir, 'stdin')
            mkfifo(user_stdin_file)
            user_stdout_file = path.join(user_sandbox.in_dir, 'stdout')
            mkfifo(user_stdout_file)
            judge_stdin_file = path.join(judge_sandbox.in_dir, 'stdin')
            link(user_stdout_file, judge_stdin_file)
            user_stderr_file = path.join(user_sandbox.in_dir, 'stderr')
            mkfifo(user_stderr_file)
            judge_stdout_file = path.join(judge_sandbox.in_dir, 'stdout')
            mkfifo(judge_stdout_file)
            judge_stderr_file = path.join(judge_sandbox.in_dir, 'stderr')
            mkfifo(judge_stderr_file)
            judge_extra_file = path.join(judge_sandbox.in_dir, 'extra')
            mkfifo(judge_extra_file)
            with socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK) as user_cgroup_sock, \
                    socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK) as judge_cgroup_sock:
                user_cgroup_sock.bind(path.join(user_sandbox.in_dir, 'cgroup'))
                judge_cgroup_sock.bind(path.join(judge_sandbox.in_dir, 'cgroup'))
                user_cgroup_sock.listen()
                judge_cgroup_sock.listen()
                user_execute_task = loop.create_task(user_executable.execute(
                    user_sandbox,
                    stdin_file='/in/stdin',
                    stdout_file='/in/stdout',
                    stderr_file='/in/stderr',
                    cgroup_file='/in/cgroup'))
                judge_execute_task = loop.create_task(judge_executable.execute(
                    judge_sandbox,
                    stdin_file='/in/stdin',
                    stdout_file='/in/stdout',
                    stderr_file='/in/stderr',
                    extra_file='/in/extra',
                    cgroup_file='/in/cgroup'))
                others_task = gather(
                    loop.run_in_executor(None, self.do_input, user_stdin_file),
                    loop.run_in_executor(None, self.do_input, judge_extra_file),
                    read_pipe(user_stderr_file, MAX_STDERR_SIZE),
                    read_pipe(judge_stdout_file, MAX_STDERR_SIZE),
                    read_pipe(judge_stderr_file, MAX_STDERR_SIZE),
                    wait_cgroup(user_cgroup_sock,
                                user_execute_task,
                                self.time_ns,
                                self.time_ns,
                                self.memory_bytes,
                                PROCESS_LIMIT),
                    wait_cgroup(judge_cgroup_sock,
                                judge_execute_task,
                                DEFAULT_TIME_NS,
                                self.time_ns + DEFAULT_TIME_NS,
                                DEFAULT_MEMORY_BYTES,
                                PROCESS_LIMIT))
                user_execute_status, judge_execute_status = await gather(
                    user_execute_task, judge_execute_task)
                _, _, user_stderr, judge_stdout, judge_stderr, \
                (user_time_usage_ns, user_memory_usage_bytes), \
                (judge_time_usage_ns, judge_memory_usage_bytes) = \
                    await others_task
            if (judge_execute_status or
                    judge_memory_usage_bytes >= DEFAULT_MEMORY_BYTES or
                    judge_time_usage_ns >= DEFAULT_TIME_NS):
                status = STATUS_SYSTEM_ERROR
                score = 0
            elif user_memory_usage_bytes >= self.memory_bytes:
                status = STATUS_MEMORY_LIMIT_EXCEEDED
                score = 0
            elif user_time_usage_ns >= self.time_ns:
                status = STATUS_TIME_LIMIT_EXCEEDED
                score = 0
            elif user_execute_status:
                status = STATUS_RUNTIME_ERROR
                score = 0
            else:
                try:
                    status, score = map(int, judge_stdout.split())
                except SystemError:
                    status = STATUS_SYSTEM_ERROR
                    score = 0
            return status, score, user_time_usage_ns, user_memory_usage_bytes, user_stderr
        finally:
            put_sandbox(user_sandbox, judge_sandbox)