static RundotnetData RunSqlServer(RundotnetData data)
{
string path = reExp.Utils.Utils.RootFolder + "executables/usercode/" + Utils.Utils.RandomString() + ".sql";
using (TextWriter tw = new StreamWriter(path))
{
tw.Write(data.Program);
}
using (Process process = new Process())
{
try
{
double TotalMemoryInBytes = 0;
double TotalThreadCount = 0;
int samplesCount = 0;
process.StartInfo.FileName = reExp.Utils.Utils.RootFolder + "executables/SqlServer.exe";
process.StartInfo.Arguments = path.Replace(" ", "|_|");
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
DateTime start = DateTime.Now;
process.Start();
OutputReader output = new OutputReader(process.StandardOutput, false);
Thread outputReader = new Thread(new ThreadStart(output.ReadOutput));
outputReader.Start();
OutputReader error = new OutputReader(process.StandardError);
Thread errorReader = new Thread(new ThreadStart(error.ReadOutput));
errorReader.Start();
do
{
// Refresh the current process property values.
process.Refresh();
if (!process.HasExited)
{
try
{
var proc = process.TotalProcessorTime;
// Update the values for the overall peak memory statistics.
var mem1 = process.PagedMemorySize64;
var mem2 = process.PrivateMemorySize64;
//update stats
TotalMemoryInBytes += (mem1 + mem2);
TotalThreadCount += (process.Threads.Count);
samplesCount++;
if (proc.TotalSeconds > 5 || mem1 + mem2 > 100000000 || process.Threads.Count > 100 || start + TimeSpan.FromSeconds(15) < DateTime.Now)
{
var time = proc.TotalSeconds;
var mem = mem1 + mem2;
process.Kill();
var res = string.Format("Process killed because it exceeded given resources.\nCpu time used {0} sec, absolute running time {1} sec, memory used {2} Mb, nr of threads {3}", time, (int)(DateTime.Now - start).TotalSeconds, (int)(mem / 1048576), process.Threads.Count);
data.Errors.Add(res);
string partialResult = output.Builder.ToString();
data.Output = partialResult;
data.RunStats = string.Format("Absolute service time: {0} sec", Math.Round((double)(DateTime.Now - start).TotalMilliseconds / 1000, 2));
Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, res, (int)data.LanguageChoice, data.IsApi, false);
return data;
}
}
catch (InvalidOperationException)
{
break;
}
}
}
while (!process.WaitForExit(10));
process.WaitForExit();
errorReader.Join(5000);
outputReader.Join(5000);
if (!string.IsNullOrEmpty(error.Output))
{
data.Output = output.Builder.ToString();
data.Errors.Add(error.Output);
data.RunStats = string.Format("Absolute service time: {0} sec", Math.Round((double)(DateTime.Now - start).TotalMilliseconds / 1000, 2));
Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, error.Output, (int)data.LanguageChoice, data.IsApi, false);
return data;
}
if (File.Exists(path + ".stats"))
{
using (TextReader tr = new StreamReader(path + ".stats"))
{
data.RunStats = tr.ReadLine();
if (!string.IsNullOrEmpty(data.RunStats))
data.RunStats += ", ";
else
data.RunStats = "";
data.RunStats += string.Format("absolute service time: {0} sec", Math.Round((double)(DateTime.Now - start).TotalMilliseconds / 1000, 2));
}
}
else
{
data.RunStats = string.Format("Absolute service time: {0} sec", Math.Round((double)(DateTime.Now - start).TotalMilliseconds / 1000, 2));
}
data.Output = output.Output;
Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, "OK", (int)data.LanguageChoice, data.IsApi, true);
return data;
}
catch (Exception e)
{
if (!process.HasExited)
{
reExp.Utils.Log.LogInfo("Process left running " + e.Message, e, "RunSqlServer");
}
throw;
}
finally
{
try
{
reExp.Utils.CleanUp.DeleteFile(path);
reExp.Utils.CleanUp.DeleteFile(path + ".stats");
}
catch (Exception)
{ }
SqlServerUtils job = new SqlServerUtils();
Thread t = new Thread(job.DoShrinkJob);
t.Start();
}
}
}