forked from EvilBeaver/OneScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadManager.cs
More file actions
103 lines (86 loc) · 3.09 KB
/
ThreadManager.cs
File metadata and controls
103 lines (86 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*----------------------------------------------------------
This Source Code Form is subject to the terms of the
Mozilla Public License, v.2.0. If a copy of the MPL
was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using ScriptEngine.Machine;
using ScriptEngine.Machine.Debugger;
namespace OneScript.DebugServices
{
public class ThreadManager : IThreadEventsListener
{
private readonly IDictionary<int, MachineWaitToken> _machinesOnThreads = new ConcurrentDictionary<int, MachineWaitToken>();
public MachineWaitToken GetTokenForThread(int threadId)
{
if (_machinesOnThreads.TryGetValue(threadId, out var value))
{
return value;
}
throw new ArgumentOutOfRangeException($"Thread {threadId} is unregistered");
}
public event EventHandler<ThreadStoppedEventArgs> ThreadStopped;
public MachineWaitToken[] GetAllTokens()
{
return _machinesOnThreads.Values.ToArray();
}
private void EmitThreadStopped(int threadId, MachineStopReason reason, string errMessage)
{
var machine = GetTokenForThread(threadId).Machine;
var args = new ThreadStoppedEventArgs
{
Machine = machine,
ThreadId = threadId,
StopReason = reason,
ErrorMessage = errMessage
};
ThreadStopped?.Invoke(this, args);
}
public void ReleaseAllThreads()
{
var tokens = GetAllTokens();
foreach (var machineWaitToken in tokens)
{
machineWaitToken.Machine.UnsetDebugMode();
machineWaitToken.Dispose();
}
_machinesOnThreads.Clear();
}
public void Detach(int threadId)
{
if (_machinesOnThreads.Remove(threadId, out var t))
{
// Если машина была остановлена - продолжаем её уже без остановок
t.Machine.UnsetDebugMode();
t.Set();
}
}
public void Dispose()
{
ReleaseAllThreads();
}
public void ThreadStarted(int threadId, MachineInstance machine)
{
_machinesOnThreads[threadId] = new MachineWaitToken
{
Machine = machine
};
}
void IThreadEventsListener.ThreadStopped(int threadId, MachineStopReason reason, string errorMessage)
{
EmitThreadStopped(threadId, reason, errorMessage);
}
public void ThreadExited(int threadId)
{
_machinesOnThreads.Remove(threadId);
}
public IEnumerable<int> GetThreadIds()
{
return _machinesOnThreads.Keys.ToList();
}
}
}