diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2018-11-28 05:10:49 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-28 05:10:49 -0800 |
commit | 2a496aea30da4bbe4981753c11ed095867202466 (patch) | |
tree | fb8f12d6c5a2fffb15b6d25e34843a0440f1123b /libpod/util.go | |
parent | a7df0bc1fa5811481d0b52342a3a71005c361329 (diff) | |
parent | fc3047322a527347072ce98ba183cbc8cb49231d (diff) | |
download | podman-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.go | 44 |
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) } } |