-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoperations.go
More file actions
68 lines (59 loc) · 1.22 KB
/
operations.go
File metadata and controls
68 lines (59 loc) · 1.22 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
package webrtc
import (
"sync"
)
// Operation is a function
type operation func()
// Operations is a task executor.
type operations struct {
ops []operation
mu sync.Mutex
startMu sync.Mutex
done chan struct{}
}
func newOperations() *operations {
closed := make(chan struct{})
close(closed)
return &operations{
done: closed,
}
}
// Enqueue adds a new action to be executed. If there are no actions scheduled,
// the execution will start immediately in a new goroutine.
func (o *operations) Enqueue(op operation) {
o.mu.Lock()
defer o.mu.Unlock()
o.ops = append(o.ops, op)
if len(o.ops) == 1 {
done := make(chan struct{})
o.done = done
go func() {
o.startMu.Lock()
defer o.startMu.Unlock()
o.start()
close(done)
}()
}
}
// Done will return a channel that will be closed as soon as all currently
// enqueued operations are finished.
func (o *operations) Done() <-chan struct{} {
o.mu.Lock()
defer o.mu.Unlock()
return o.done
}
func (o *operations) pop() (fn func(), isLast bool) {
o.mu.Lock()
defer o.mu.Unlock()
fn = o.ops[0]
o.ops = o.ops[1:]
return fn, len(o.ops) == 0
}
func (o *operations) start() {
var fn func()
isLast := false
for !isLast {
fn, isLast = o.pop()
fn()
}
}