Skip to content

Commit fadd212

Browse files
committed
Fix issues with closing patcher
1 parent 52d444f commit fadd212

File tree

1 file changed

+151
-42
lines changed

1 file changed

+151
-42
lines changed

src/Assets/Scripts/Patcher.cs

Lines changed: 151 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public enum UserDecision
2323
StartApp
2424
}
2525

26+
#region Private fields
27+
2628
private static readonly DebugLogger DebugLogger = new DebugLogger(typeof(Patcher));
2729

2830
public static Patcher Instance { get; private set; }
@@ -35,7 +37,9 @@ public enum UserDecision
3537

3638
private App _app;
3739

38-
private bool _hasBeenDestroyed;
40+
private bool _keepThreadAlive;
41+
42+
private bool _isThreadBeingDestroyed;
3943

4044
private UserDecision _userDecision = UserDecision.None;
4145

@@ -49,10 +53,9 @@ public enum UserDecision
4953

5054
private CancellationTokenSource _cancellationTokenSource;
5155

52-
public PatcherData Data
53-
{
54-
get { return _data; }
55-
}
56+
#endregion
57+
58+
#region Events
5659

5760
public event Action<OverallStatus> UpdateAppStatusChanged;
5861

@@ -66,23 +69,21 @@ public PatcherData Data
6669

6770
public event Action<bool> CanCheckInternetConnectionChanged;
6871

72+
#endregion
73+
74+
#region Public fields
75+
6976
public string EditorAppSecret;
7077

7178
public int EditorOverrideLatestVersionId;
7279

7380
public PatcherConfiguration DefaultConfiguration;
7481

75-
private PatcherState _state = PatcherState.None;
82+
#endregion
7683

77-
public PatcherState State
78-
{
79-
get { return _state; }
80-
set
81-
{
82-
_state = value;
83-
OnStateChanged(_state);
84-
}
85-
}
84+
#region Public properties
85+
86+
#region Decisions availability
8687

8788
private bool _canUpdateApp;
8889

@@ -123,9 +124,29 @@ public bool CanCheckInternetConnection
123124
}
124125
}
125126

126-
private PatcherError _error;
127+
#endregion
128+
129+
private PatcherState _state = PatcherState.None;
130+
131+
public PatcherState State
132+
{
133+
get { return _state; }
134+
set
135+
{
136+
_state = value;
137+
OnStateChanged(_state);
138+
}
139+
}
140+
127141
private PatcherData _data;
128142

143+
public PatcherData Data
144+
{
145+
get { return _data; }
146+
}
147+
148+
private PatcherError _error;
149+
129150
public PatcherError Error
130151
{
131152
get { return _error; }
@@ -136,6 +157,10 @@ public PatcherError Error
136157
}
137158
}
138159

160+
#endregion
161+
162+
#region Public methods
163+
139164
public void SetUserDecision(UserDecision userDecision)
140165
{
141166
DebugLogger.Log("Setting user deicision.");
@@ -181,6 +206,10 @@ public void Cancel()
181206
}
182207
}
183208

209+
#endregion
210+
211+
#region Logging operations
212+
184213
private void LogSystemInfo()
185214
{
186215
DebugLogger.LogVariable(Environment.Version, "Environment.Version");
@@ -204,16 +233,21 @@ private void LogPatcherInfo()
204233
DebugLogger.Log(string.Format("Patcher version - {0}", GetPatcherVersion()));
205234
}
206235

