Skip to content

Commit 4477132

Browse files
authored
Merge pull request #180 from immutable/fix/windows-engine-timeout
[DX-2753] fix: add voltstro unity web browser fixes for engine timeout
2 parents 0288124 + 77483da commit 4477132

11 files changed

+372
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:668a01c66bf4bd9c89cb1c393fcfaca294766ba9077d389ff575a0a54a2a4eef
2+
oid sha256:28795420fd282716cf4e7c58ebf7bfee64f3d98b3fbac4dcdce94b964d6ae2ee
33
size 23040
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
2+
3+
// UnityWebBrowser (UWB)
4+
// Copyright (c) 2021-2024 Voltstro-Studios
5+
//
6+
// This project is under the MIT license. See the LICENSE.md file for more details.
7+
8+
using System;
9+
using System.Diagnostics;
10+
using VoltstroStudios.UnityWebBrowser.Core.Engines.Process;
11+
using VoltstroStudios.UnityWebBrowser.Helper;
12+
using VoltstroStudios.UnityWebBrowser.Logging;
13+
14+
namespace VoltstroStudios.UnityWebBrowser.Core.Engines
15+
{
16+
/// <summary>
17+
/// Handler for the engine process
18+
/// </summary>
19+
internal sealed class EngineProcess : IDisposable
20+
{
21+
private readonly IProcess processHandle;
22+
private readonly Engine engine;
23+
private readonly IWebBrowserLogger logger;
24+
25+
/// <summary>
26+
/// Creates a new <see cref="EngineProcess"/> instance
27+
/// </summary>
28+
/// <param name="engine"></param>
29+
/// <param name="logger"></param>
30+
public EngineProcess(Engine engine, IWebBrowserLogger logger)
31+
{
32+
processHandle = new WindowProcess();
33+
34+
this.engine = engine;
35+
this.logger = logger;
36+
}
37+
38+
/// <summary>
39+
/// Has the process exited?
40+
/// </summary>
41+
public bool HasExited => processHandle.HasExited;
42+
43+
/// <summary>
44+
/// What was the exit code of the process
45+
/// </summary>
46+
public int ExitCode => processHandle.ExitCode;
47+
48+
/// <summary>
49+
/// Starts the engine process
50+
/// </summary>
51+
/// <param name="arguments"></param>
52+
/// <param name="onLogEvent"></param>
53+
/// <param name="onErrorLogEvent"></param>
54+
public void StartProcess(string arguments, DataReceivedEventHandler onLogEvent, DataReceivedEventHandler onErrorLogEvent)
55+
{
56+
string engineFullProcessPath = WebBrowserUtils.GetBrowserEngineProcessPath(engine);
57+
string engineDirectory = WebBrowserUtils.GetBrowserEnginePath(engine);
58+
59+
logger.Debug($"Process Path: '{engineFullProcessPath}'\nWorking: '{engineDirectory}'");
60+
logger.Debug($"Arguments: '{arguments}'");
61+
62+
processHandle.StartProcess(engineFullProcessPath, engineDirectory, arguments, onLogEvent, onErrorLogEvent);
63+
}
64+
65+
/// <summary>
66+
/// Kills the engine process
67+
/// </summary>
68+
public void KillProcess()
69+
{
70+
processHandle.KillProcess();
71+
}
72+
73+
public void Dispose()
74+
{
75+
processHandle.Dispose();
76+
}
77+
}
78+
}
79+
80+
#endif

src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/Runtime/Core/Engines/EngineProcess.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/Runtime/Core/Engines/Process.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
2+
3+
// UnityWebBrowser (UWB)
4+
// Copyright (c) 2021-2024 Voltstro-Studios
5+
//
6+
// This project is under the MIT license. See the LICENSE.md file for more details.
7+
8+
using System;
9+
using System.Diagnostics;
10+
11+
namespace VoltstroStudios.UnityWebBrowser.Core.Engines.Process
12+
{
13+
internal interface IProcess : IDisposable
14+
{
15+
public void StartProcess(string executable, string workingDir, string arguments, DataReceivedEventHandler onLogEvent, DataReceivedEventHandler onErrorLogEvent);
16+
17+
public void KillProcess();
18+
19+
public bool HasExited { get; }
20+
21+
public int ExitCode { get; }
22+
}
23+
}
24+
25+
#endif

