summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2018-11-20 11:19:40 +0100
committerGiuseppe Scrivano <gscrivan@redhat.com>2018-11-28 10:53:41 +0100
commitfc3047322a527347072ce98ba183cbc8cb49231d (patch)
tree8facef6cb16261b8aee1d9d2330f18800c9edda3
parent070ce0c85570b79a3612ad1fdf15b5c1287b00b6 (diff)
downloadpodman-fc3047322a527347072ce98ba183cbc8cb49231d.tar.gz
podman-fc3047322a527347072ce98ba183cbc8cb49231d.tar.bz2
podman-fc3047322a527347072ce98ba183cbc8cb49231d.zip
util: use fsnotify to wait for file
prefer a fsnotify watcher to polling the file, we take advantage of inotify on Linux and react more promptly to the PID file being created. If the watcher cannot be created, then fallback to the old polling mechanism. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
-rw-r--r--libpod/util.go36
1 files changed, 34 insertions, 2 deletions
diff --git a/libpod/util.go b/libpod/util.go
index 25e78bd01..aa3494529 100644
--- a/libpod/util.go
+++ b/libpod/util.go
@@ -13,6 +13,7 @@ import (
"github.com/containers/image/signature"
"github.com/containers/image/types"
"github.com/containers/libpod/pkg/util"
+ "github.com/fsnotify/fsnotify"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@@ -93,18 +94,49 @@ func MountExists(specMounts []spec.Mount, dest string) bool {
func WaitForFile(path string, chWait chan error, timeout time.Duration) (bool, error) {
done := make(chan struct{})
chControl := make(chan struct{})
+
+ var inotifyEvents chan fsnotify.Event
+ var timer chan struct{}
+ watcher, err := fsnotify.NewWatcher()
+ if err == nil {
+ if err := watcher.Add(filepath.Dir(path)); err == nil {
+ inotifyEvents = watcher.Events
+ }
+ defer watcher.Close()
+ }
+ if inotifyEvents == nil {
+ // If for any reason we fail to create the inotify
+ // watcher, fallback to polling the file
+ timer = make(chan struct{})
+ go func() {
+ select {
+ case <-chControl:
+ close(timer)
+ return
+ default:
+ time.Sleep(25 * time.Millisecond)
+ timer <- struct{}{}
+ }
+ }()
+ }
+
go func() {
for {
select {
case <-chControl:
return
- default:
+ case <-timer:
+ _, err := os.Stat(path)
+ if err == nil {
+ close(done)
+ return
+ }
+ case <-inotifyEvents:
_, err := os.Stat(path)
if err == nil {
close(done)
return
}
- time.Sleep(25 * time.Millisecond)
}
}
}()