mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-24 21:46:52 +01:00
DreamDaemon is now suspended while symswap happens (#54)
* DreamDaemon is now suspended while symswap happens * Fix
This commit is contained in:
+13
-12
@@ -433,20 +433,21 @@ namespace TGServerService
|
||||
try
|
||||
{
|
||||
//gotta go fast
|
||||
if (currentStatus == TGDreamDaemonStatus.Online)
|
||||
var online = currentStatus == TGDreamDaemonStatus.Online;
|
||||
if(online)
|
||||
Proc.Suspend();
|
||||
try
|
||||
{
|
||||
Thread.CurrentThread.Priority = ThreadPriority.Highest;
|
||||
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
|
||||
try
|
||||
{
|
||||
Proc.PriorityClass = ProcessPriorityClass.Idle;
|
||||
}
|
||||
catch { }
|
||||
if (Directory.Exists(GameDirLive))
|
||||
//these two lines should be atomic but this is the best we can do
|
||||
Directory.Delete(GameDirLive);
|
||||
CreateSymlink(GameDirLive, resurrectee);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(online && !Proc.HasExited)
|
||||
Proc.Resume();
|
||||
}
|
||||
if (Directory.Exists(GameDirLive))
|
||||
//these two lines should be atomic but this is the best we can do
|
||||
Directory.Delete(GameDirLive);
|
||||
CreateSymlink(GameDirLive, resurrectee);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace TGServerService
|
||||
{
|
||||
//lightly massaged code from https://stackoverflow.com/a/13109774
|
||||
public static class ProcessExtension
|
||||
{
|
||||
enum ThreadAccess : int
|
||||
{
|
||||
TERMINATE = (0x0001),
|
||||
SUSPEND_RESUME = (0x0002),
|
||||
GET_CONTEXT = (0x0008),
|
||||
SET_CONTEXT = (0x0010),
|
||||
SET_INFORMATION = (0x0020),
|
||||
QUERY_INFORMATION = (0x0040),
|
||||
SET_THREAD_TOKEN = (0x0080),
|
||||
IMPERSONATE = (0x0100),
|
||||
DIRECT_IMPERSONATION = (0x0200)
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern bool CloseHandle(IntPtr hObject);
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern uint SuspendThread(IntPtr hThread);
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern int ResumeThread(IntPtr hThread);
|
||||
|
||||
public static void Suspend(this Process process)
|
||||
{
|
||||
foreach (ProcessThread thread in process.Threads)
|
||||
{
|
||||
var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);
|
||||
if (pOpenThread == IntPtr.Zero)
|
||||
continue;
|
||||
SuspendThread(pOpenThread);
|
||||
CloseHandle(pOpenThread);
|
||||
}
|
||||
}
|
||||
public static void Resume(this Process process)
|
||||
{
|
||||
foreach (ProcessThread thread in process.Threads)
|
||||
{
|
||||
var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);
|
||||
if (pOpenThread == IntPtr.Zero)
|
||||
continue;
|
||||
ResumeThread(pOpenThread);
|
||||
CloseHandle(pOpenThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,7 @@
|
||||
<Compile Include="InterfaceBase.cs" />
|
||||
<Compile Include="IRC.cs" />
|
||||
<Compile Include="Interop.cs" />
|
||||
<Compile Include="ProcessExtension.cs" />
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
|
||||
Reference in New Issue
Block a user