summaryrefslogtreecommitdiffhomepage
path: root/pkg/context
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-09-15 22:17:56 +0000
committergVisor bot <gvisor-bot@google.com>2020-09-15 22:17:56 +0000
commit86a49b5de9dda0c050584bbaa408be1b68b1fd55 (patch)
tree6c179ca0f16be32639c09f85bf4c135e9b8efcc5 /pkg/context
parent0c8d10699e1bf4f4f1e6f9fb7fdd4ec1a961daf3 (diff)
parent456c6c33e104e7421a5a815bba69d46b289ae724 (diff)
Merge release-20200907.0-52-g456c6c33e (automated)
Diffstat (limited to 'pkg/context')
-rw-r--r--pkg/context/context.go57
1 files changed, 44 insertions, 13 deletions
diff --git a/pkg/context/context.go b/pkg/context/context.go
index 5319b6d8d..2613bc752 100644
--- a/pkg/context/context.go
+++ b/pkg/context/context.go
@@ -26,7 +26,6 @@ import (
"context"
"time"
- "gvisor.dev/gvisor/pkg/amutex"
"gvisor.dev/gvisor/pkg/log"
)
@@ -68,9 +67,10 @@ func ThreadGroupIDFromContext(ctx Context) (tgid int32, ok bool) {
// In both cases, values extracted from the Context should be used instead.
type Context interface {
log.Logger
- amutex.Sleeper
context.Context
+ ChannelSleeper
+
// 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
@@ -85,29 +85,60 @@ type Context interface {
UninterruptibleSleepFinish(activate bool)
}
-// NoopSleeper is a noop implementation of amutex.Sleeper and UninterruptibleSleep
-// methods for anonymous embedding in other types that do not implement sleeps.
-type NoopSleeper struct {
- amutex.NoopSleeper
+// A ChannelSleeper represents a goroutine that may sleep interruptibly, where
+// interruption is indicated by a channel becoming readable.
+type ChannelSleeper interface {
+ // SleepStart is called before going to sleep interruptibly. If SleepStart
+ // returns a non-nil channel and that channel becomes ready for receiving
+ // while the goroutine is sleeping, the goroutine should be woken, and
+ // SleepFinish(false) should be called. Otherwise, SleepFinish(true) should
+ // be called after the goroutine stops sleeping.
+ SleepStart() <-chan struct{}
+
+ // SleepFinish is called after an interruptibly-sleeping goroutine stops
+ // sleeping, as documented by SleepStart.
+ SleepFinish(success bool)
+
+ // Interrupted returns true if the channel returned by SleepStart is
+ // ready for receiving.
+ Interrupted() bool
+}
+
+// NoopSleeper is a noop implementation of ChannelSleeper and
+// Context.UninterruptibleSleep* methods for anonymous embedding in other types
+// that do not implement special behavior around sleeps.
+type NoopSleeper struct{}
+
+// SleepStart implements ChannelSleeper.SleepStart.
+func (NoopSleeper) SleepStart() <-chan struct{} {
+ return nil
+}
+
+// SleepFinish implements ChannelSleeper.SleepFinish.
+func (NoopSleeper) SleepFinish(success bool) {}
+
+// Interrupted implements ChannelSleeper.Interrupted.
+func (NoopSleeper) Interrupted() bool {
+ return false
}
-// UninterruptibleSleepStart does nothing.
-func (NoopSleeper) UninterruptibleSleepStart(bool) {}
+// UninterruptibleSleepStart implements Context.UninterruptibleSleepStart.
+func (NoopSleeper) UninterruptibleSleepStart(deactivate bool) {}
-// UninterruptibleSleepFinish does nothing.
-func (NoopSleeper) UninterruptibleSleepFinish(bool) {}
+// UninterruptibleSleepFinish implements Context.UninterruptibleSleepFinish.
+func (NoopSleeper) UninterruptibleSleepFinish(activate bool) {}
-// Deadline returns zero values, meaning no deadline.
+// Deadline implements context.Context.Deadline.
func (NoopSleeper) Deadline() (time.Time, bool) {
return time.Time{}, false
}
-// Done returns nil.
+// Done implements context.Context.Done.
func (NoopSleeper) Done() <-chan struct{} {
return nil
}
-// Err returns nil.
+// Err returns context.Context.Err.
func (NoopSleeper) Err() error {
return nil
}