예제 #1
0
파일: Sandbox.cs 프로젝트: sdcb/sdoj
        public static SandboxIoResult BeginRun(SandboxRunInfo info)
        {
            var apiInfo     = (ApiRunInfo)info;
            var apiIoResult = new ApiRunIoResult();

            NativeBeginRun(ref apiInfo, ref apiIoResult);

            var result = (SandboxIoResult)apiIoResult;

            return(result);
        }
예제 #2
0
파일: Sandbox.cs 프로젝트: sdcb/sdoj
        public static JudgeResult Judge(JudgeInfo ji, Encoding languageEncoding)
        {
            var info = new SandboxRunInfo
            {
                LimitProcessCount = 1,
                MemoryLimitMb     = ji.MemoryLimitMb,
                Path        = ji.Path,
                TimeLimitMs = ji.TimeLimitMs
            };

            SandboxIoResult ior = BeginRun(info);

            if (!ior.Succeed)
            {
                EndRun(ior.InstanceHandle);

                return((JudgeResult)ior);
            }
            ior.ErrorReadStream.Dispose();
            var writeTask = Task.Run(async() =>
            {
                using (var writer = new StreamWriter(ior.InputWriteStream, languageEncoding))
                {
                    await writer.WriteAsync(ji.Input);
                }
            });
            var readTask = ReadToEndFrom(ior.OutputReadStream, languageEncoding);

            SandboxRunResult res = EndRun(ior.InstanceHandle);

            writeTask.Wait();
            readTask.Wait();

            var jr = (JudgeResult)res;

            jr.Output = readTask.Result;

            return(jr);
        }
예제 #3
0
파일: Sandbox.cs 프로젝트: sdcb/sdoj
        public static Process2JudgeResult Process2Judge(Process2JudgeInfo p2info, Encoding languageEncoding)
        {
            // 步骤:
            // 1、启动评测
            // 2、将进程输入、输出重定向
            // 3、等待程序运行完成
            // 4、处理并返回程序运行结果。

            // 1、启动评测
            var info1 = new SandboxRunInfo
            {
                LimitProcessCount = 1,
                MemoryLimitMb     = 512.0f,
                TimeLimitMs       = 10000,
                Path = p2info.Path1
            };
            SandboxIoResult io1 = BeginRun(info1);

            if (!io1.Succeed)
            {
                EndRun(io1.InstanceHandle);
                return(new Process2JudgeResult
                {
                    P1Result = (JudgeResult)io1
                });
            }

            var info2 = new SandboxRunInfo
            {
                LimitProcessCount = 1,
                MemoryLimitMb     = p2info.MemoryLimitMb,
                TimeLimitMs       = p2info.TimeLimitMs,
                Path = p2info.Path2
            };
            SandboxIoResult io2 = BeginRun(info2);

            if (!io2.Succeed)
            {
                EndRun(io2.InstanceHandle);
                return(new Process2JudgeResult
                {
                    P2Result = (JudgeResult)io2
                });
            }

            // 2、将两个进程的输入输出重定向。
            Func <FileStream, FileStream, CancellationToken, Task> transformFunc = async(toRead, toWrite, cancel) =>
            {
                var buffer = new char[4096];
                using (var reader = new StreamReader(toRead, Encoding.Default))
                    using (var writer = new StreamWriter(toWrite))
                    {
                        while (!cancel.IsCancellationRequested)
                        {
                            var c = await reader.ReadAsync(buffer, 0, buffer.Length);

                            if (c != 0)
                            {
                                await writer.WriteAsync(buffer, 0, c);

                                Debug.WriteLine($"{Task.CurrentId}: {new string(buffer, 0, c)}");
                                await writer.FlushAsync();
                            }
                            else
                            {
                                await Task.Delay(10);
                            }
                        }
                    }
            };

            var cancelToken  = new CancellationTokenSource();
            var transform12  = transformFunc(io1.OutputReadStream, io2.InputWriteStream, cancelToken.Token);
            var transform21  = transformFunc(io2.OutputReadStream, io1.InputWriteStream, cancelToken.Token);
            var stdErrorTask = ReadToEndFrom(io1.ErrorReadStream, languageEncoding);

            io2.ErrorReadStream.Dispose();

            // 3、等待程序运行完成
            var run1 = EndRun(io1.InstanceHandle);
            var run2 = EndRun(io2.InstanceHandle);

            cancelToken.Cancel(throwOnFirstException: false);
            transform21.Wait();
            transform12.Wait();
            stdErrorTask.Wait();

            // 4、返回运行结果。
            var toReturn = new Process2JudgeResult
            {
                P1Result = (JudgeResult)run1,
                P2Result = (JudgeResult)run2
            };

            toReturn.P1Result.Output = stdErrorTask.Result;
            return(toReturn);
        }