Change to set thread number (#153)
[platform/core/appfw/pkgmgr-info.git] / src / server / runner.cc
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <glib-unix.h>
18 #include <vconf.h>
19
20 #include <string>
21
22 #include "pkg_request.hh"
23 #include "runner.hh"
24 #include "pkgmgrinfo_debug.h"
25 #include "pkgmgrinfo_private.h"
26
27 #ifdef LOG_TAG
28 #undef LOG_TAG
29 #endif
30 #define LOG_TAG "PKGMGR_INFO"
31
32 namespace pkgmgr_server {
33
34 static const std::string SOCK_PATH = "/run/pkgmgr-info-server";
35
36 Runner::Runner(int thread_num) : sid_(-1) {
37   if (thread_num > std::thread::hardware_concurrency())
38     thread_num_ = std::thread::hardware_concurrency();
39   else
40     thread_num_ = thread_num;
41
42   server_ = std::make_unique<pkgmgr_common::socket::ServerSocket>(SOCK_PATH);
43   thread_pool_ = std::make_unique<WorkerThread>(thread_num_);
44   sid_ = g_unix_fd_add(server_->GetFd(), G_IO_IN, OnReceiveRequest, this);
45   vconf_notify_key_changed(VCONFKEY_LANGSET, OnLanguageChange, this);
46   std::unique_ptr<char, decltype(std::free)*> locale(
47       _get_system_locale(), std::free);
48   if (locale.get() == nullptr)
49     return;
50
51   thread_pool_->SetLocale(locale.get());
52   LOGI("Start Runner");
53 }
54
55 Runner::~Runner() {
56   g_source_remove(sid_);
57   vconf_ignore_key_changed(VCONFKEY_LANGSET, OnLanguageChange);
58 }
59
60 int Runner::FdErrorHandler(int fd, GIOCondition cond, void* user_data) {
61   auto runner = static_cast<Runner*>(user_data);
62   if (static_cast<int>(cond) & (G_IO_ERR | G_IO_HUP)) {
63     auto it = runner->sid_map_.find(fd);
64     if (it != runner->sid_map_.end()) {
65       LOGW("Socket disconnect. fd(%d) condition(%d)", fd, static_cast<int>(cond));
66       g_source_remove(it->second);
67       runner->sid_map_.erase(it);
68     }
69     close(fd);
70   }
71
72   return G_SOURCE_CONTINUE;
73 }
74
75 int Runner::OnReceiveRequest(int fd, GIOCondition cond, void* user_data) {
76   auto runner = static_cast<Runner*>(user_data);
77   int client_fd = runner->server_->Accept();
78   if (client_fd < 0) {
79     LOGE("Failed to Accept. (%d)", client_fd);
80     return G_SOURCE_CONTINUE;
81   }
82
83   auto condition = static_cast<GIOCondition>(G_IO_ERR | G_IO_HUP);
84   int sid = g_unix_fd_add(client_fd, condition, FdErrorHandler, runner);
85   runner->sid_map_[client_fd] = sid;
86   runner->QueueRequest(client_fd);
87   return G_SOURCE_CONTINUE;
88 }
89
90 void Runner::OnLanguageChange(keynode_t* key, void* user_data) {
91   auto runner = static_cast<Runner*>(user_data);
92   std::unique_ptr<char, decltype(std::free)*> locale(
93       _get_system_locale(), std::free);
94   if (locale.get() == nullptr)
95     return;
96
97   runner->thread_pool_->SetLocale(locale.get());
98 }
99
100 bool Runner::QueueRequest(int client_fd) {
101   auto req = std::make_shared<PkgRequest>(client_fd);
102   thread_pool_->PushQueue(req);
103   return true;
104 }
105
106 }  // namespace pkgmgr_server