summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/fs.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/fs/fs.go')
-rw-r--r--pkg/sentry/fs/fs.go24
1 files changed, 14 insertions, 10 deletions
diff --git a/pkg/sentry/fs/fs.go b/pkg/sentry/fs/fs.go
index b5c72990e..0ba4b7269 100644
--- a/pkg/sentry/fs/fs.go
+++ b/pkg/sentry/fs/fs.go
@@ -44,7 +44,7 @@
// DirentCache.mu
// Locks in InodeOperations implementations or overlayEntry
// Inode.Watches.mu (see `Inotify` for other lock ordering)
-// MountSource.mu
+// MountSource.mu
//
// If multiple Dirent or MountSource locks must be taken, locks in the parent must be
// taken before locks in their children.
@@ -60,10 +60,11 @@ import (
)
var (
- // work is a sync.WaitGroup that can be used to queue asynchronous
- // operations via Do. Callers can use Barrier to ensure no operations
- // are outstanding.
- work sync.WaitGroup
+ // workMu is used to synchronize pending asynchronous work. Async work
+ // runs with the lock held for reading. AsyncBarrier will take the lock
+ // for writing, thus ensuring that all Async work completes before
+ // AsyncBarrier returns.
+ workMu sync.RWMutex
// asyncError is used to store up to one asynchronous execution error.
asyncError = make(chan error, 1)
@@ -71,14 +72,17 @@ var (
// AsyncBarrier waits for all outstanding asynchronous work to complete.
func AsyncBarrier() {
- work.Wait()
+ workMu.Lock()
+ workMu.Unlock()
}
// Async executes a function asynchronously.
+//
+// Async must not be called recursively.
func Async(f func()) {
- work.Add(1)
- go func() { // S/R-SAFE: Barrier must be called.
- defer work.Done() // Ensure Done in case of panic.
+ workMu.RLock()
+ go func() { // S/R-SAFE: AsyncBarrier must be called.
+ defer workMu.RUnlock() // Ensure RUnlock in case of panic.
f()
}()
}
@@ -89,7 +93,7 @@ func Async(f func()) {
func AsyncErrorBarrier() error {
wait := make(chan struct{}, 1)
go func() { // S/R-SAFE: Does not touch persistent state.
- work.Wait()
+ AsyncBarrier()
wait <- struct{}{}
}()
select {