Update dependencies
This commit is contained in:
228
vendor/gvisor.dev/gvisor/pkg/context/context.go
vendored
Normal file
228
vendor/gvisor.dev/gvisor/pkg/context/context.go
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package context defines an internal context type.
|
||||
//
|
||||
// The given Context conforms to the standard Go context, but mandates
|
||||
// additional methods that are specific to the kernel internals. Note however,
|
||||
// that the Context described by this package carries additional constraints
|
||||
// regarding concurrent access and retaining beyond the scope of a call.
|
||||
//
|
||||
// See the Context type for complete details.
|
||||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
// Blocker represents an object with control flow hooks.
|
||||
//
|
||||
// These may be used to perform blocking operations, sleep or otherwise
|
||||
// wait, since there may be asynchronous events that require processing.
|
||||
type Blocker interface {
|
||||
// Interrupt interrupts any Block operations.
|
||||
Interrupt()
|
||||
|
||||
// Interrupted notes whether this context is Interrupted.
|
||||
Interrupted() bool
|
||||
|
||||
// BlockOn blocks until one of the previously registered events occurs,
|
||||
// or some external interrupt (cancellation).
|
||||
//
|
||||
// The return value should indicate whether the wake-up occurred as a
|
||||
// result of the requested event (versus an external interrupt).
|
||||
BlockOn(waiter.Waitable, waiter.EventMask) bool
|
||||
|
||||
// Block blocks until an event is received from C, or some external
|
||||
// interrupt. It returns nil if an event is received from C and an err if t
|
||||
// is interrupted.
|
||||
Block(C <-chan struct{}) error
|
||||
|
||||
// BlockWithTimeoutOn blocks until either the conditions of Block are
|
||||
// satisfied, or the timeout is hit. Note that deadlines are not supported
|
||||
// since the notion of "with respect to what clock" is not resolved.
|
||||
//
|
||||
// The return value is per BlockOn.
|
||||
BlockWithTimeoutOn(waiter.Waitable, waiter.EventMask, time.Duration) (time.Duration, bool)
|
||||
|
||||
// UninterruptibleSleepStart indicates the beginning of an uninterruptible
|
||||
// sleep state (equivalent to Linux's TASK_UNINTERRUPTIBLE). If deactivate
|
||||
// is true and the Context represents a Task, the Task's AddressSpace is
|
||||
// deactivated.
|
||||
UninterruptibleSleepStart(deactivate bool)
|
||||
|
||||
// UninterruptibleSleepFinish indicates the end of an uninterruptible sleep
|
||||
// state that was begun by a previous call to UninterruptibleSleepStart. If
|
||||
// activate is true and the Context represents a Task, the Task's
|
||||
// AddressSpace is activated. Normally activate is the same value as the
|
||||
// deactivate parameter passed to UninterruptibleSleepStart.
|
||||
UninterruptibleSleepFinish(activate bool)
|
||||
}
|
||||
|
||||
// NoTask is an implementation of Blocker that does not block.
|
||||
type NoTask struct {
|
||||
cancel chan struct{}
|
||||
}
|
||||
|
||||
// Interrupt implements Blocker.Interrupt.
|
||||
func (nt *NoTask) Interrupt() {
|
||||
select {
|
||||
case nt.cancel <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupted implements Blocker.Interrupted.
|
||||
func (nt *NoTask) Interrupted() bool {
|
||||
return nt.cancel != nil && len(nt.cancel) > 0
|
||||
}
|
||||
|
||||
// Block implements Blocker.Block.
|
||||
func (nt *NoTask) Block(C <-chan struct{}) error {
|
||||
if nt.cancel == nil {
|
||||
nt.cancel = make(chan struct{}, 1)
|
||||
}
|
||||
select {
|
||||
case <-nt.cancel:
|
||||
return errors.New("interrupted system call") // Interrupted.
|
||||
case <-C:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// BlockOn implements Blocker.BlockOn.
|
||||
func (nt *NoTask) BlockOn(w waiter.Waitable, mask waiter.EventMask) bool {
|
||||
if nt.cancel == nil {
|
||||
nt.cancel = make(chan struct{}, 1)
|
||||
}
|
||||
e, ch := waiter.NewChannelEntry(mask)
|
||||
w.EventRegister(&e)
|
||||
defer w.EventUnregister(&e)
|
||||
select {
|
||||
case <-nt.cancel:
|
||||
return false // Interrupted.
|
||||
case _, ok := <-ch:
|
||||
return ok
|
||||
}
|
||||
}
|
||||
|
||||
// BlockWithTimeoutOn implements Blocker.BlockWithTimeoutOn.
|
||||
func (nt *NoTask) BlockWithTimeoutOn(w waiter.Waitable, mask waiter.EventMask, duration time.Duration) (time.Duration, bool) {
|
||||
if nt.cancel == nil {
|
||||
nt.cancel = make(chan struct{}, 1)
|
||||
}
|
||||
e, ch := waiter.NewChannelEntry(mask)
|
||||
w.EventRegister(&e)
|
||||
defer w.EventUnregister(&e)
|
||||
start := time.Now() // In system time.
|
||||
t := time.AfterFunc(duration, func() { ch <- struct{}{} })
|
||||
select {
|
||||
case <-nt.cancel:
|
||||
return time.Since(start), false // Interrupted.
|
||||
case _, ok := <-ch:
|
||||
if ok && t.Stop() {
|
||||
// Timer never fired.
|
||||
return time.Since(start), ok
|
||||
}
|
||||
// Timer fired, remain is zero.
|
||||
return time.Duration(0), ok
|
||||
}
|
||||
}
|
||||
|
||||
// UninterruptibleSleepStart implmenents Blocker.UninterruptedSleepStart.
|
||||
func (*NoTask) UninterruptibleSleepStart(bool) {}
|
||||
|
||||
// UninterruptibleSleepFinish implmenents Blocker.UninterruptibleSleepFinish.
|
||||
func (*NoTask) UninterruptibleSleepFinish(bool) {}
|
||||
|
||||
// Context represents a thread of execution (hereafter "goroutine" to reflect
|
||||
// Go idiosyncrasy). It carries state associated with the goroutine across API
|
||||
// boundaries.
|
||||
//
|
||||
// While Context exists for essentially the same reasons as Go's standard
|
||||
// context.Context, the standard type represents the state of an operation
|
||||
// rather than that of a goroutine. This is a critical distinction:
|
||||
//
|
||||
// - Unlike context.Context, which "may be passed to functions running in
|
||||
// different goroutines", it is *not safe* to use the same Context in multiple
|
||||
// concurrent goroutines.
|
||||
//
|
||||
// - It is *not safe* to retain a Context passed to a function beyond the scope
|
||||
// of that function call.
|
||||
//
|
||||
// In both cases, values extracted from the Context should be used instead.
|
||||
type Context interface {
|
||||
context.Context
|
||||
log.Logger
|
||||
Blocker
|
||||
}
|
||||
|
||||
// logContext implements basic logging.
|
||||
type logContext struct {
|
||||
NoTask
|
||||
log.Logger
|
||||
context.Context
|
||||
}
|
||||
|
||||
// bgContext is the context returned by context.Background.
|
||||
var bgContext Context
|
||||
var bgOnce sync.Once
|
||||
|
||||
// Background returns an empty context using the default logger.
|
||||
// Generally, one should use the Task as their context when available, or avoid
|
||||
// having to use a context in places where a Task is unavailable.
|
||||
//
|
||||
// Using a Background context for tests is fine, as long as no values are
|
||||
// needed from the context in the tested code paths.
|
||||
//
|
||||
// The global log.SetTarget() must be called before context.Background()
|
||||
func Background() Context {
|
||||
bgOnce.Do(func() {
|
||||
bgContext = &logContext{
|
||||
Context: context.Background(),
|
||||
Logger: log.Log(),
|
||||
}
|
||||
})
|
||||
return bgContext
|
||||
}
|
||||
|
||||
// WithValue returns a copy of parent in which the value associated with key is
|
||||
// val.
|
||||
func WithValue(parent Context, key, val any) Context {
|
||||
return &withValue{
|
||||
Context: parent,
|
||||
key: key,
|
||||
val: val,
|
||||
}
|
||||
}
|
||||
|
||||
type withValue struct {
|
||||
Context
|
||||
key any
|
||||
val any
|
||||
}
|
||||
|
||||
// Value implements Context.Value.
|
||||
func (ctx *withValue) Value(key any) any {
|
||||
if key == ctx.key {
|
||||
return ctx.val
|
||||
}
|
||||
return ctx.Context.Value(key)
|
||||
}
|
||||
3
vendor/gvisor.dev/gvisor/pkg/context/context_state_autogen.go
vendored
Normal file
3
vendor/gvisor.dev/gvisor/pkg/context/context_state_autogen.go
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
// automatically generated by stateify.
|
||||
|
||||
package context
|
||||
Reference in New Issue
Block a user