-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathResourceQueue.cs
74 lines (63 loc) · 1.74 KB
/
ResourceQueue.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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
namespace johnshope.Sync {
public class ResourceQueue<T>: System.Collections.Generic.LinkedList<T> {
AutoResetEvent signal = new AutoResetEvent(false);
public void Enqueue(T entry) {
lock (this) {
var node = First;
while (node != null && node.Value != null) node = node.Next;
if (node == null) AddLast(entry);
else AddBefore(node, entry);
}
signal.Set();
}
public T Dequeue() {
lock (this) {
if (base.Count > 0) {
var entry = First;
RemoveFirst();
return entry.Value;
} else return default(T);
}
}
public T Dequeue(Func<T, bool> where) {
lock (this) {
if (base.Count > 0) {
var entry = First;
while (entry != null && entry.Value != null && !where(entry.Value)) entry = entry.Next;
if (entry == null) entry = First;
Remove(entry);
return entry.Value;
} else return default(T);
}
}
public event EventHandler Blocking;
public event EventHandler Blocked;
public T DequeueOrBlock() {
do {
lock (this) {
if (base.Count > 0) return Dequeue();
}
if (Blocking != null) Blocking(this, EventArgs.Empty);
signal.WaitOne();
if (Blocked != null) Blocked(this, EventArgs.Empty);
} while (true);
}
public T DequeueOrBlock(Func<T, bool> where) {
do {
lock (this) {
if (base.Count > 0) return Dequeue(where);
}
if (Blocking != null) Blocking(this, EventArgs.Empty);
signal.WaitOne();
if (Blocked != null) Blocked(this, EventArgs.Empty);
} while (true);
}
public bool IsEmpty { get { lock (this) return base.Count == 0; } }
public new int Count { get { lock (this) return base.Count; } }
}
}