2 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "ready_checker.hh"
21 #include "utils/logging.hh"
23 #include "pkgmgrinfo_debug.h"
26 #define LOG_TAG "PKGMGR_INFO"
28 namespace pkgmgr_common {
30 gboolean ReadyChecker::OnReceiveEvent(GIOChannel* channel, GIOCondition cond,
32 char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event))));
35 struct inotify_event* event;
36 auto ready_checker = reinterpret_cast<ReadyChecker*>(user_data);
37 int fd = g_io_channel_unix_get_fd(channel);
39 while ((len = read(fd, buf, sizeof(buf))) > 0) {
40 for (ptr = buf; ptr < buf + len;
41 ptr += sizeof(struct inotify_event) + event->len) {
42 event = reinterpret_cast<struct inotify_event*>(ptr);
43 char* nptr = ptr + sizeof(struct inotify_event) + event->len;
50 if (!(event->mask & IN_CREATE) ||
51 ready_checker->ready_file_ != event->name)
54 LOG(INFO) << "server is ready : " << ready_checker->ready_file_;
55 ready_checker->ready_ = true;
56 ready_checker->Dispose();
57 return G_SOURCE_CONTINUE;
61 return G_SOURCE_CONTINUE;
64 ReadyChecker::ReadyChecker(const std::string& ready_path) {
65 if (access(ready_path.c_str(), F_OK) == 0) {
71 auto it = ready_path.find_last_of("/");
72 if (it == ready_path.npos) {
73 LOG(ERROR) << "Invalid path: " << ready_path;
78 fd_ = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
80 LOG(ERROR) << "Failed to inotify_init. errno: " << errno;
85 ready_path_ = ready_path.substr(0, it);
86 ready_file_ = ready_path.substr(it + 1);
87 wd_ = inotify_add_watch(fd_, ready_path_.c_str(), IN_CREATE);
89 LOG(ERROR) << "Failed to inotify_add_watch. errno: " << errno;
94 channel_ = g_io_channel_unix_new(fd_);
95 if (channel_ == nullptr) {
96 LOG(ERROR) << "Failed to create GIO channel";
101 tag_ = g_io_add_watch(channel_, G_IO_IN, OnReceiveEvent, this);
103 LOG(ERROR) << "Failed to add watch";
111 ReadyChecker::~ReadyChecker() {
115 bool ReadyChecker::IsReady() const {
119 void ReadyChecker::Dispose() {
124 g_source_remove(tag_);
128 if (channel_ != nullptr) {
129 g_io_channel_unref(channel_);
134 inotify_rm_watch(fd_, wd_);
146 } // namespace pkgmgr_common