Source File
operations.go
Belonging Package
github.com/pion/webrtc/v4
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>// SPDX-License-Identifier: MITpackage webrtcimport ()// Operation is a function.type operation func()// Operations is a task executor.type operations struct {mu sync.MutexbusyCh chan struct{}ops *list.ListupdateNegotiationNeededFlagOnEmptyChain *atomicBoolonNegotiationNeeded func()isClosed bool}func newOperations(*atomicBool,func(),) *operations {return &operations{ops: list.New(),updateNegotiationNeededFlagOnEmptyChain: ,onNegotiationNeeded: ,}}// Enqueue adds a new action to be executed. If there are no actions scheduled,// the execution will start immediately in a new goroutine. If the queue has been// closed, the operation will be dropped. The queue is only deliberately closed// by a user.func ( *operations) ( operation) {.mu.Lock()defer .mu.Unlock()_ = .tryEnqueue()}// tryEnqueue attempts to enqueue the given operation. It returns false// if the op is invalid or the queue is closed. mu must be locked by// tryEnqueue's caller.func ( *operations) ( operation) bool {if == nil {return false}if .isClosed {return false}.ops.PushBack()if .busyCh == nil {.busyCh = make(chan struct{})go .start()}return true}// IsEmpty checks if there are tasks in the queue.func ( *operations) () bool {.mu.Lock()defer .mu.Unlock()return .ops.Len() == 0}// Done blocks until all currently enqueued operations are finished executing.// For more complex synchronization, use Enqueue directly.func ( *operations) () {var sync.WaitGroup.Add(1).mu.Lock():= .tryEnqueue(func() {.Done()}).mu.Unlock()if ! {return}.Wait()}// GracefulClose waits for the operations queue to be cleared and forbids// new operations from being enqueued.func ( *operations) () {.mu.Lock()if .isClosed {.mu.Unlock()return}// do not enqueue anymore ops from here on// o.isClosed=true will also not allow a new busyCh// to be created..isClosed = true:= .busyCh.mu.Unlock()if == nil {return}<-}func ( *operations) () func() {.mu.Lock()defer .mu.Unlock()if .ops.Len() == 0 {return nil}:= .ops.Front().ops.Remove()if , := .Value.(operation); {return}return nil}func ( *operations) () {defer func() {.mu.Lock()defer .mu.Unlock()// this wil lbe the most recent busy chanclose(.busyCh)if .ops.Len() == 0 || .isClosed {.busyCh = nilreturn}// either a new operation was enqueued while we// were busy, or an operation panicked.busyCh = make(chan struct{})go .()}():= .pop()for != nil {()= .pop()}if !.updateNegotiationNeededFlagOnEmptyChain.get() {return}.updateNegotiationNeededFlagOnEmptyChain.set(false).onNegotiationNeeded()}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |