mirror of
https://github.com/pion/webrtc.git
synced 2025-10-05 15:16:52 +08:00
69 lines
1.2 KiB
Go
69 lines
1.2 KiB
Go
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()
|
|
}
|
|
}
|