2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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.
20 #include "log-private.hh"
26 Logger::Logger(int pid, int fd, IEvent* listener)
27 : pid_(pid), fd_(fd), listener_(listener) {
28 thread_ = std::thread([&]() {
29 GMainContext* context = g_main_context_new();
30 GIOChannel* io = g_io_channel_unix_new(fd_);
31 GIOCondition cond = static_cast<GIOCondition>(
32 G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_ERR | G_IO_NVAL);
33 GSource* source = g_io_create_watch(io, cond);
34 g_source_set_callback(source, (GSourceFunc)OnDataReceivedCb, this,
36 g_source_set_priority(source, G_PRIORITY_DEFAULT);
37 g_source_attach(source, context);
38 g_source_unref(source);
40 loop_ = g_main_loop_new(context, FALSE);
41 g_main_context_push_thread_default(context);
43 g_main_loop_run(loop_);
45 if (!g_source_is_destroyed(source))
46 g_source_destroy(source);
48 g_io_channel_unref(io);
50 g_main_context_pop_thread_default(context);
51 g_main_loop_unref(loop_);
52 g_main_context_unref(context);
57 if (g_main_loop_is_running(loop_))
58 g_main_loop_quit(loop_);
66 int Logger::GetPid() {
74 int Logger::Read(void* buf, unsigned int size) {
75 char* buffer = static_cast<char*>(buf);
76 unsigned int left = size;
78 ssize_t read_size = read(fd_, buffer, left);
80 _E("Failed to read data. fd(%d), errno(%d)", fd_, errno);
90 rpc_port_parcel_h Logger::Read()
93 int ret = Read(reinterpret_cast<void*>(&size), sizeof(size));
97 auto* buf = new unsigned char[size];
98 ret = Read(static_cast<void*>(buf), size);
104 rpc_port_parcel_h parcel = nullptr;
105 rpc_port_parcel_create(&parcel);
106 rpc_port_parcel_burst_write(parcel, buf, size);
111 gboolean Logger::OnDataReceivedCb(GIOChannel* io,
112 GIOCondition cond, gpointer data) {
113 auto* logger = static_cast<Logger*>(data);
114 auto* listener = logger->listener_;
115 int fd = g_io_channel_unix_get_fd(io);
116 int pid = logger->pid_;
118 if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
119 _E("Error(%d), fd(%d)", cond, fd);
120 listener->OnDisconnected(pid, fd);
121 return G_SOURCE_REMOVE;
124 rpc_port_parcel_h parcel = logger->Read();
125 listener->OnDataReceived(pid, parcel);
126 rpc_port_parcel_destroy(parcel);
127 return G_SOURCE_CONTINUE;
131 } // namespace rpc_port