summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/fs')
-rw-r--r--pkg/sentry/fs/fs.go12
-rw-r--r--pkg/sentry/fs/gofer/inode.go7
2 files changed, 16 insertions, 3 deletions
diff --git a/pkg/sentry/fs/fs.go b/pkg/sentry/fs/fs.go
index 0ba4b7269..36f263235 100644
--- a/pkg/sentry/fs/fs.go
+++ b/pkg/sentry/fs/fs.go
@@ -57,6 +57,7 @@ import (
"sync"
"gvisor.googlesource.com/gvisor/pkg/log"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/context"
)
var (
@@ -87,6 +88,17 @@ func Async(f func()) {
}()
}
+// AsyncWithContext is just like Async, except that it calls the asynchronous
+// function with the given context as argument. This function exists to avoid
+// needing to allocate an extra function on the heap in a hot path.
+func AsyncWithContext(ctx context.Context, f func(context.Context)) {
+ workMu.RLock()
+ go func() { // S/R-SAFE: AsyncBarrier must be called.
+ defer workMu.RUnlock() // Ensure RUnlock in case of panic.
+ f(ctx)
+ }()
+}
+
// AsyncErrorBarrier waits for all outstanding asynchronous work to complete, or
// the first async error to arrive. Other unfinished async executions will
// continue in the background. Other past and future async errors are ignored.
diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go
index 16435169a..83fff7517 100644
--- a/pkg/sentry/fs/gofer/inode.go
+++ b/pkg/sentry/fs/gofer/inode.go
@@ -352,9 +352,10 @@ func (i *inodeOperations) Release(ctx context.Context) {
// Releasing the fileState may make RPCs to the gofer. There is
// no need to wait for those to return, so we can do this
// asynchronously.
- fs.Async(func() {
- i.fileState.Release(ctx)
- })
+ //
+ // We use AsyncWithContext to avoid needing to allocate an extra
+ // anonymous function on the heap.
+ fs.AsyncWithContext(ctx, i.fileState.Release)
}
// Mappable implements fs.InodeOperations.Mappable.