summaryrefslogtreecommitdiff
path: root/libpod/util.go
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2018-11-28 05:10:49 -0800
committerGitHub <noreply@github.com>2018-11-28 05:10:49 -0800
commit2a496aea30da4bbe4981753c11ed095867202466 (patch)
treefb8f12d6c5a2fffb15b6d25e34843a0440f1123b /libpod/util.go
parenta7df0bc1fa5811481d0b52342a3a71005c361329 (diff)
parentfc3047322a527347072ce98ba183cbc8cb49231d (diff)
downloadpodman-2a496aea30da4bbe4981753c11ed095867202466.tar.gz
podman-2a496aea30da4bbe4981753c11ed095867202466.tar.bz2
podman-2a496aea30da4bbe4981753c11ed095867202466.zip
Merge pull request #1833 from giuseppe/remove-exec-polling
exec: remove polling for PID file
Diffstat (limited to 'libpod/util.go')
-rw-r--r--libpod/util.go44
1 files changed, 39 insertions, 5 deletions
diff --git a/libpod/util.go b/libpod/util.go
index 7007b29cd..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"
)
@@ -90,31 +91,64 @@ func MountExists(specMounts []spec.Mount, dest string) bool {
}
// WaitForFile waits until a file has been created or the given timeout has occurred
-func WaitForFile(path string, timeout time.Duration) error {
+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)
}
}
}()
select {
+ case e := <-chWait:
+ return true, e
case <-done:
- return nil
+ return false, nil
case <-time.After(timeout):
close(chControl)
- return errors.Wrapf(ErrInternal, "timed out waiting for file %s", path)
+ return false, errors.Wrapf(ErrInternal, "timed out waiting for file %s", path)
}
}