Example #1
0
async def _compiler_build(compiler,
                          time_limit_ns,
                          memory_limit_bytes,
                          process_limit,
                          code,
                          code_type,
                          config):
    loop = get_event_loop()
    sandbox, = await get_sandbox(1)
    try:
        await compiler.prepare(sandbox, code, code_type, config)
        output_file = path.join(sandbox.in_dir, 'output')
        mkfifo(output_file)
        with socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK) as cgroup_sock:
            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',
                config=config))
            others_task = gather(read_pipe(output_file, _MAX_OUTPUT),
                                 wait_cgroup(cgroup_sock,
                                             build_task,
                                             time_limit_ns,
                                             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:
        put_sandbox(sandbox)
Example #2
0
 async def judge(self, package):
     loop = get_event_loop()
     sandbox, = await get_sandbox(1)
     try:
         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)
         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),
                 self.read_pipe(stdout_file, MAX_STDERR_SIZE),
                 self.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, stdout, 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, stdout, stderr
     except:
         return 0, 0, 0, 0, 0, 0
     finally:
         put_sandbox(sandbox)
Example #3
0
File: case.py Project: 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)