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 "pkgmgrinfo_debug.h"
24 #define LOG_TAG "PKGMGR_INFO"
26 namespace pkgmgr_common {
28 gboolean ReadyChecker::OnReceiveEvent(GIOChannel* channel, GIOCondition cond,
30 char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event))));
33 struct inotify_event* event;
34 auto ready_checker = reinterpret_cast<ReadyChecker*>(user_data);
35 int fd = g_io_channel_unix_get_fd(channel);
36 while ((len = read(fd, buf, sizeof(buf))) > 0) {
37 for (ptr = buf; ptr < buf + len;
38 ptr += sizeof(struct inotify_event) + event->len) {
39 event = reinterpret_cast<struct inotify_event*>(ptr);
40 char* nptr = ptr + sizeof(struct inotify_event) + event->len;
45 if (event->mask & IN_CREATE &&
46 ready_checker->ready_file_ == event->name) {
47 _LOGI("server is ready (%s)", ready_checker->ready_file_.c_str());
48 ready_checker->ready_ = true;
49 ready_checker->Dispose();
50 return G_SOURCE_CONTINUE;
56 return G_SOURCE_CONTINUE;
59 ReadyChecker::ReadyChecker(const std::string& ready_path) {
60 if (access(ready_path.c_str(), F_OK) == 0) {
65 auto it = ready_path.find_last_of("/");
66 if (it == ready_path.npos) {
67 _LOGE("Invalid path %s", ready_path.c_str());
72 fd_ = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
74 _LOGE("Failed to inotify_init. errno(%d)", errno);
78 ready_path_ = ready_path.substr(0, it);
79 ready_file_ = ready_path.substr(it + 1);
80 wd_ = inotify_add_watch(fd_, ready_path_.c_str(), IN_CREATE);
82 _LOGE("Failed to inotify_add_watch. errno(%d)", errno);
87 channel_ = g_io_channel_unix_new(fd_);
88 if (channel_ == nullptr) {
89 _LOGE("Failed to create GIO channel");
93 tag_ = g_io_add_watch(channel_, G_IO_IN, OnReceiveEvent, this);
95 _LOGE("Failed to add watch");
103 ReadyChecker::~ReadyChecker() {
107 bool ReadyChecker::IsReady() const {
111 void ReadyChecker::Dispose() {
116 g_source_remove(tag_);
120 if (channel_ != nullptr) {
121 g_io_channel_unref(channel_);
126 inotify_rm_watch(fd_, wd_);
138 } // namespace pkgmgr_common