-
-
Notifications
You must be signed in to change notification settings - Fork 492
/
Copy pathLoopThreadPool.cs
126 lines (104 loc) · 3.45 KB
/
LoopThreadPool.cs
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//
// Copyright Fela Ameghino 2015-2025
//
// Distributed under the GNU General Public License v3.0. (See accompanying
// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt)
//
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace Telegram.Common
{
public partial class LoopThreadPool
{
private static readonly ConcurrentDictionary<TimeSpan, LoopThread> _specificFrameRate = new();
private static readonly MultiValueDictionary<TimeSpan, LoopThread> _test = new();
private static readonly object _lock = new();
public static LoopThread Rent(TimeSpan frameRate)
{
LoopThread target = null;
lock (_lock)
{
_test.TryGetValue(frameRate, out var threads);
_test[frameRate] = threads ??= new List<LoopThread>();
for (int i = 0; i < threads.Count; i++)
{
var thread = threads[i];
if (thread.Count == 0)
{
if (target == null)
{
target = thread;
}
else
{
threads.RemoveAt(i);
i--;
}
}
else if (thread.HasMoreResources)
{
target = thread;
}
}
if (target == null)
{
target = new LoopThread(frameRate);
threads.Add(target);
}
target.Rent();
}
return target;
}
public static void Release(LoopThread target)
{
if (target == null)
{
return;
}
lock (_lock)
{
target.Release();
if (target.Count == 0 && _test.TryGetValue(target.Interval, out var threads))
{
threads.Remove(target);
}
}
}
public static LoopThread Get2(TimeSpan frameRate)
{
if (_specificFrameRate.TryGetValue(frameRate, out LoopThread thread))
{
return thread;
}
thread = new LoopThread(frameRate);
_specificFrameRate[frameRate] = thread;
return thread;
}
private readonly LoopThread[] _pool;
private int _lastUsed = -1;
public LoopThreadPool(int count, TimeSpan interval)
{
_pool = new LoopThread[count];
for (int i = 0; i < count; i++)
{
_pool[i] = new LoopThread(interval);
}
}
[ThreadStatic]
private static LoopThreadPool _animations;
public static LoopThreadPool Animations => _animations ??= new LoopThreadPool(3, TimeSpan.FromMilliseconds(1000 / 30));
[ThreadStatic]
private static LoopThreadPool _stickers;
public static LoopThreadPool Stickers => _stickers ??= new LoopThreadPool(2, TimeSpan.FromMilliseconds(1000 / 30));
public LoopThread Get()
{
_lastUsed++;
if (_lastUsed >= _pool.Length)
{
_lastUsed = 0;
}
return _pool[_lastUsed];
}
}
}