From: Jan Olszak Date: Thu, 29 Oct 2015 11:48:30 +0000 (+0100) Subject: common: waitForFile using Inotify X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ea2a295ee78974e14b81f7d0e044f10e890fe64c;p=platform%2Fcore%2Fsecurity%2Fvasum.git common: waitForFile using Inotify [Feature] Changed the implementation of waitForFile to use the Inotify class [Cause] Inotify verification [Solution] N/A [Verification] Build, install, run tests Change-Id: I5fe10f38e9ebdf1f0dde02eb6a63bdbb4c1548fd --- diff --git a/common/utils/file-wait.cpp b/common/utils/file-wait.cpp index b1d9a4f..4386473 100644 --- a/common/utils/file-wait.cpp +++ b/common/utils/file-wait.cpp @@ -23,34 +23,54 @@ */ #include "config.hpp" -#include "utils/exception.hpp" + #include "utils/file-wait.hpp" +#include "utils/exception.hpp" +#include "utils/inotify.hpp" +#include "utils/paths.hpp" +#include "utils/fs.hpp" + +#include "ipc/epoll/event-poll.hpp" #include #include #include +#include +#include +#include "logger/logger.hpp" namespace utils { +void waitForFile(const std::string& file, const unsigned int timeoutMs) +{ + std::string dir = dirName(file); + assertIsDir(dir); -const unsigned int GRANULARITY = 100; + ipc::epoll::EventPoll poll; + Inotify inotify(poll); -void waitForFile(const std::string& filename, const unsigned int timeoutMs) -{ - //TODO this is a temporary solution, use inotify instead of sleep - struct stat s; - unsigned int loops = 0; - while (stat(filename.c_str(), &s) == -1) { - if (errno != ENOENT) { - throw UtilsException("file access error: " + filename); - } - ++ loops; - if (loops * GRANULARITY > timeoutMs) { - throw UtilsException("timeout on waiting for: " + filename); + std::string filename = file.substr(dir.size() + 1); + bool isWaiting = true; + inotify.setHandler(dir, IN_CREATE | IN_ISDIR, [&isWaiting, &filename](const std::string& name, uint32_t) { + if (name == filename) { + isWaiting = false; + + // There's a race between inotify event and filesystem update. + ::sync(); } - usleep(GRANULARITY * 1000); + }); + + auto deadline = std::chrono::steady_clock::now() + + std::chrono::milliseconds(timeoutMs); + + while (isWaiting && std::chrono::steady_clock::now() < deadline ) { + auto duration = deadline - std::chrono::steady_clock::now(); + poll.dispatchIteration(std::chrono::duration_cast(duration).count()); } -} + if(isWaiting) { + throw UtilsException("No such file: " + file); + } +} } // namespace utils