diff options
Diffstat (limited to 'vendor/github.com/pion/stun/agent.go')
-rw-r--r-- | vendor/github.com/pion/stun/agent.go | 228 |
1 files changed, 0 insertions, 228 deletions
diff --git a/vendor/github.com/pion/stun/agent.go b/vendor/github.com/pion/stun/agent.go deleted file mode 100644 index 6a8a473..0000000 --- a/vendor/github.com/pion/stun/agent.go +++ /dev/null @@ -1,228 +0,0 @@ -package stun - -import ( - "errors" - "sync" - "time" -) - -// NoopHandler just discards any event. -var NoopHandler Handler = func(e Event) {} - -// NewAgent initializes and returns new Agent with provided handler. -// If h is nil, the NoopHandler will be used. -func NewAgent(h Handler) *Agent { - if h == nil { - h = NoopHandler - } - a := &Agent{ - transactions: make(map[transactionID]agentTransaction), - handler: h, - } - return a -} - -// Agent is low-level abstraction over transaction list that -// handles concurrency (all calls are goroutine-safe) and -// time outs (via Collect call). -type Agent struct { - // transactions is map of transactions that are currently - // in progress. Event handling is done in such way when - // transaction is unregistered before agentTransaction access, - // minimizing mux lock and protecting agentTransaction from - // data races via unexpected concurrent access. - transactions map[transactionID]agentTransaction - closed bool // all calls are invalid if true - mux sync.Mutex // protects transactions and closed - handler Handler // handles transactions -} - -// Handler handles state changes of transaction. -// -// Handler is called on transaction state change. -// Usage of e is valid only during call, user must -// copy needed fields explicitly. -type Handler func(e Event) - -// Event is passed to Handler describing the transaction event. -// Do not reuse outside Handler. -type Event struct { - TransactionID [TransactionIDSize]byte - Message *Message - Error error -} - -// agentTransaction represents transaction in progress. -// Concurrent access is invalid. -type agentTransaction struct { - id transactionID - deadline time.Time -} - -var ( - // ErrTransactionStopped indicates that transaction was manually stopped. - ErrTransactionStopped = errors.New("transaction is stopped") - // ErrTransactionNotExists indicates that agent failed to find transaction. - ErrTransactionNotExists = errors.New("transaction not exists") - // ErrTransactionExists indicates that transaction with same id is already - // registered. - ErrTransactionExists = errors.New("transaction exists with same id") -) - -// StopWithError removes transaction from list and calls handler with -// provided error. Can return ErrTransactionNotExists and ErrAgentClosed. -func (a *Agent) StopWithError(id [TransactionIDSize]byte, err error) error { - a.mux.Lock() - if a.closed { - a.mux.Unlock() - return ErrAgentClosed - } - t, exists := a.transactions[id] - delete(a.transactions, id) - h := a.handler - a.mux.Unlock() - if !exists { - return ErrTransactionNotExists - } - h(Event{ - TransactionID: t.id, - Error: err, - }) - return nil -} - -// Stop stops transaction by id with ErrTransactionStopped, blocking -// until handler returns. -func (a *Agent) Stop(id [TransactionIDSize]byte) error { - return a.StopWithError(id, ErrTransactionStopped) -} - -// ErrAgentClosed indicates that agent is in closed state and is unable -// to handle transactions. -var ErrAgentClosed = errors.New("agent is closed") - -// Start registers transaction with provided id and deadline. -// Could return ErrAgentClosed, ErrTransactionExists. -// -// Agent handler is guaranteed to be eventually called. -func (a *Agent) Start(id [TransactionIDSize]byte, deadline time.Time) error { - a.mux.Lock() - defer a.mux.Unlock() - if a.closed { - return ErrAgentClosed - } - _, exists := a.transactions[id] - if exists { - return ErrTransactionExists - } - a.transactions[id] = agentTransaction{ - id: id, - deadline: deadline, - } - return nil -} - -// agentCollectCap is initial capacity for Agent.Collect slices, -// sufficient to make function zero-alloc in most cases. -const agentCollectCap = 100 - -// ErrTransactionTimeOut indicates that transaction has reached deadline. -var ErrTransactionTimeOut = errors.New("transaction is timed out") - -// Collect terminates all transactions that have deadline before provided -// time, blocking until all handlers will process ErrTransactionTimeOut. -// Will return ErrAgentClosed if agent is already closed. -// -// It is safe to call Collect concurrently but makes no sense. -func (a *Agent) Collect(gcTime time.Time) error { - toRemove := make([]transactionID, 0, agentCollectCap) - a.mux.Lock() - if a.closed { - // Doing nothing if agent is closed. - // All transactions should be already closed - // during Close() call. - a.mux.Unlock() - return ErrAgentClosed - } - // Adding all transactions with deadline before gcTime - // to toCall and toRemove slices. - // No allocs if there are less than agentCollectCap - // timed out transactions. - for id, t := range a.transactions { - if t.deadline.Before(gcTime) { - toRemove = append(toRemove, id) - } - } - // Un-registering timed out transactions. - for _, id := range toRemove { - delete(a.transactions, id) - } - // Calling handler does not require locked mutex, - // reducing lock time. - h := a.handler - a.mux.Unlock() - // Sending ErrTransactionTimeOut to handler for all transactions, - // blocking until last one. - event := Event{ - Error: ErrTransactionTimeOut, - } - for _, id := range toRemove { - event.TransactionID = id - h(event) - } - return nil -} - -// Process incoming message, synchronously passing it to handler. -func (a *Agent) Process(m *Message) error { - e := Event{ - TransactionID: m.TransactionID, - Message: m, - } - a.mux.Lock() - if a.closed { - a.mux.Unlock() - return ErrAgentClosed - } - h := a.handler - delete(a.transactions, m.TransactionID) - a.mux.Unlock() - h(e) - return nil -} - -// SetHandler sets agent handler to h. -func (a *Agent) SetHandler(h Handler) error { - a.mux.Lock() - if a.closed { - a.mux.Unlock() - return ErrAgentClosed - } - a.handler = h - a.mux.Unlock() - return nil -} - -// Close terminates all transactions with ErrAgentClosed and renders Agent to -// closed state. -func (a *Agent) Close() error { - e := Event{ - Error: ErrAgentClosed, - } - a.mux.Lock() - if a.closed { - a.mux.Unlock() - return ErrAgentClosed - } - for _, t := range a.transactions { - e.TransactionID = t.id - a.handler(e) - } - a.transactions = nil - a.closed = true - a.handler = nil - a.mux.Unlock() - return nil -} - -type transactionID [TransactionIDSize]byte |