236+
#endregion
237+
238+
#region Unity events
239+
207240
private void Awake()
208241
{
209242
DebugLogger.Log("Awake Unity event.");
210243

211-
LogSystemInfo();
212-
LogPatcherInfo();
213-
214244
Instance = this;
215245
Dispatcher.Initialize();
216246
Application.runInBackground = true;
247+
248+
LogSystemInfo();
249+
LogPatcherInfo();
250+
217251
try
218252
{
219253
LoadPatcherData();
@@ -232,57 +266,116 @@ private void Start()
232266
DebugLogger.Log("Start Unity event.");
233267

234268
DebugLogger.Log("Starting patcher thread.");
269+
270+
_keepThreadAlive = true;
235271
_thread = new Thread(ThreadFunc);
236272
_thread.Start();
237273
}
238274

275+
private void OnApplicationQuit()
276+
{
277+
DebugLogger.Log("OnApplicationQuit Unity event.");
278+
279+
if (_thread != null && _thread.IsAlive)
280+
{
281+
DebugLogger.Log("Cancelling quit because patcher thread is still alive.");
282+
283+
Application.CancelQuit();
284+
StartCoroutine(DestroyPatcherThreadAndQuit());
285+
}
286+
}
287+
239288
private void OnDestroy()
240289
{
241290
DebugLogger.Log("OnDestroy Unity event.");
242291

243-
if(_app != null)
292+
if (_thread != null && _thread.IsAlive)
244293
{
245-
_app.Dispose();
294+
DestroyPatcherThread();
246295
}
296+
}
247297

248-
DebugLogger.Log("Cleaning up thread.");
249-
250-
_hasBeenDestroyed = true;
298+
private void DestroyPatcherThread()
299+
{
300+
DebugLogger.Log("Destroying patcher thread.");
251301

252-
if (_thread != null && _thread.IsAlive)
302+
while (_thread != null && _thread.IsAlive)
253303
{
254-
while(_thread.IsAlive)
255-
{
256-
Cancel();
304+
DebugLogger.Log("Trying to safely destroy patcher thread.");
305+
306+
_keepThreadAlive = false;
307+
Cancel();
308+
_thread.Interrupt();
257309

258-
DebugLogger.Log("Interrupting thread.");
310+
_thread.Join(1000);
259311

260-
_thread.Interrupt();
261-
312+
if (_thread.IsAlive)
313+
{
314+
DebugLogger.Log("Trying to force destroy patcher thread.");
315+
316+
_thread.Abort();
262317
_thread.Join(1000);
318+
}
319+
}
263320

264-
if (_thread.IsAlive)
265-
{
266-
while (_thread.IsAlive)
267-
{
268-
DebugLogger.Log("Aborting thread.");
321+
DebugLogger.Log("Patcher thread has been destroyed.");
322+
}
269323

270-
_thread.Abort();
271-
_thread.Join(1000);
272-
}
324+
private IEnumerator DestroyPatcherThreadAndQuit()
325+
{
326+
DebugLogger.Log("Destroying patcher thread.");
327+
328+
if (_isThreadBeingDestroyed)
329+
{
330+
DebugLogger.Log("Patcher thread is already being destroyed.");
331+
yield break;
332+
}
333+
334+
_isThreadBeingDestroyed = true;
335+
336+
while (_thread != null && _thread.IsAlive)
337+
{
338+
DebugLogger.Log("Trying to safely destroy patcher thread.");
339+
340+
_keepThreadAlive = false;
341+
Cancel();
342+
_thread.Interrupt();
343+
344+
float startTime = Time.unscaledTime;
345+
while (Time.unscaledTime - startTime < 1.0f && _thread.IsAlive)
346+
{
347+
yield return null;
348+
}
349+
350+
if (_thread.IsAlive)
351+
{
352+
DebugLogger.Log("Trying to force destroy patcher thread.");
353+
354+
_thread.Abort();
355+
startTime = Time.unscaledTime;
356+
while (Time.unscaledTime - startTime < 1.0f && _thread.IsAlive)
357+
{
358+
yield return null;
273359
}
274360
}
275361
}
362+
363+
DebugLogger.Log("Patcher thread has been destroyed. Quitting application.");
364+
Application.Quit();
276365
}
277366

367+
#endregion
368+
369+
#region Thread
370+
278371
private void ThreadFunc()
279372
{
280373
try
281374
{
282375
CheckInternetConnection();
283376
LoadPatcherConfiguration();
284377

285-
while (!_hasBeenDestroyed)
378+
while (_keepThreadAlive)
286379
{
287380
try
288381
{
@@ -307,6 +400,7 @@ private void ThreadFunc()
307400
}
308401
catch (OperationCanceledException)
309402
{
403+
DebugLogger.Log("Patcher has been cancelled.");
310404
}
311405
catch (UnauthorizedAccessException)
312406
{
@@ -336,16 +430,25 @@ private void ThreadFunc()
336430
{
337431
DebugLogger.Log("Thread has been interrupted.");
338432
}
339-
catch(ThreadAbortException)
433+
catch (ThreadAbortException)
340434
{
341435
DebugLogger.Log("Thread has been aborted.");
342436
}
343-
catch(Exception exception)
437+
catch (Exception exception)
344438
{
345439
DebugLogger.LogException(exception);
346440
DebugLogger.LogError("Exception in patcher thread.");
347441
Quit();
348442
}
443+
finally
444+
{
445+
if (_app != null)
446+
{
447+
_app.Dispose();
448+
}
449+
450+
DebugLogger.Log("Patcher thread has been destroyed.");
451+
}
349452
}
350453

351454
private void LoadPatcherData()
@@ -501,6 +604,10 @@ private void HandleErrorMessage(Exception exception)
501604
_errorMessageHandled.WaitOne();
502605
}
503606

607+
#endregion
608+
609+
#region Event invokers
610+
504611
protected virtual void OnUpdateAppStatusChanged(OverallStatus obj)
505612
{
506613
Dispatcher.Invoke(() =>
@@ -548,5 +655,7 @@ protected virtual void OnCanCheckInternetConnectionChanged(bool obj)
548655
if (CanCheckInternetConnectionChanged != null) CanCheckInternetConnectionChanged(obj);
549656
});
550657
}
658+
659+
#endregion
551660
}
552661
}

0 commit comments

Comments
 (0)