src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/Runtime/Core/Engines/Process/IProcess.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
2+
3+
// UnityWebBrowser (UWB)
4+
// Copyright (c) 2021-2024 Voltstro-Studios
5+
//
6+
// This project is under the MIT license. See the LICENSE.md file for more details.
7+
8+
using System;
9+
using System.ComponentModel;
10+
using System.Diagnostics;
11+
using System.Runtime.InteropServices;
12+
13+
namespace VoltstroStudios.UnityWebBrowser.Core.Engines.Process
14+
{
15+
internal sealed class WindowProcess : IProcess
16+
{
17+
private readonly System.Diagnostics.Process process;
18+
private readonly IntPtr jobHandle;
19+
20+
public WindowProcess()
21+
{
22+
//Job handle code from SO
23+
//https://stackoverflow.com/questions/3342941/kill-child-process-when-parent-process-is-killed
24+
string jobName = "UWBChildProcesses" + System.Diagnostics.Process.GetCurrentProcess().Id;
25+
jobHandle = CreateJobObject(IntPtr.Zero, jobName);
26+
27+
JOBOBJECT_BASIC_LIMIT_INFORMATION info = new()
28+
{
29+
// This is the key flag. When our process is killed, Windows will automatically
30+
// close the job handle, and when that happens, we want the child processes to
31+
// be killed, too.
32+
LimitFlags = JOBOBJECTLIMIT.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
33+
};
34+
35+
JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
36+
{
37+
BasicLimitInformation = info
38+
};
39+
40+
int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
41+
IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
42+
try
43+
{
44+
Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
45+
46+
if (!SetInformationJobObject(jobHandle, JobObjectInfoType.ExtendedLimitInformation,
47+
extendedInfoPtr, (uint)length))
48+
{
49+
throw new Win32Exception();
50+
}
51+
}
52+
finally
53+
{
54+
Marshal.FreeHGlobal(extendedInfoPtr);
55+
}
56+
57+
process = new System.Diagnostics.Process();
58+
}
59+
60+
public void StartProcess(string executable, string workingDir, string arguments, DataReceivedEventHandler onLogEvent, DataReceivedEventHandler onErrorLogEvent)
61+
{
62+
ProcessStartInfo startInfo = new(executable, arguments)
63+
{
64+
CreateNoWindow = true,
65+
UseShellExecute = false,
66+
RedirectStandardOutput = true,
67+
RedirectStandardError = true,
68+
WorkingDirectory = workingDir
69+
};
70+
71+
process.StartInfo = startInfo;
72+
process.OutputDataReceived += onLogEvent;
73+
process.ErrorDataReceived += onErrorLogEvent;
74+
process.Start();
75+
process.BeginOutputReadLine();
76+
process.BeginErrorReadLine();
77+
78+
//Assign this process to the job handle
79+
bool success = AssignProcessToJobObject(jobHandle, process.Handle);
80+
if (!success && !process.HasExited)
81+
throw new Win32Exception();
82+
}
83+
84+
public void KillProcess()
85+
{
86+
TerminateJobObject(jobHandle, 0);
87+
}
88+
89+
public bool HasExited => process.HasExited;
90+
public int ExitCode => process.ExitCode;
91+
92+
public void Dispose()
93+
{
94+
process.Dispose();
95+
}
96+
97+
#region WIN32 Native
98+
99+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
100+
private static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, string name);
101+
102+
[DllImport("kernel32.dll")]
103+
private static extern bool SetInformationJobObject(IntPtr job, JobObjectInfoType infoType,
104+
IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
105+
106+
[DllImport("kernel32.dll", SetLastError = true)]
107+
private static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
108+
109+
[DllImport("kernel32.dll", SetLastError = true)]
110+
private static extern bool TerminateJobObject(IntPtr job, uint exitCode);
111+
112+
public enum JobObjectInfoType
113+
{
114+
AssociateCompletionPortInformation = 7,
115+
BasicLimitInformation = 2,
116+
BasicUIRestrictions = 4,
117+
EndOfJobTimeInformation = 6,
118+
ExtendedLimitInformation = 9,
119+
SecurityLimitInformation = 5,
120+
GroupInformation = 11
121+
}
122+
123+
[StructLayout(LayoutKind.Sequential)]
124+
public struct JOBOBJECT_BASIC_LIMIT_INFORMATION
125+
{
126+
public Int64 PerProcessUserTimeLimit;
127+
public Int64 PerJobUserTimeLimit;
128+
public JOBOBJECTLIMIT LimitFlags;
129+
public UIntPtr MinimumWorkingSetSize;
130+
public UIntPtr MaximumWorkingSetSize;
131+
public UInt32 ActiveProcessLimit;
132+
public Int64 Affinity;
133+
public UInt32 PriorityClass;
134+
public UInt32 SchedulingClass;
135+
}
136+
137+
[Flags]
138+
public enum JOBOBJECTLIMIT : uint
139+
{
140+
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x2000
141+
}
142+
143+
[StructLayout(LayoutKind.Sequential)]
144+
public struct IO_COUNTERS
145+
{
146+
public UInt64 ReadOperationCount;
147+
public UInt64 WriteOperationCount;
148+
public UInt64 OtherOperationCount;
149+
public UInt64 ReadTransferCount;
150+
public UInt64 WriteTransferCount;
151+
public UInt64 OtherTransferCount;
152+
}
153+
154+
[StructLayout(LayoutKind.Sequential)]
155+
public struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
156+
{
157+
public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
158+
public IO_COUNTERS IoInfo;
159+
public UIntPtr ProcessMemoryLimit;
160+
public UIntPtr JobMemoryLimit;
161+
public UIntPtr PeakProcessMemoryUsed;
162+
public UIntPtr PeakJobMemoryUsed;
163+
}
164+
165+
#endregion
166+
}
167+
}
168+
169+
#endif

src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/Runtime/Core/Engines/Process/WindowProcess.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)