#include "ready_checker.hh"
-#include <utility>
+#include <unistd.h>
#include "utils/logging.hh"
-#include "pkgmgrinfo_debug.h"
-
#undef LOG_TAG
#define LOG_TAG "PKGMGR_INFO"
namespace pkgmgr_common {
-gboolean ReadyChecker::OnReceiveEvent(GIOChannel* channel, GIOCondition cond,
- gpointer user_data) {
- char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event))));
- char* ptr;
- ssize_t len;
- struct inotify_event* event;
- auto ready_checker = reinterpret_cast<ReadyChecker*>(user_data);
- int fd = g_io_channel_unix_get_fd(channel);
-
- while ((len = read(fd, buf, sizeof(buf))) > 0) {
- for (ptr = buf; ptr < buf + len;
- ptr += sizeof(struct inotify_event) + event->len) {
- event = reinterpret_cast<struct inotify_event*>(ptr);
- char* nptr = ptr + sizeof(struct inotify_event) + event->len;
- if (nptr > buf + len)
- break;
-
- if (!event->len)
- continue;
-
- if (!(event->mask & IN_CREATE) ||
- ready_checker->ready_file_ != event->name)
- continue;
-
- LOG(INFO) << "server is ready : " << ready_checker->ready_file_;
- ready_checker->ready_ = true;
- ready_checker->Dispose();
- return G_SOURCE_CONTINUE;
- }
- }
-
- return G_SOURCE_CONTINUE;
-}
-
-ReadyChecker::ReadyChecker(const std::string& ready_path) {
- if (access(ready_path.c_str(), F_OK) == 0) {
- ready_ = true;
- disposed_ = true;
- return;
- }
-
- auto it = ready_path.find_last_of("/");
- if (it == ready_path.npos) {
- LOG(ERROR) << "Invalid path: " << ready_path;
- disposed_ = true;
- return;
- }
-
- fd_ = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
- if (fd_ == -1) {
- LOG(ERROR) << "Failed to inotify_init. errno: " << errno;
- disposed_ = true;
- return;
- }
-
- ready_path_ = ready_path.substr(0, it);
- ready_file_ = ready_path.substr(it + 1);
- wd_ = inotify_add_watch(fd_, ready_path_.c_str(), IN_CREATE);
- if (wd_ == -1) {
- LOG(ERROR) << "Failed to inotify_add_watch. errno: " << errno;
- Dispose();
- return;
- }
-
- channel_ = g_io_channel_unix_new(fd_);
- if (channel_ == nullptr) {
- LOG(ERROR) << "Failed to create GIO channel";
- Dispose();
- return;
- }
-
- tag_ = g_io_add_watch(channel_, G_IO_IN, OnReceiveEvent, this);
- if (tag_ == 0) {
- LOG(ERROR) << "Failed to add watch";
- Dispose();
- return;
- }
-
- disposed_ = false;
-}
-
-ReadyChecker::~ReadyChecker() {
- Dispose();
+ReadyChecker::ReadyChecker(const std::string& ready_path)
+ : ready_path_(ready_path) {
+ Check();
}
bool ReadyChecker::IsReady() const {
- return ready_;
+ return ready_.load();
}
-void ReadyChecker::Dispose() {
- if (disposed_)
- return;
-
- if (tag_) {
- g_source_remove(tag_);
- tag_ = 0;
- }
-
- if (channel_ != nullptr) {
- g_io_channel_unref(channel_);
- channel_ = nullptr;
- }
-
- if (wd_ > 0) {
- inotify_rm_watch(fd_, wd_);
- wd_ = 0;
- }
-
- if (fd_ > 0) {
- close(fd_);
- fd_ = 0;
+bool ReadyChecker::Check() {
+ if (access(ready_path_.c_str(), F_OK) == 0) {
+ ready_.store(true);
+ return true;
}
- disposed_ = true;
+ return false;
}
} // namespace pkgmgr_common
* limitations under the License.
*/
-#include <gio/gio.h>
-#include <glib.h>
-#include <sys/inotify.h>
-
#include <string>
+#include <atomic>
#ifndef READY_CHECKER_HH_
#define READY_CHECKER_HH_
class EXPORT_API ReadyChecker {
public:
explicit ReadyChecker(const std::string& ready_path);
- ~ReadyChecker();
ReadyChecker(const ReadyChecker&) = delete;
ReadyChecker& operator = (const ReadyChecker&) = delete;
bool IsReady() const;
+ bool Check();
private:
std::string ready_path_;
- std::string ready_file_;
- int fd_ = 0;
- int wd_ = 0;
- GIOChannel* channel_ = nullptr;
- int tag_ = 0;
- bool ready_ = false;
- bool disposed_ = false;
-
- void Dispose();
- static gboolean OnReceiveEvent(GIOChannel* channel, GIOCondition cond,
- gpointer user_data);
+ std::atomic<bool> ready_ = false;
};
} // namespace pkgmgr_common