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
102 lines (86 loc) · 3.13 KB
/
ThreadManager.cs
File metadata and controls
102 lines (86 loc) · 3.13 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
/*----------------------------------------------------------
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 System.Threading;
using ScriptEngine.Machine;
namespace OneScript.DebugServices
{
public class ThreadManager : IDisposable
{
private readonly IDictionary<int, MachineWaitToken> _machinesOnThreads = new ConcurrentDictionary<int, MachineWaitToken>();
public MachineWaitToken GetTokenForThread(int threadId)
{
return _machinesOnThreads[threadId];
}
public MachineWaitToken GetTokenForCurrentThread()
{
return GetTokenForThread(Thread.CurrentThread.ManagedThreadId);
}
public event EventHandler<ThreadStoppedEventArgs> ThreadStopped;
public void AttachToCurrentThread()
{
var machine = MachineInstance.Current;
_machinesOnThreads[Thread.CurrentThread.ManagedThreadId] = new MachineWaitToken()
{
Machine = machine
};
machine.MachineStopped += Machine_MachineStopped;
}
public void DetachFromCurrentThread()
{
var threadId = Thread.CurrentThread.ManagedThreadId;
DetachFromThread(threadId);
}
public void DetachFromThread(int threadId)
{
if (_machinesOnThreads.TryGetValue(threadId, out var t))
{
t.Machine.MachineStopped -= Machine_MachineStopped;
_machinesOnThreads.Remove(threadId);
// Если машина была остановлена - продолжаем её уже без остановок
t.Machine.UnsetDebugMode();
t.Set();
}
}
public MachineWaitToken[] GetAllTokens()
{
return _machinesOnThreads.Values.ToArray();
}
private void Machine_MachineStopped(object sender, MachineStoppedEventArgs e)
{
var args = new ThreadStoppedEventArgs
{
Machine = (MachineInstance)sender,
ThreadId = e.ThreadId,
StopReason = e.Reason,
ErrorMessage = e.ErrorMessage
};
ThreadStopped?.Invoke(this, args);
}
public int[] GetAllThreadIds()
{
return _machinesOnThreads.Keys.ToArray();
}
public void ReleaseAllThreads()
{
var tokens = GetAllTokens();
foreach (var machineWaitToken in tokens)
{
machineWaitToken.Machine.MachineStopped -= Machine_MachineStopped;
machineWaitToken.Dispose();
}
_machinesOnThreads.Clear();
}
public void Dispose()
{
ReleaseAllThreads();
}
}
}