Refactor launchpad to c++ 03/287603/4
authorChanggyu Choi <changyu.choi@samsung.com>
Wed, 1 Feb 2023 07:05:39 +0000 (16:05 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Mon, 6 Feb 2023 09:09:35 +0000 (18:09 +0900)
We will refactor launchpad to c++ step by step.

Changes:
 - debugger_info
 - launcher_info
 - loader_info

Change-Id: I973d98b0669c4b752ba6cf7203f83e8c83085dc0
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
40 files changed:
CMakeLists.txt
src/launchpad-process-pool/CMakeLists.txt
src/launchpad-process-pool/inc/debugger_info.h [deleted file]
src/launchpad-process-pool/inc/debugger_info.hh [new file with mode: 0644]
src/launchpad-process-pool/inc/launcher_info.hh [new file with mode: 0644]
src/launchpad-process-pool/inc/launchpad_config.h
src/launchpad-process-pool/inc/launchpad_debug.h
src/launchpad-process-pool/inc/launchpad_inotify.h
src/launchpad-process-pool/inc/launchpad_io_channel.h
src/launchpad-process-pool/inc/loader_info.h [deleted file]
src/launchpad-process-pool/inc/loader_info.hh [new file with mode: 0644]
src/launchpad-process-pool/inc/util.hh [new file with mode: 0644]
src/launchpad-process-pool/src/debugger_info.c [deleted file]
src/launchpad-process-pool/src/debugger_info.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launcher_info.c [deleted file]
src/launchpad-process-pool/src/launcher_info.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launchpad.c [deleted file]
src/launchpad-process-pool/src/launchpad.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launchpad_config.cc [moved from src/launchpad-process-pool/src/launchpad_config.c with 99% similarity]
src/launchpad-process-pool/src/launchpad_dbus.c [deleted file]
src/launchpad-process-pool/src/launchpad_dbus.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launchpad_debug.c [deleted file]
src/launchpad-process-pool/src/launchpad_debug.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launchpad_inotify.c [deleted file]
src/launchpad-process-pool/src/launchpad_inotify.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launchpad_io_channel.c [deleted file]
src/launchpad-process-pool/src/launchpad_io_channel.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launchpad_log.cc [moved from src/launchpad-process-pool/src/launchpad_log.c with 52% similarity]
src/launchpad-process-pool/src/launchpad_logger.c [deleted file]
src/launchpad-process-pool/src/launchpad_logger.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launchpad_memory_monitor.c [deleted file]
src/launchpad-process-pool/src/launchpad_memory_monitor.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launchpad_signal.c [deleted file]
src/launchpad-process-pool/src/launchpad_signal.cc [new file with mode: 0644]
src/launchpad-process-pool/src/launchpad_worker.c [deleted file]
src/launchpad-process-pool/src/launchpad_worker.cc [new file with mode: 0644]
src/launchpad-process-pool/src/loader_info.c [deleted file]
src/launchpad-process-pool/src/loader_info.cc [new file with mode: 0644]
src/launchpad-process-pool/src/util.cc [moved from src/launchpad-process-pool/inc/launcher_info.h with 52% similarity]
src/lib/common/inc/launchpad_plugin.h

index 1708bfa..7c79e5f 100644 (file)
@@ -26,7 +26,7 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FILE_OFFSET_BITS=64")
 SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
 SET(CMAKE_C_FLAGS_RELEASE "-O2")
 
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_C_FLAGS} -std=c++14")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_C_FLAGS} -std=c++17")
 SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
 SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
 
index b0af4fe..3175dac 100644 (file)
@@ -2,6 +2,7 @@ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src
   LAUNCHPAD_PROCESS_POOL_SRCS)
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../lib/common/src
   LIB_COMMON_SRCS)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/inc)
 
 ADD_EXECUTABLE(${TARGET_LAUNCHPAD_PROCESS_POOL}
   ${LAUNCHPAD_PROCESS_POOL_SRCS}
diff --git a/src/launchpad-process-pool/inc/debugger_info.h b/src/launchpad-process-pool/inc/debugger_info.h
deleted file mode 100644 (file)
index ecaae3a..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __DEBUGGER_INFO_H__
-#define __DEBUGGER_INFO_H__
-
-#include <glib.h>
-
-typedef struct debugger_info_s *debugger_info_h;
-
-GList *_debugger_info_load(const char *path);
-void _debugger_info_unload(GList *info);
-debugger_info_h _debugger_info_find(GList *info_list, const char *name);
-const char *_debugger_info_get_exe(debugger_info_h info);
-GList *_debugger_info_get_extra_key_list(debugger_info_h info);
-GList *_debugger_info_get_extra_env_list(debugger_info_h info);
-GList *_debugger_info_get_unlink_list(debugger_info_h info);
-const char *_debugger_info_get_attach(debugger_info_h info);
-GList *_debugger_info_get_last_extra_key_list(debugger_info_h info);
-GList *_debugger_info_get_default_opt_list(debugger_info_h info);
-
-#endif /* __DEBUGGER_INFO_H__ */
diff --git a/src/launchpad-process-pool/inc/debugger_info.hh b/src/launchpad-process-pool/inc/debugger_info.hh
new file mode 100644 (file)
index 0000000..83a578d
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DEBUGGER_INFO_HH_
+#define DEBUGGER_INFO_HH_
+
+#include <filesystem>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace launchpad {
+
+class DebuggerInfo {
+ public:
+  const std::string& GetName() const;
+  const std::string& GetExe() const;
+  const std::vector<std::string>& GetAppTypes() const;
+  const std::vector<std::string>& GetExtraKeyList() const;
+  const std::vector<std::string>& GetExtraEnvList() const;
+  const std::vector<std::string>& GetUnlinkList() const;
+  const std::string& GetAttachInfo() const;
+  const std::vector<std::string>& GetLastExtraKeyList() const;
+  const std::vector<std::string>& GetDefaultOptList() const;
+
+ private:
+  std::string name_;
+  std::string exe_;
+  std::vector<std::string> app_types_;
+  std::vector<std::string> extra_key_list_;
+  std::vector<std::string> extra_env_list_;
+  std::vector<std::string> unlink_list_;
+  std::string attach_;
+  std::vector<std::string> last_extra_key_list_;
+  std::vector<std::string> default_opt_list_;
+
+  friend class DebuggerInfoInflator;
+};
+
+using DebuggerInfoPtr = std::shared_ptr<DebuggerInfo>;
+
+class DebuggerInfoInflator {
+ public:
+  std::vector<DebuggerInfoPtr> Inflate(const std::string_view path);
+ private:
+  void Parse(std::vector<DebuggerInfoPtr>& debugger_info_list,
+             const std::filesystem::path& path);
+};
+
+}  // namespace launchpad
+
+#endif  // DEBUGGER_INFO_HH_
diff --git a/src/launchpad-process-pool/inc/launcher_info.hh b/src/launchpad-process-pool/inc/launcher_info.hh
new file mode 100644 (file)
index 0000000..0a7c178
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LAUNCHER_INFO_HH_
+#define LAUNCHER_INFO_HH_
+
+#include <filesystem>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace launchpad {
+
+class LauncherInfo {
+ public:
+  const std::string& GetName() const;
+  const std::string& GetExe() const;
+  const std::vector<std::string>& GetAppTypes() const;
+  const std::vector<std::string>& GetExtraArgs() const;
+
+ private:
+  std::string name_;
+  std::string exe_;
+  std::vector<std::string> app_types_;
+  std::vector<std::string> extra_args_;
+  friend class LauncherInfoInflator;
+};
+
+using LauncherInfoPtr = std::shared_ptr<LauncherInfo>;
+
+class LauncherInfoInflator {
+ public:
+  std::vector<LauncherInfoPtr> Inflate(const std::string_view path);
+
+ private:
+  void Parse(std::vector<LauncherInfoPtr>& launcher_info_list,
+      const std::filesystem::path& path);
+};
+
+}  // namespace launchpad
+
+#endif /* LAUNCHER_INFO_HH_ */
index 0f769db..23fd60b 100644 (file)
 #ifndef __LAUNCHPAD_CONFIG_H__
 #define __LAUNCHPAD_CONFIG_H__
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef enum {
        CONFIG_TYPE_MEMORY_STATUS_LOW_KEY,
        CONFIG_TYPE_MEMORY_STATUS_LOW_VALUE,
@@ -37,4 +41,8 @@ int _config_init(void);
 
 void _config_fini(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __LAUNCHPAD_CONFIG_H__ */
index 1697900..7411ba1 100644 (file)
 #include <stdbool.h>
 #include <bundle.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 int _debug_change_mount_namespace(void);
 int _debug_create_extra_argv(int *arg, char ***argv);
 int _debug_create_argv(int *argc, char ***argv, bool *attach);
@@ -29,5 +33,8 @@ void _debug_prepare_debugger(bundle *kb);
 int _debug_init(void);
 void _debug_fini(void);
 
-#endif /* __LAUNCHPAD_DEBUG_H__ */
+#ifdef __cplusplus
+}
+#endif
 
+#endif /* __LAUNCHPAD_DEBUG_H__ */
index 4db903e..77d1122 100644 (file)
 #include <stdbool.h>
 #include <sys/inotify.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct inotify_watch_info_s *inotify_watch_info_h;
 
 typedef bool (*inotify_watch_cb)(const char *event_name, uint32_t mask,
@@ -32,3 +36,7 @@ void _inotify_rm_watch(inotify_watch_info_h handle);
 int _inotify_init(void);
 
 void _inotify_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
index b9ae867..25fab13 100644 (file)
@@ -27,6 +27,10 @@ typedef enum {
        IO_NVAL = 0x20,
 } io_condition_e;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef bool (*io_channel_event_cb)(int fd, io_condition_e condition,
                void *user_data);
 
@@ -38,3 +42,7 @@ io_channel_h _io_channel_create(int fd, io_condition_e condition,
 void _io_channel_destroy(io_channel_h channel);
 
 int _io_channel_set_close_on_destroy(io_channel_h channel, bool do_close);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/launchpad-process-pool/inc/loader_info.h b/src/launchpad-process-pool/inc/loader_info.h
deleted file mode 100644 (file)
index 6d44b1d..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <glib.h>
-#include <bundle.h>
-
-#define DEFAULT_CPU_THRESHOLD_MAX              90
-#define DEFAULT_CPU_THRESHOLD_MIN              40
-
-enum loader_method_e {
-       METHOD_TIMEOUT = 0x0001,
-       METHOD_VISIBILITY = 0x0002,
-       METHOD_DEMAND = 0x0004,
-       METHOD_REQUEST = 0x0010,
-       METHOD_AVAILABLE_MEMORY = 0x0020,
-       METHOD_TTL = 0x0040,
-       METHOD_OUT_OF_MEMORY = 0x0100,
-       METHOD_INSTALL = 0x0200,
-};
-
-typedef struct _loader_info {
-       int type;
-       char *name;
-       char *exe;
-       GList *app_types;
-       int detection_method;
-       int timeout_val;
-       char *hw_acc;
-       GList *alternative_loaders;
-       bundle *extra;
-       int cpu_threshold_max;
-       int cpu_threshold_min;
-       bool on_boot;
-       bool global;
-       bool app_exists;
-       int activation_method;
-       int deactivation_method;
-       unsigned int ttl;
-       bool is_hydra;
-       bool app_check;
-       int on_boot_timeout;
-       int sched_priority;
-} loader_info_t;
-
-typedef void (*loader_info_foreach_cb)(loader_info_t *info, void *data);
-
-GList *_loader_info_load_dir(const char *path);
-GList *_loader_info_load_file(GList *list, const char *path);
-GList *_loader_info_unload(GList *list, const char *loader_name);
-void _loader_info_dispose(GList *info);
-int _loader_info_find_type(GList *info, const char *app_type, bool hwacc);
-int _loader_info_find_type_by_loader_name(GList *info, const char *loader_name);
-const char* _loader_info_find_loader_path_by_loader_name(GList *info, const char *loader_name);
-loader_info_t* _loader_info_find_loader_by_loader_name(GList *info, const char *loader_name);
-int *_loader_get_alternative_types(GList *info, int type, int *len);
-int _loader_info_foreach(GList *info, loader_info_foreach_cb callback,
-               void *data);
-bool _loader_info_exist_app_type(loader_info_t *info, const char *app_type);
diff --git a/src/launchpad-process-pool/inc/loader_info.hh b/src/launchpad-process-pool/inc/loader_info.hh
new file mode 100644 (file)
index 0000000..d96e029
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LOADER_INFO_HH_
+#define LOADER_INFO_HH_
+
+#include <bundle_cpp.h>
+
+#include <filesystem>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include "util.hh"
+
+namespace launchpad {
+
+constexpr int DefaultCpuThresholdMax = 90;
+constexpr int DefaultCpuThresholdMin = 40;
+
+enum class LoaderType : int {
+  Unsupported = -1,
+  User        = 1,
+  Dynamic     = 100,
+  Max
+};
+
+enum class LoaderMethod : int {
+  Empty           = 0x0000,
+  Timeout         = 0x0001,
+  Visibility      = 0x0002,
+  Demand          = 0x0004,
+  Request         = 0x0010,
+  AvailableMemory = 0x0020,
+  Ttl             = 0x0040,
+  OutOfMemory     = 0x0100,
+  Install         = 0x0200,
+};
+
+class LoaderInfo {
+ public:
+  LoaderType GetType() const;
+  const std::string& GetName() const;
+  const std::string& GetExe() const;
+  int GetCpuThresholdMax() const;
+  int GetCpuThresholdMin() const;
+  unsigned int GetTtl() const;
+  const std::vector<std::string>& GetAppTypes() const;
+  LoaderMethod GetDetectionMethod() const;
+  LoaderMethod GetActivationMethod() const;
+  LoaderMethod GetDeactivationMethod() const;
+  const std::string& GetHwAcc() const;
+  int GetOnbootTimeout() const;
+  int GetTimeoutVal() const;
+  int GetSchedPriority() const;
+  bool IsAppExists() const;
+  bool IsOnBoot() const;
+  bool IsHydraEnabled() const;
+  bool IsNeededAppCheck() const;
+  tizen_base::Bundle& GetExtra();
+  void SetType(LoaderType type);
+  void SetAppExists(bool exsits);
+
+ private:
+  LoaderType type_ = LoaderType::Unsupported;
+  std::string name_;
+  std::string exe_;
+  std::vector<std::string> app_types_;
+  LoaderMethod detection_method_ =
+      LoaderMethod::Timeout | LoaderMethod::Visibility | LoaderMethod::Install;
+  LoaderMethod activation_method_ = LoaderMethod::Empty;
+  LoaderMethod deactivation_method_ = LoaderMethod::Empty;
+  int timeout_val_ = 5000;
+  std::string hw_acc_;
+  std::vector<std::string> alternative_loaders_;
+  tizen_base::Bundle extra_;
+  int cpu_threshold_max_ = DefaultCpuThresholdMax;
+  int cpu_threshold_min_ = DefaultCpuThresholdMin;
+  bool on_boot_ = true;
+  bool global_ = false;
+  bool app_exists_ = false;
+  unsigned int ttl_ = 600U;  /* 10 minute */
+  bool is_hydra_ = false;
+  bool app_check_ = true;
+  int on_boot_timeout_ = 0;
+  int sched_priority_ = 0;
+
+  friend class LoaderInfoManager;
+  friend class LoaderInfoInflator;
+};
+
+using LoaderInfoPtr = std::shared_ptr<LoaderInfo>;
+
+class LoaderInfoInflator {
+ public:
+  std::vector<LoaderInfoPtr> Inflate(const std::string_view path);
+  void Parse(std::vector<LoaderInfoPtr>& launcher_info_list,
+             const std::filesystem::path& path);
+
+ private:
+  void ParseDetectionMethod(const LoaderInfoPtr& info,
+                            std::string& tok_start,
+                            std::istringstream& ss);
+  void ParseActivationMethod(const LoaderInfoPtr& info,
+                             std::string& tok_start,
+                             std::istringstream& ss);
+  void ParseDeactivationMethod(const LoaderInfoPtr& info,
+                               std::string& tok_start,
+                               std::istringstream& ss);
+  void ParseAppTypes(const LoaderInfoPtr& info,
+                     std::string& tok_start,
+                     std::istringstream& ss);
+};
+
+class LoaderInfoManager {
+ public:
+  explicit LoaderInfoManager(std::string path);
+  LoaderInfoManager(const LoaderInfoManager&) = delete;
+  LoaderInfoManager& operator=(const LoaderInfoManager&) = delete;
+
+  void Load();
+  void LoadFile(const std::string_view file);
+  void Unload(const std::string_view loader_name);
+  void Dispose();
+  LoaderType FindHwType(const std::string_view app_type);
+  LoaderType FindSwType(const std::string_view app_type);
+  std::string FindLoaderPath(const std::string_view loader_name);
+  LoaderInfoPtr FindLoaderInfo(const std::string_view loader_name);
+  std::vector<LoaderType> GetAlternativeTypes(LoaderType type);
+  const std::vector<LoaderInfoPtr>& GetLoaderInfoList() const;
+
+ private:
+  std::string path_;
+  std::vector<LoaderInfoPtr> loader_list_;
+};
+
+}  // namespace launchpad
+
+#endif  // LOADER_INFO_HH_
diff --git a/src/launchpad-process-pool/inc/util.hh b/src/launchpad-process-pool/inc/util.hh
new file mode 100644 (file)
index 0000000..3fffdf0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UTIL_HH_
+#define UTIL_HH_
+
+#include <string>
+#include <vector>
+
+namespace launchpad {
+
+template <typename E>
+E operator|(E a, E b) {
+  return static_cast<E>(static_cast<int>(a) | static_cast<int>(b));
+}
+
+template <typename E>
+bool operator==(E a, int x) {
+  return static_cast<int>(a) == x;
+}
+
+std::vector<std::string> Split(const std::string& str,
+                               const std::string& delim);
+
+}  // namespace launchpad
+
+#endif  // UTIL_HH_
diff --git a/src/launchpad-process-pool/src/debugger_info.c b/src/launchpad-process-pool/src/debugger_info.c
deleted file mode 100644 (file)
index e043e58..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "launchpad_common.h"
-#include "debugger_info.h"
-
-#define TAG_DEBUGGER           "[DEBUGGER]"
-#define TAG_NAME               "NAME"
-#define TAG_EXE                        "EXE"
-#define TAG_APP_TYPE           "APP_TYPE"
-#define TAG_EXTRA_KEY          "EXTRA_KEY"
-#define TAG_EXTRA_ENV          "EXTRA_ENV"
-#define TAG_UNLINK             "UNLINK"
-#define TAG_ATTACH             "ATTACH"
-#define TAG_LAST_EXTRA_KEY     "LAST_EXTRA_KEY"
-#define TAG_DEFAULT_OPT                "DEFAULT_OPT"
-
-struct debugger_info_s {
-       char *name;
-       char *exe;
-       GList *app_types;
-       GList *extra_key_list;
-       GList *extra_env_list;
-       GList *unlink_list;
-       char *attach;
-       GList *last_extra_key_list;
-       GList *default_opt_list;
-};
-
-static struct debugger_info_s *__create_debugger_info(void)
-{
-       struct debugger_info_s *info;
-
-       info = calloc(1, sizeof(struct debugger_info_s));
-       if (info == NULL) {
-               _E("out of memory");
-               return NULL;
-       }
-
-       return info;
-}
-
-static void __destroy_debugger_info(gpointer data)
-{
-       struct debugger_info_s *info = (struct debugger_info_s *)data;
-
-       if (info == NULL)
-               return;
-
-       if (info->default_opt_list)
-               g_list_free_full(info->default_opt_list, free);
-       if (info->last_extra_key_list)
-               g_list_free_full(info->last_extra_key_list, free);
-       if (info->attach)
-               free(info->attach);
-       if (info->unlink_list)
-               g_list_free_full(info->unlink_list, free);
-       if (info->extra_env_list)
-               g_list_free_full(info->extra_env_list, free);
-       if (info->extra_key_list)
-               g_list_free_full(info->extra_key_list, free);
-       if (info->app_types)
-               g_list_free_full(info->app_types, free);
-       if (info->exe)
-               free(info->exe);
-       if (info->name)
-               free(info->name);
-       free(info);
-}
-
-static void __parse_app_types(struct debugger_info_s *info, char *line)
-{
-       char *token;
-       char *saveptr = NULL;
-
-       token = strtok_r(line, " |\t\r\n", &saveptr);
-       while (token) {
-               info->app_types = g_list_append(info->app_types, strdup(token));
-               token = strtok_r(NULL, " |\t\r\n", &saveptr);
-       }
-}
-
-static GList *__parse_file(GList *list, const char *path)
-{
-       FILE *fp;
-       char buf[LINE_MAX];
-       char *tok1 = NULL;
-       char *tok2 = NULL;
-       struct debugger_info_s *info = NULL;
-
-       fp = fopen(path, "rt");
-       if (fp == NULL)
-               return list;
-
-       while (fgets(buf, sizeof(buf), fp) != NULL) {
-               FREE_AND_NULL(tok1);
-               FREE_AND_NULL(tok2);
-               sscanf(buf, "%ms %ms", &tok1, &tok2);
-               if (tok1 && strcasecmp(TAG_DEBUGGER, tok1) == 0) {
-                       if (info) {
-                               _D("name: %s, exe: %s", info->name, info->exe);
-                               list = g_list_append(list, info);
-                       }
-
-                       info = __create_debugger_info();
-                       if (info == NULL)
-                               break;
-
-                       continue;
-               }
-
-               if (!tok1 || !tok2)
-                       continue;
-               if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
-                       continue;
-               if (info == NULL)
-                       continue;
-
-               if (strcasecmp(TAG_NAME, tok1) == 0) {
-                       info->name = strdup(tok2);
-                       if (info->name == NULL) {
-                               _E("out of memory");
-                               __destroy_debugger_info(info);
-                               info = NULL;
-                               break;
-                       }
-               } else if (strcasecmp(TAG_EXE, tok1) == 0) {
-                       info->exe = strdup(tok2);
-                       if (info->exe == NULL) {
-                               _E("out of memory");
-                               __destroy_debugger_info(info);
-                               info = NULL;
-                               break;
-                       }
-               } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
-                       __parse_app_types(info, &buf[strlen(tok1)]);
-                       if (info->app_types == NULL) {
-                               _E("app_types is NULL");
-                               __destroy_debugger_info(info);
-                               info = NULL;
-                               break;
-                       }
-               } else if (strcasecmp(TAG_EXTRA_KEY, tok1) == 0) {
-                       info->extra_key_list = g_list_append(
-                                       info->extra_key_list, strdup(tok2));
-               } else if (strcasecmp(TAG_EXTRA_ENV, tok1) == 0) {
-                       info->extra_env_list = g_list_append(
-                                       info->extra_env_list, strdup(tok2));
-               } else if (strcasecmp(TAG_UNLINK, tok1) == 0) {
-                       info->unlink_list = g_list_append(info->unlink_list,
-                                       strdup(tok2));
-               } else if (strcasecmp(TAG_ATTACH, tok1) == 0) {
-                       info->attach = strdup(tok2);
-                       if (info->attach == NULL) {
-                               _E("attach is NULL");
-                               __destroy_debugger_info(info);
-                               info = NULL;
-                               break;
-                       }
-               } else if (strcasecmp(TAG_LAST_EXTRA_KEY, tok1) == 0) {
-                       info->last_extra_key_list = g_list_append(
-                                       info->last_extra_key_list,
-                                       strdup(tok2));
-               } else if (strcasecmp(TAG_DEFAULT_OPT, tok1) == 0) {
-                       info->default_opt_list = g_list_append(
-                                       info->default_opt_list,
-                                       strdup(tok2));
-               }
-       }
-       fclose(fp);
-
-       if (info) {
-               _D("name: %s, exe: %s", info->name, info->exe);
-               list = g_list_append(list, info);
-       }
-
-       if (tok1)
-               free(tok1);
-       if (tok2)
-               free(tok2);
-
-       return list;
-}
-
-GList *_debugger_info_load(const char *path)
-{
-       DIR *dp;
-       struct dirent *dentry = NULL;
-       GList *list = NULL;
-       char buf[PATH_MAX];
-       char *ext;
-
-       if (path == NULL)
-               return NULL;
-
-       dp = opendir(path);
-       if (dp == NULL)
-               return NULL;
-
-       while ((dentry = readdir(dp)) != NULL) {
-               if (dentry->d_name[0] == '.')
-                       continue;
-
-               ext = strrchr(dentry->d_name, '.');
-               if (ext && strcmp(ext, ".debugger") == 0) {
-                       snprintf(buf, sizeof(buf), "%s/%s",
-                                       path, dentry->d_name);
-                       list = __parse_file(list, buf);
-               }
-       }
-       closedir(dp);
-
-       return list;
-}
-
-void _debugger_info_unload(GList *info)
-{
-       if (info == NULL)
-               return;
-
-       g_list_free_full(info, __destroy_debugger_info);
-}
-
-static int __comp_name(gconstpointer a, gconstpointer b)
-{
-       struct debugger_info_s *info = (struct debugger_info_s *)a;
-
-       if (info == NULL || info->name == NULL || b == NULL)
-               return -1;
-
-       if (strcasecmp(info->name, b) == 0)
-               return 0;
-
-       return -1;
-}
-
-debugger_info_h _debugger_info_find(GList *info_list, const char *name)
-{
-       GList *list;
-
-       if (info_list == NULL || name == NULL)
-               return NULL;
-
-       list = g_list_find_custom(info_list, name, __comp_name);
-       if (list == NULL)
-               return NULL;
-
-       return (debugger_info_h)list->data;
-}
-
-const char *_debugger_info_get_exe(debugger_info_h info)
-{
-       if (info == NULL)
-               return NULL;
-
-       return info->exe;
-}
-
-GList *_debugger_info_get_extra_key_list(debugger_info_h info)
-{
-       if (info == NULL)
-               return NULL;
-
-       return info->extra_key_list;
-}
-
-GList *_debugger_info_get_extra_env_list(debugger_info_h info)
-{
-       if (info == NULL)
-               return NULL;
-
-       return info->extra_env_list;
-}
-
-GList *_debugger_info_get_unlink_list(debugger_info_h info)
-{
-       if (info == NULL)
-               return NULL;
-
-       return info->unlink_list;
-}
-
-const char *_debugger_info_get_attach(debugger_info_h info)
-{
-       if (info == NULL)
-               return NULL;
-
-       return info->attach;
-}
-
-GList *_debugger_info_get_last_extra_key_list(debugger_info_h info)
-{
-       if (info == NULL)
-               return NULL;
-
-       return info->last_extra_key_list;
-}
-
-GList *_debugger_info_get_default_opt_list(debugger_info_h info)
-{
-       if (info == NULL)
-               return NULL;
-
-       return info->default_opt_list;
-}
diff --git a/src/launchpad-process-pool/src/debugger_info.cc b/src/launchpad-process-pool/src/debugger_info.cc
new file mode 100644 (file)
index 0000000..8cbeaf7
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+#include <utility>
+
+#include "debugger_info.hh"
+#include "launchpad_common.h"
+#include "util.hh"
+
+namespace launchpad {
+namespace {
+
+constexpr const char kTagDebugger[] = "[DEBUGGER]";
+constexpr const char kTagName[] = "NAME";
+constexpr const char kTagExe[] = "EXE";
+constexpr const char kTagAppType[] = "APP_TYPE";
+constexpr const char kTagExtraKey[] = "EXTRA_KEY";
+constexpr const char kTagExtraEnv[] = "EXTRA_ENV";
+constexpr const char kTagUnlink[] = "UNLINK";
+constexpr const char kTagAttach[] = "ATTACH";
+constexpr const char kTagLastExtraKey[] = "LAST_EXTRA_KEY";
+constexpr const char kTagDefaultOpt[] = "DEFAULT_OPT";
+
+}  // namespace
+
+namespace fs = std::filesystem;
+
+void DebuggerInfoInflator::Parse(
+    std::vector<DebuggerInfoPtr>& debugger_info_list,
+    const fs::path& path) {
+  std::ifstream fp;
+  fp.open(path);
+  if (fp.fail())
+    return;
+
+  DebuggerInfoPtr info;
+  std::string input;
+  while (std::getline(fp, input)) {
+    std::istringstream ss(input);
+    std::string tok1, tok2;
+    if (!(ss >> tok1))
+      continue;
+
+    if (strcasecmp(kTagDebugger, tok1.c_str()) == 0) {
+      if (info != nullptr) {
+        _D("name: %s, exe: %s", info->name_.c_str(), info->exe_.c_str());
+        debugger_info_list.push_back(std::move(info));
+      }
+
+      info = std::make_unique<DebuggerInfo>();
+      continue;
+    }
+
+    if (!(ss >> tok2))
+      continue;
+    if (tok1.front() == '#' || info == nullptr)
+      continue;
+
+    std::string key;
+    std::transform(tok1.begin(), tok1.end(), std::back_inserter(key),
+                   [](char ch) { return toupper(ch); });
+    if (kTagName == key) {
+      info->name_ = std::move(tok2);
+    } else if (kTagExe == key) {
+      fs::path file(tok2);
+      if (fs::exists(file) == false) {
+        _E("Failed to access %s", tok2.c_str());
+        info.reset();
+        continue;
+      }
+
+      info->exe_ = std::move(tok2);
+    } else if (kTagAppType == key) {
+      std::string line = std::move(tok2);
+      do {
+        auto tokens = Split(line, " |\t\r\n");
+        for (auto& token : tokens) {
+          _E("types: %s", token.c_str());
+          info->app_types_.push_back(std::move(token));
+        }
+      } while (std::getline(ss, line));
+    } else if (kTagExtraKey == key) {
+      info->extra_key_list_.push_back(std::move(tok2));
+    } else if (kTagExtraEnv == key) {
+      info->extra_env_list_.push_back(std::move(tok2));
+    } else if (kTagUnlink == key) {
+      info->unlink_list_.push_back(std::move(tok2));
+    } else if (kTagAttach == key) {
+      info->attach_ = std::move(tok2);
+    } else if (kTagLastExtraKey == key) {
+      info->last_extra_key_list_.push_back(std::move(tok2));
+    } else if (kTagDefaultOpt == key) {
+      info->default_opt_list_.push_back(std::move(tok2));
+    }
+  }
+
+  fp.close();
+  if (info) {
+    _D("name: %s, exe: %s", info->name_.c_str(), info->exe_.c_str());
+    debugger_info_list.push_back(std::move(info));
+  }
+}
+
+const std::string& DebuggerInfo::GetName() const {
+  return name_;
+}
+
+const std::string& DebuggerInfo::GetExe() const {
+  return exe_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetAppTypes() const {
+  return app_types_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetExtraKeyList() const {
+  return extra_key_list_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetExtraEnvList() const {
+  return extra_env_list_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetUnlinkList() const {
+  return unlink_list_;
+}
+
+const std::string& DebuggerInfo::GetAttachInfo() const {
+  return attach_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetLastExtraKeyList() const {
+  return last_extra_key_list_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetDefaultOptList() const {
+  return default_opt_list_;
+}
+
+std::vector<DebuggerInfoPtr> DebuggerInfoInflator::Inflate(
+    const std::string_view path) {
+  fs::path p(path);
+  if (fs::is_directory(p) == false)
+    return {};
+
+  std::vector<DebuggerInfoPtr> result;
+  for (auto& entry : fs::directory_iterator(p)) {
+    fs::path file(entry.path());
+    if (file.extension() == ".debugger")
+      Parse(result, file);
+  }
+
+  return result;
+}
+
+}  // namespace launchpad
diff --git a/src/launchpad-process-pool/src/launcher_info.c b/src/launchpad-process-pool/src/launcher_info.c
deleted file mode 100644 (file)
index 89a7ccd..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "launcher_info.h"
-#include "launchpad_common.h"
-
-#define TAG_LAUNCHER   "[LAUNCHER]"
-#define TAG_NAME       "NAME"
-#define TAG_EXE                "EXE"
-#define TAG_APP_TYPE   "APP_TYPE"
-#define TAG_EXTRA_ARG  "EXTRA_ARG"
-
-struct launcher_info_s {
-       char *name;
-       char *exe;
-       GList *app_types;
-       GList *extra_args;
-};
-
-static struct launcher_info_s *__create_launcher_info(void)
-{
-       struct launcher_info_s *info;
-
-       info = calloc(1, sizeof(struct launcher_info_s));
-       if (info == NULL) {
-               _E("out of memory");
-               return NULL;
-       }
-
-       return info;
-}
-
-static void __destroy_launcher_info(gpointer data)
-{
-       struct launcher_info_s *info = (struct launcher_info_s *)data;
-
-       if (info == NULL)
-               return;
-
-       if (info->extra_args)
-               g_list_free_full(info->extra_args, free);
-       if (info->app_types)
-               g_list_free_full(info->app_types, free);
-       if (info->exe)
-               free(info->exe);
-       if (info->name)
-               free(info->name);
-       free(info);
-}
-
-static void __parse_app_types(struct launcher_info_s *info, char *line)
-{
-       char *token;
-       char *saveptr = NULL;
-
-       token = strtok_r(line, " |\t\r\n", &saveptr);
-       while (token) {
-               info->app_types = g_list_append(info->app_types, strdup(token));
-               token = strtok_r(NULL, " |\t\r\n", &saveptr);
-       }
-}
-
-static GList *__parse_file(GList *list, const char *path)
-{
-       FILE *fp;
-       char buf[LINE_MAX];
-       char *tok1 = NULL;
-       char *tok2 = NULL;
-       struct launcher_info_s *info = NULL;
-
-       fp = fopen(path, "rt");
-       if (fp == NULL)
-               return list;
-
-       while (fgets(buf, sizeof(buf), fp) != NULL) {
-               FREE_AND_NULL(tok1);
-               FREE_AND_NULL(tok2);
-               sscanf(buf, "%ms %ms", &tok1, &tok2);
-               if (tok1 && strcasecmp(TAG_LAUNCHER, tok1) == 0) {
-                       if (info) {
-                               _D("name: %s, exe: %s", info->name, info->exe);
-                               list = g_list_append(list, info);
-                       }
-
-                       info = __create_launcher_info();
-                       if (info == NULL)
-                               break;
-
-                       continue;
-               }
-
-               if (!tok1 || !tok2)
-                       continue;
-               if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
-                       continue;
-               if (info == NULL)
-                       continue;
-
-               if (strcasecmp(TAG_NAME, tok1) == 0) {
-                       info->name = strdup(tok2);
-                       if (info->name == NULL) {
-                               _E("out of memory");
-                               __destroy_launcher_info(info);
-                               info = NULL;
-                               break;
-                       }
-               } else if (strcasecmp(TAG_EXE, tok1) == 0) {
-                       info->exe = strdup(tok2);
-                       if (info->exe == NULL) {
-                               _E("out of memory");
-                               __destroy_launcher_info(info);
-                               info = NULL;
-                               break;
-                       }
-                       if (access(info->exe, F_OK | X_OK) != 0) {
-                               _E("Failed to access %s", info->exe);
-                               __destroy_launcher_info(info);
-                               info = NULL;
-                       }
-               } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
-                       __parse_app_types(info, &buf[strlen(tok1)]);
-                       if (info->app_types == NULL) {
-                               _E("app_types is NULL");
-                               __destroy_launcher_info(info);
-                               info = NULL;
-                               break;
-                       }
-               } else if (strcasecmp(TAG_EXTRA_ARG, tok1) == 0) {
-                       info->extra_args = g_list_append(info->extra_args,
-                                       strdup(tok2));
-               }
-       }
-       fclose(fp);
-
-       if (info) {
-               _D("name: %s, exe: %s", info->name, info->exe);
-               list = g_list_append(list, info);
-       }
-
-       if (tok1)
-               free(tok1);
-       if (tok2)
-               free(tok2);
-
-       return list;
-}
-
-GList *_launcher_info_load(const char *path)
-{
-       DIR *dp;
-       struct dirent *dentry = NULL;
-       GList *list = NULL;
-       char buf[PATH_MAX];
-       char *ext;
-
-       if (path == NULL)
-               return NULL;
-
-       dp = opendir(path);
-       if (dp == NULL)
-               return NULL;
-
-       while ((dentry = readdir(dp)) != NULL) {
-               if (dentry->d_name[0] == '.')
-                       continue;
-
-               ext = strrchr(dentry->d_name, '.');
-               if (ext && strcmp(ext, ".launcher") == 0) {
-                       snprintf(buf, sizeof(buf), "%s/%s",
-                                       path, dentry->d_name);
-                       list = __parse_file(list, buf);
-               }
-       }
-       closedir(dp);
-
-       return list;
-}
-
-void _launcher_info_unload(GList *info)
-{
-       if (info == NULL)
-               return;
-
-       g_list_free_full(info, __destroy_launcher_info);
-}
-
-static int __comp_str(gconstpointer a, gconstpointer b)
-{
-       if (a == NULL || b == NULL)
-               return -1;
-
-       return strcmp(a, b);
-}
-
-static int __comp_app_type(gconstpointer a, gconstpointer b)
-{
-       struct launcher_info_s *info = (struct launcher_info_s *)a;
-
-       if (info == NULL || info->app_types == NULL || b == NULL)
-               return -1;
-
-       if (g_list_find_custom(info->app_types, b, __comp_str))
-               return 0;
-
-       return -1;
-}
-
-launcher_info_h _launcher_info_find(GList *info_list, const char *app_type)
-{
-       GList *list;
-
-       if (info_list == NULL || app_type == NULL)
-               return NULL;
-
-       list = g_list_find_custom(info_list, app_type, __comp_app_type);
-       if (list == NULL)
-               return NULL;
-
-       return (launcher_info_h)list->data;
-}
-
-const char *_launcher_info_get_exe(launcher_info_h info)
-{
-       if (info == NULL)
-               return NULL;
-
-       return info->exe;
-}
-
-GList *_launcher_info_get_extra_args(launcher_info_h info)
-{
-       if (info == NULL)
-               return NULL;
-
-       return info->extra_args;
-}
diff --git a/src/launchpad-process-pool/src/launcher_info.cc b/src/launchpad-process-pool/src/launcher_info.cc
new file mode 100644 (file)
index 0000000..7387323
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+#include <utility>
+
+#include "launcher_info.hh"
+#include "launchpad_common.h"
+#include "util.hh"
+
+namespace launchpad {
+namespace {
+
+constexpr const char kTagLauncher[] = "[LAUNCHER]";
+constexpr const char kTagName[] = "NAME";
+constexpr const char kTagExe[] = "EXE";
+constexpr const char kTagAppType[] = "APP_TYPE";
+constexpr const char kTagExtraArg[] = "EXTRA_ARG";
+
+}  // namespace
+
+namespace fs = std::filesystem;
+
+const std::string& LauncherInfo::GetName() const {
+  return name_;
+}
+
+const std::string& LauncherInfo::GetExe() const {
+  return exe_;
+}
+
+const std::vector<std::string>& LauncherInfo::GetAppTypes() const {
+  return app_types_;
+}
+
+const std::vector<std::string>& LauncherInfo::GetExtraArgs() const {
+  return extra_args_;
+}
+
+void LauncherInfoInflator::Parse(
+    std::vector<LauncherInfoPtr>& launcher_info_list,
+    const fs::path& path) {
+  std::ifstream fp;
+  fp.open(path);
+  if (fp.fail())
+    return;
+
+  LauncherInfoPtr info;
+  std::string input;
+  while (std::getline(fp, input)) {
+    std::istringstream ss(input);
+    std::string tok1, tok2;
+    if (!(ss >> tok1))
+      continue;
+
+    if (strcasecmp(kTagLauncher, tok1.c_str()) == 0) {
+      if (info != nullptr) {
+        _D("name: %s, exe: %s", info->name_.c_str(), info->exe_.c_str());
+        launcher_info_list.push_back(std::move(info));
+      }
+
+      info = std::make_shared<LauncherInfo>();
+      continue;
+    }
+
+    if (!(ss >> tok2))
+      continue;
+    if (tok1.front() == '#' || info == nullptr)
+      continue;
+
+    std::string key;
+    std::transform(tok1.begin(), tok1.end(), std::back_inserter(key),
+                   [](char ch) { return toupper(ch); });
+    if (kTagName == key) {
+      info->name_ = std::move(tok2);
+    } else if (kTagExe == key) {
+      fs::path file(tok2);
+      if (fs::exists(file) == false) {
+        _E("Failed to access %s", tok2.c_str());
+        info.reset();
+        continue;
+      }
+
+      info->exe_ = std::move(tok2);
+    } else if (kTagAppType == key) {
+      std::string line = std::move(tok2);
+      do {
+        auto tokens = Split(line, " |\t\r\n");
+        for (auto& token : tokens) {
+          info->app_types_.push_back(std::move(token));
+        }
+      } while (std::getline(ss, line));
+    } else if (kTagExtraArg == key) {
+      info->extra_args_.push_back(std::move(tok2));
+    }
+  }
+
+  fp.close();
+  if (info) {
+    _D("name: %s, exe: %s", info->name_.c_str(), info->exe_.c_str());
+    launcher_info_list.push_back(std::move(info));
+  }
+}
+
+std::vector<LauncherInfoPtr> LauncherInfoInflator::Inflate(
+    const std::string_view path) {
+  fs::path p(path);
+  if (fs::is_directory(p) == false)
+    return {};
+
+  std::vector<LauncherInfoPtr> result;
+  for (auto& entry : fs::directory_iterator(p)) {
+    fs::path file(entry.path());
+    if (file.extension() == ".launcher") {
+      Parse(result, file);
+    }
+  }
+
+  return result;
+}
+
+}  // namespace launchpad
diff --git a/src/launchpad-process-pool/src/launchpad.c b/src/launchpad-process-pool/src/launchpad.c
deleted file mode 100644 (file)
index e5ca890..0000000
+++ /dev/null
@@ -1,3571 +0,0 @@
-/*
- * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <systemd/sd-daemon.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/capability.h>
-#include <sched.h>
-#include <stdbool.h>
-#include <malloc.h>
-#include <bundle_internal.h>
-#include <security-manager.h>
-#include <time.h>
-#include <systemd/sd-daemon.h>
-#include <glib.h>
-#include <linux/limits.h>
-#include <ttrace.h>
-#include <vconf.h>
-#include <math.h>
-#include <trust-anchor.h>
-
-#include "key.h"
-#include "launcher_info.h"
-#include "launchpad_common.h"
-#include "launchpad_config.h"
-#include "launchpad_dbus.h"
-#include "launchpad_debug.h"
-#include "launchpad_inotify.h"
-#include "launchpad_io_channel.h"
-#include "launchpad_log.h"
-#include "launchpad_memory_monitor.h"
-#include "launchpad_plugin.h"
-#include "launchpad_proc.h"
-#include "launchpad_signal.h"
-#include "launchpad_types.h"
-#include "launchpad_worker.h"
-#include "loader_info.h"
-#include "perf.h"
-#include "slot_info.h"
-
-#define AUL_PR_NAME         16
-#define EXEC_CANDIDATE_EXPIRED 5
-#define EXEC_CANDIDATE_WAIT 1
-#define DIFF(a, b) (((a) > (b)) ? (a) - (b) : (b) - (a))
-#define CANDIDATE_NONE 0
-#define HYDRA_NONE 0
-#define PROCESS_POOL_LAUNCHPAD_SOCK ".launchpad-process-pool-sock"
-#define LAUNCHPAD_LOGGER_SOCK ".launchpad-logger-sock"
-#define LOADER_PATH_DEFAULT "/usr/bin/launchpad-loader"
-#define LOADER_INFO_PATH       "/usr/share/aul"
-#define OPT_SHARE_PATH "/opt/share"
-#define LOADERS_PATH "loaders"
-#define APP_DEFINED_LOADER_INFO_PATH   OPT_SHARE_PATH "/" LOADERS_PATH
-#define COMMON_LOADER_NAME "common-loader1"
-
-#define LAUNCHER_INFO_PATH     LOADER_INFO_PATH
-#define REGULAR_UID_MIN 5000
-#define PAD_ERR_FAILED                 -1
-#define PAD_ERR_REJECTED               -2
-#define PAD_ERR_INVALID_ARGUMENT       -3
-#define PAD_ERR_INVALID_PATH           -4
-#define CPU_CHECKER_TIMEOUT            1000
-#define PI                             3.14159265
-#define WIN_SCORE 100
-#define LOSE_SCORE_RATE 0.7f
-
-enum candidate_process_state_e {
-       CANDIDATE_PROCESS_STATE_RUNNING,
-       CANDIDATE_PROCESS_STATE_PAUSED,
-};
-
-typedef struct {
-       int type;
-       bool prepared;
-       int pid; /* for hydra this pid is not the pid of hydra itself */
-                /* but pid of non-hydra candidate, which was forked from hydra */
-       int hydra_pid;
-       int loader_id;
-       int caller_pid;
-       int send_fd;
-       int hydra_fd;
-       int last_exec_time;
-       guint timer;
-       char *loader_name;
-       char *loader_path;
-       char *loader_extra;
-       int detection_method;
-       int timeout_val;
-       unsigned long long cpu_total_time;
-       unsigned long long cpu_idle_time;
-       int threshold;
-       int threshold_max;
-       int threshold_min;
-       int cur_event;
-       bool on_boot;
-       bool app_exists;
-       bool touched;
-       int activation_method;
-       int deactivation_method;
-       unsigned int ttl;
-       guint live_timer;
-       int state;
-       bool is_hydra;
-       bool app_check;
-       io_channel_h client_channel;
-       io_channel_h channel;
-       io_channel_h hydra_channel;
-       unsigned int score;
-       unsigned int pss;
-       int cpu_check_count;
-       int on_boot_timeout;
-       guint on_boot_timer;
-       int sched_priority;
-} candidate_process_context_t;
-
-typedef struct {
-       GPollFD *gpollfd;
-       int type;
-       int loader_id;
-} loader_context_t;
-
-typedef struct {
-       GQueue *queue;
-       guint timer;
-       guint idle_checker;
-       candidate_process_context_t *running_cpc;
-} sequencer;
-
-struct app_launch_arg {
-       const char *appid;
-       const char *app_path;
-       appinfo_t *menu_info;
-       bundle *kb;
-};
-
-struct app_arg {
-       int argc;
-       char **argv;
-};
-
-struct app_info {
-       const char *type;
-       bool exists;
-};
-
-struct cleanup_info_s {
-       char *appid;
-       int pid;
-};
-
-typedef struct candidate_info_s {
-       char **argv;
-       int argc;
-       int loader_id;
-       int type;
-       pid_t pid;
-} candidate_info_t;
-
-typedef struct request_s {
-       app_pkt_t *pkt;
-       appinfo_t *menu_info;
-       bundle *kb;
-       candidate_process_context_t *cpc;
-       candidate_process_context_t *org_cpc;
-       const char *app_path;
-       int clifd;
-       int cmd;
-       int loader_id;
-       pid_t caller_pid;
-       uid_t caller_uid;
-       pid_t pid; /* result */
-} request_t;
-
-typedef request_t *request_h;
-
-typedef int (*request_handler)(request_h request);
-
-static int __sys_hwacc;
-static GList *loader_info_list;
-static GList *app_defined_loader_info_list;
-static int user_slot_offset;
-static GList *candidate_slot_list;
-static app_labels_monitor *label_monitor;
-static GList *launcher_info_list;
-static GHashTable *__pid_table;
-static int __memory_status_low;
-static int __memory_status_normal;
-static sequencer __sequencer;
-static int MEMORY_STATUS_LOW;
-static int MEMORY_STATUS_NORMAL;
-static int MAX_CPU_CHECK_COUNT;
-
-static io_channel_h __logger_channel;
-static io_channel_h __label_monitor_channel;
-static io_channel_h __launchpad_channel;
-static int __client_fd = -1;
-static worker_h __cleaner;
-
-static candidate_process_context_t *__add_slot(slot_info_t *info);
-static int __remove_slot(int type, int loader_id);
-static int __add_default_slots(void);
-static gboolean __handle_idle_checker(gpointer data);
-static int __add_idle_checker(int detection_method, GList *cur);
-static void __dispose_candidate_process(candidate_process_context_t *cpc);
-static bool __is_low_memory(void);
-static void __update_slot_state(candidate_process_context_t *cpc, int method,
-               bool force);
-static void __init_app_defined_loader_monitor(void);
-static gboolean __launchpad_recovery_cb(gpointer data);
-static gboolean __logger_recovery_cb(gpointer data);
-
-static gboolean __handle_queuing_slots(gpointer data)
-{
-       candidate_process_context_t *cpc;
-       unsigned long long total = 0;
-       unsigned long long idle = 0;
-
-       if (__sequencer.idle_checker > 0)
-               return G_SOURCE_CONTINUE;
-
-       if (g_queue_is_empty(__sequencer.queue)) {
-               __sequencer.timer = 0;
-               return G_SOURCE_REMOVE;
-       }
-
-       cpc = (candidate_process_context_t *)g_queue_pop_head(
-                       __sequencer.queue);
-       if (!cpc) {
-               _E("Critical error!");
-               __sequencer.timer = 0;
-               return G_SOURCE_REMOVE;;
-       }
-
-       if (cpc->app_check && !cpc->app_exists) {
-               _W("The application is not installed. Type(%d)", cpc->type);
-               return G_SOURCE_CONTINUE;
-       }
-
-       if (cpc->timer) {
-               g_source_remove(cpc->timer);
-               cpc->timer = 0;
-       }
-
-       if (cpc->pid != CANDIDATE_NONE) {
-               _W("The slot(%d) is already running. pid(%d)",
-                               cpc->type, cpc->pid);
-               return G_SOURCE_CONTINUE;
-       }
-
-       _get_cpu_idle(&total, &idle);
-       cpc->cpu_idle_time = idle;
-       cpc->cpu_total_time = total;
-       cpc->cpu_check_count = 0;
-
-       __sequencer.idle_checker = g_timeout_add(CPU_CHECKER_TIMEOUT,
-                       __handle_idle_checker, cpc);
-       __sequencer.running_cpc = cpc;
-
-       _W("[__SEQUENCER__] Add idle checker. Type(%d)", cpc->type);
-
-       return G_SOURCE_CONTINUE;
-}
-
-static bool __sequencer_slot_is_running(candidate_process_context_t *cpc)
-{
-       if (__sequencer.running_cpc == cpc)
-               return true;
-
-       return false;
-}
-
-static bool __sequencer_slot_exist(candidate_process_context_t *cpc)
-{
-       GList *found;
-
-       found = g_queue_find(__sequencer.queue, cpc);
-       if (found)
-               return true;
-
-       return false;
-}
-
-static int __sequencer_add_slot(candidate_process_context_t *cpc)
-{
-       if (__sequencer_slot_exist(cpc)) {
-               _W("Already exists");
-               return -1;
-       }
-
-       if (__sequencer_slot_is_running(cpc)) {
-               _W("slot(%d) is running", cpc->type);
-               return -1;
-       }
-
-       g_queue_push_tail(__sequencer.queue, cpc);
-
-       return 0;
-}
-
-static void __sequencer_remove_slot(candidate_process_context_t *cpc)
-{
-       g_queue_remove(__sequencer.queue, cpc);
-}
-
-static void __sequencer_run(void)
-{
-       if (__sequencer.timer)
-               return;
-
-       __sequencer.timer = g_timeout_add(500, __handle_queuing_slots, NULL);
-       if (!__sequencer.timer)
-               _E("Failed to add sequencer timer");
-}
-
-static void __sequencer_stop(void)
-{
-       if (!__sequencer.timer)
-               return;
-
-       g_source_remove(__sequencer.timer);
-       __sequencer.timer = 0;
-}
-
-static bool __sequencer_queue_is_empty(void)
-{
-       if (g_queue_is_empty(__sequencer.queue))
-               return true;
-
-       return false;
-}
-
-static int __sequencer_init(void)
-{
-       _D("[__SEQUENCER__] Init");
-
-       __sequencer.queue = g_queue_new();
-       if (!__sequencer.queue) {
-               _E("Out of memory");
-               return -1;
-       }
-
-       return 0;
-}
-
-static void __sequencer_fini(void)
-{
-       _D("[__SEQUENCER__] Finish");
-
-       if (__sequencer.idle_checker > 0)
-               g_source_remove(__sequencer.idle_checker);
-
-       if (__sequencer.timer > 0)
-               g_source_remove(__sequencer.timer);
-
-       g_queue_free(__sequencer.queue);
-}
-
-static int __make_loader_id(void)
-{
-       static int id = PAD_LOADER_ID_DYNAMIC_BASE;
-
-       return ++id;
-}
-
-static candidate_process_context_t *__find_slot_from_static_type(int type)
-{
-       candidate_process_context_t *cpc;
-       GList *iter = candidate_slot_list;
-
-       if (type == LAUNCHPAD_LOADER_TYPE_DYNAMIC ||
-                       type == LAUNCHPAD_LOADER_TYPE_UNSUPPORTED)
-               return NULL;
-
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (type == cpc->type)
-                       return cpc;
-
-               iter = g_list_next(iter);
-       }
-
-       return NULL;
-}
-
-static candidate_process_context_t *__find_slot_from_pid(int pid)
-{
-       candidate_process_context_t *cpc;
-       GList *iter = candidate_slot_list;
-
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (pid == cpc->pid)
-                       return cpc;
-
-               iter = g_list_next(iter);
-       }
-
-       return NULL;
-}
-
-static candidate_process_context_t *__find_hydra_slot_from_pid(int pid)
-{
-       candidate_process_context_t *cpc;
-       GList *iter = candidate_slot_list;
-
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (cpc->is_hydra && pid == cpc->hydra_pid)
-                       return cpc;
-
-               iter = g_list_next(iter);
-       }
-
-       return NULL;
-}
-
-static candidate_process_context_t *__find_slot_from_caller_pid(int caller_pid)
-{
-       candidate_process_context_t *cpc;
-       GList *iter = candidate_slot_list;
-
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (caller_pid == cpc->caller_pid)
-                       return cpc;
-
-               iter = g_list_next(iter);
-       }
-
-       return NULL;
-}
-
-static candidate_process_context_t *__find_slot_from_loader_id(int id)
-{
-       candidate_process_context_t *cpc;
-       GList *iter = candidate_slot_list;
-
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (id == cpc->loader_id)
-                       return cpc;
-
-               iter = g_list_next(iter);
-       }
-
-       return NULL;
-}
-
-static candidate_process_context_t *__find_slot_from_loader_name(const char *loader_name)
-{
-       candidate_process_context_t *cpc;
-       GList *iter = candidate_slot_list;
-
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (strcmp(cpc->loader_name, loader_name) == 0)
-                       return cpc;
-
-               iter = g_list_next(iter);
-       }
-
-       return NULL;
-}
-
-static candidate_process_context_t *__find_slot(int type, int loader_id)
-{
-       if (type == LAUNCHPAD_LOADER_TYPE_DYNAMIC)
-               return __find_slot_from_loader_id(loader_id);
-
-       return __find_slot_from_static_type(type);
-}
-
-static void __update_slot_score(candidate_process_context_t *slot)
-{
-       if (!slot)
-               return;
-
-       slot->score *= LOSE_SCORE_RATE;
-       slot->score += WIN_SCORE;
-}
-
-static void __update_slots_pss(void)
-{
-       candidate_process_context_t *cpc;
-       GList *iter;
-
-       iter = candidate_slot_list;
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               iter = g_list_next(iter);
-
-               if (cpc->pid == CANDIDATE_NONE)
-                       continue;
-
-               _proc_get_mem_pss(cpc->pid, &cpc->pss);
-       }
-}
-
-static gint __compare_slot(gconstpointer a, gconstpointer b)
-{
-       candidate_process_context_t *slot_a = (candidate_process_context_t *)a;
-       candidate_process_context_t *slot_b = (candidate_process_context_t *)b;
-
-       if (slot_a->is_hydra && !slot_b->is_hydra)
-               return -1;
-       if (!slot_a->is_hydra && slot_b->is_hydra)
-               return 1;
-
-       if (slot_a->score < slot_b->score)
-               return 1;
-       if (slot_a->score > slot_b->score)
-               return -1;
-
-       if (slot_a->pss < slot_b->pss)
-               return -1;
-       if (slot_a->pss > slot_b->pss)
-               return 1;
-
-       return 0;
-}
-
-static candidate_process_context_t *__get_running_slot(bool is_hydra)
-{
-       candidate_process_context_t *cpc;
-       GList *iter;
-
-       iter = candidate_slot_list;
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (cpc->is_hydra == is_hydra && cpc->pid != CANDIDATE_NONE)
-                       return cpc;
-
-               iter = g_list_next(iter);
-       }
-
-       return NULL;
-}
-
-static void __pause_all_running_slots(bool is_hydra)
-{
-       candidate_process_context_t *cpc = NULL;
-       GList *iter;
-
-       iter = g_list_last(candidate_slot_list);
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (cpc->is_hydra == is_hydra && cpc->pid != CANDIDATE_NONE) {
-                       __update_slot_state(cpc, METHOD_OUT_OF_MEMORY, true);
-                       if (!_memory_monitor_is_low_memory())
-                               return;
-               }
-
-               iter = g_list_previous(iter);
-       }
-}
-
-static void __resume_all_slots(void)
-{
-       candidate_process_context_t *cpc;
-       GList *iter;
-
-       iter = candidate_slot_list;
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               __update_slot_state(cpc, METHOD_AVAILABLE_MEMORY, true);
-
-               iter = g_list_next(iter);
-       }
-}
-
-static void __kill_process(int pid)
-{
-       char err_str[MAX_LOCAL_BUFSZ] = { 0, };
-
-       if (kill(pid, SIGKILL) == -1) {
-               _E("send SIGKILL: %s",
-                               strerror_r(errno, err_str, sizeof(err_str)));
-       }
-}
-
-static void __refuse_candidate_process(int server_fd)
-{
-       int client_fd = -1;
-
-       if (server_fd == -1) {
-               _E("arguments error!");
-               goto error;
-       }
-
-       client_fd = accept(server_fd, NULL, NULL);
-       if (client_fd == -1) {
-               _E("accept error!");
-               goto error;
-       }
-
-       close(client_fd);
-       _D("refuse connection!");
-
-error:
-       return;
-}
-
-static int __accept_candidate_process(int server_fd, int *out_client_fd,
-               int *out_client_pid, int cpc_pid)
-{
-       int client_fd = -1;
-       int recv_pid = 0;
-       int ret;
-       socklen_t len;
-       struct ucred cred = {};
-
-       if (server_fd == -1 || out_client_fd == NULL ||
-                       out_client_pid == NULL) {
-               _E("arguments error!");
-               goto error;
-       }
-
-       client_fd = accept(server_fd, NULL, NULL);
-       if (client_fd == -1) {
-               _E("accept error!");
-               goto error;
-       }
-
-       if (_set_sock_option(client_fd, 1) < 0) {
-               _E("Failed to set sock option");
-               goto error;
-       }
-
-       ret = recv(client_fd, &recv_pid, sizeof(recv_pid), MSG_WAITALL);
-       if (ret == -1) {
-               _E("recv error!");
-               goto error;
-       }
-
-       len = (socklen_t)sizeof(cred);
-       ret = getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &cred, &len);
-       if (ret < 0) {
-               _E("getsockopt error");
-               goto error;
-       }
-
-       if (cpc_pid != -1 && cred.pid != cpc_pid) {
-               _E("Invalid accept. pid(%d)", cred.pid);
-               goto error;
-       }
-
-       if (cred.pid != recv_pid)
-               _W("Not equal recv and real pid");
-
-       *out_client_fd = client_fd;
-       *out_client_pid = cred.pid;
-
-       return *out_client_fd;
-
-error:
-       if (client_fd != -1)
-               close(client_fd);
-
-       return -1;
-}
-
-static int __listen_addr(struct sockaddr_un *addr)
-{
-       int fd = -1;
-       fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-       if (fd < 0) {
-               _E("Socket error");
-               goto error;
-       }
-
-       unlink(addr->sun_path);
-
-       _D("bind to %s", addr->sun_path);
-       if (bind(fd, (struct sockaddr *)addr, sizeof(struct sockaddr_un)) < 0) {
-               _E("bind error");
-               goto error;
-       }
-
-       _D("listen to %s", addr->sun_path);
-       if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) {
-               _E("listen error");
-               goto error;
-       }
-
-       SECURE_LOGD("[launchpad] done, listen fd: %d", fd);
-       return fd;
-
-error:
-       if (fd != -1)
-               close(fd);
-
-       return -1;
-}
-
-static int __listen_candidate_process(int type, int loader_id)
-{
-       struct sockaddr_un addr;
-
-       _D("[launchpad] enter, type: %d", type);
-
-       memset(&addr, 0x00, sizeof(struct sockaddr_un));
-       addr.sun_family = AF_UNIX;
-       snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%u/%s%d-%d",
-                       SOCKET_PATH, getuid(), LAUNCHPAD_LOADER_SOCKET_NAME,
-                       type, loader_id);
-
-       return __listen_addr(&addr);
-}
-
-static int __listen_hydra_process(int type, int loader_id)
-{
-       struct sockaddr_un addr;
-
-       _D("[launchpad] enter, type: %d", type);
-
-       memset(&addr, 0x00, sizeof(struct sockaddr_un));
-       addr.sun_family = AF_UNIX;
-       snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%d/%s%d-%d",
-                       SOCKET_PATH, getuid(), HYDRA_LOADER_SOCKET_NAME,
-                       type, loader_id);
-
-       return __listen_addr(&addr);
-}
-
-static int __get_loader_id(bundle *kb)
-{
-       const char *val;
-
-       val = bundle_get_val(kb, AUL_K_LOADER_ID);
-       if (val == NULL)
-               return -1;
-       _W("Requested loader id: %s", val);
-
-       return atoi(val);
-}
-
-static int __candidate_process_real_launch(int candidate_fd, app_pkt_t *pkt)
-{
-       return _send_pkt_raw(candidate_fd, pkt);
-}
-
-static int __real_send(int clifd, int ret)
-{
-       if (clifd < 3) {
-               _E("Invalid parameter. clifd(%d)", clifd);
-               return -1;
-       }
-
-       if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
-               if (errno == EPIPE) {
-                       _E("send failed due to EPIPE.");
-                       close(clifd);
-                       return -1;
-               }
-               _E("send fail to client");
-       }
-
-       close(clifd);
-       return 0;
-}
-
-static int __fork_app_process(int (*child_fn)(void *), void *arg,
-               int sched_priority)
-{
-       int pid;
-       int ret;
-
-       pid = fork();
-       if (pid == -1) {
-               _E("failed to fork child process");
-               return -1;
-       }
-
-       if (pid == 0) {
-               if (sched_priority != 0)
-                       _set_priority(sched_priority);
-
-               _W("security_manager_prepare_app_candidate ++");
-               ret = security_manager_prepare_app_candidate();
-               _W("security_manager_prepare_app_candidate --");
-               if (ret != SECURITY_MANAGER_SUCCESS) {
-                       _E("failed to prepare app candidate process (%d)", ret);
-                       exit(1);
-               }
-
-               ret = child_fn(arg);
-               _E("failed to exec app process (%d)", errno);
-               exit(ret);
-       }
-
-       return pid;
-}
-
-static int __exec_loader_process(void *arg)
-{
-       char **argv = arg;
-       char err_buf[1024];
-
-       _signal_unblock_sigchld();
-       _close_all_fds();
-       _setup_stdio(basename(argv[LOADER_ARG_PATH]));
-
-       if (execv(argv[LOADER_ARG_PATH], argv) < 0) {
-               _send_message_to_logger(argv[LOADER_ARG_PATH],
-                       "Failed to prepare candidate process. error(%d:%s)",
-                       errno, strerror_r(errno, err_buf, sizeof(err_buf)));
-       } else {
-               _D("Succeeded to prepare candidate_process");
-       }
-
-       return -1;
-}
-
-static gboolean __handle_deactivate_event(gpointer user_data)
-{
-       candidate_process_context_t *cpc;
-
-       cpc = (candidate_process_context_t *)user_data;
-       __update_slot_state(cpc, METHOD_TTL, false);
-       _D("Deactivate event: type(%d)", cpc->type);
-
-       return G_SOURCE_REMOVE;
-}
-
-static void __set_live_timer(candidate_process_context_t *cpc)
-{
-       if (!cpc)
-               return;
-
-       if (cpc->deactivation_method & METHOD_TTL) {
-               if (cpc->live_timer == 0) {
-                       cpc->live_timer = g_timeout_add_seconds(cpc->ttl,
-                                       __handle_deactivate_event, cpc);
-               }
-       }
-}
-
-static int __hydra_send_request(int fd, enum hydra_cmd cmd)
-{
-       int sent = 0;
-       int size = (int)sizeof(cmd);
-       int send_ret = 0;
-
-       while (sent != size) {
-               send_ret = send(fd, (char *)&cmd + sent,
-                               size - sent, MSG_NOSIGNAL);
-               if (send_ret == -1) {
-                       _E("send error! (%d)", errno);
-                       return -1;
-               }
-
-               sent += send_ret;
-               _D("send(%d: ret: %d) : %d / %d",
-                       fd, send_ret, sent, size);
-       }
-
-       return 0;
-}
-
-static int __hydra_send_launch_candidate_request(int fd)
-{
-       SECURE_LOGD("Send launch cmd to hydra, fd: %d", fd);
-       return __hydra_send_request(fd, LAUNCH_CANDIDATE);
-}
-
-static void __candidate_info_free(candidate_info_t *info)
-{
-       int i;
-
-       if (info == NULL)
-               return;
-
-       if (info->argv) {
-               for (i = 0; i < info->argc; i++)
-                       free(info->argv[i]);
-
-               free(info->argv);
-       }
-
-       free(info);
-}
-
-static int __candidate_info_create(candidate_process_context_t *cpt,
-               candidate_info_t **candidate_info)
-{
-       char type_str[12] = {0, };
-       char loader_id_str[12] = {0, };
-       char argbuf[LOADER_ARG_LEN];
-       candidate_info_t *info;
-
-       if (cpt == NULL)
-               return -EINVAL;
-
-       info = calloc(1, sizeof(candidate_info_t));
-       if (info == NULL) {
-               _E("calloc() is failed");
-               return -ENOMEM;
-       }
-
-       info->argv = calloc(LOADER_ARG_DUMMY + 1, sizeof(char *));
-       if (info->argv == NULL) {
-               _E("calloc() is failed");
-               __candidate_info_free(info);
-               return -ENOMEM;
-       }
-
-       memset(argbuf, ' ', LOADER_ARG_LEN);
-       argbuf[LOADER_ARG_LEN - 1] = '\0';
-       info->argv[LOADER_ARG_DUMMY] = strdup(argbuf);
-
-       snprintf(loader_id_str, sizeof(loader_id_str), "%d", cpt->loader_id);
-       snprintf(type_str, sizeof(type_str), "%d", cpt->type);
-       info->argv[LOADER_ARG_PATH] = strdup(cpt->loader_path);
-       info->argv[LOADER_ARG_TYPE] = strdup(type_str);
-       info->argv[LOADER_ARG_ID] = strdup(loader_id_str);
-       info->argv[LOADER_ARG_HYDRA] = strdup(cpt->is_hydra ? "1" : "0");
-       info->argv[LOADER_ARG_EXTRA] = strdup(cpt->loader_extra);
-
-       info->argc = LOADER_ARG_DUMMY + 1;
-       info->type = cpt->type;
-       info->loader_id = cpt->loader_id;
-
-       *candidate_info = info;
-       return 0;
-}
-
-static int __prepare_candidate_process(int type, int loader_id)
-{
-       candidate_process_context_t *cpt = __find_slot(type, loader_id);
-       candidate_info_t *info;
-       int ret;
-
-       if (cpt == NULL)
-               return -1;
-
-       if (cpt->is_hydra && cpt->hydra_pid != HYDRA_NONE)
-               return __hydra_send_launch_candidate_request(cpt->hydra_fd);
-
-       _D("prepare candidate process / type:%d", type);
-       ret = __candidate_info_create(cpt, &info);
-       if (ret < 0)
-               return ret;
-
-       info->pid = __fork_app_process(__exec_loader_process, info->argv,
-                       cpt->sched_priority);
-       if (info->pid == -1) {
-               _E("Failed to create a child process. type: %d", type);
-               __candidate_info_free(info);
-               return -1;
-       }
-
-       _W("Candidate process. type: %d, loader_id: %d, pid: %d",
-                       info->type, info->loader_id, info->pid);
-       cpt = __find_slot(info->type, info->loader_id);
-       if (cpt == NULL) {
-               _E("Not found slot.");
-               __candidate_info_free(info);
-               return -1;
-       }
-
-       cpt->last_exec_time = time(NULL);
-       if (cpt->is_hydra) {
-               cpt->hydra_pid = info->pid;
-       } else {
-               cpt->pid = info->pid;
-               __set_live_timer(cpt);
-       }
-
-       _log_print("[CANDIDATE]", "pid(%7d) | type(%d) | loader(%s)",
-                       info->pid, cpt->loader_id, cpt->loader_name);
-       _memory_monitor_reset_timer();
-       __candidate_info_free(info);
-       return 0;
-}
-
-static gboolean __handle_timeout_event(gpointer user_data)
-{
-       candidate_process_context_t *cpc;
-
-       cpc = (candidate_process_context_t *)user_data;
-       cpc->timer = 0;
-
-       if (cpc->pid != CANDIDATE_NONE) {
-               _W("Candidate(%d) process(%d) is running", cpc->type, cpc->pid);
-               return G_SOURCE_REMOVE;
-       }
-
-       __sequencer_add_slot(cpc);
-       __sequencer_run();
-       return G_SOURCE_REMOVE;
-}
-
-static void __set_timer(candidate_process_context_t *cpc)
-{
-       if (cpc == NULL || cpc->timer > 0)
-               return;
-
-       if ((cpc->detection_method & METHOD_TIMEOUT) &&
-                       cpc->state == CANDIDATE_PROCESS_STATE_RUNNING) {
-               cpc->timer = g_timeout_add(cpc->timeout_val,
-                               __handle_timeout_event, cpc);
-       }
-}
-
-static void __reset_slot(candidate_process_context_t *cpc)
-{
-       if (cpc == NULL)
-               return;
-
-       cpc->send_fd = -1;
-       cpc->prepared = false;
-       cpc->pid = CANDIDATE_NONE;
-       cpc->client_channel = NULL;
-       cpc->timer = 0;
-       cpc->live_timer = 0;
-       cpc->on_boot_timer = 0;
-}
-
-static void __dispose_candidate_process(candidate_process_context_t *cpc)
-{
-       if (!cpc)
-               return;
-
-       _D("Dispose candidate process %d", cpc->type);
-       if (cpc->pid > 0) {
-               _D("kill process %d", cpc->pid);
-               __kill_process(cpc->pid);
-       }
-       if (cpc->live_timer > 0)
-               g_source_remove(cpc->live_timer);
-       if (cpc->client_channel)
-               _io_channel_destroy(cpc->client_channel);
-       if (cpc->timer > 0)
-               g_source_remove(cpc->timer);
-       if (cpc->send_fd > 0)
-               close(cpc->send_fd);
-       if (cpc->on_boot_timer > 0)
-               g_source_remove(cpc->on_boot_timer);
-       __reset_slot(cpc);
-}
-
-static void __dispose_hydra_process(candidate_process_context_t *cpc)
-{
-       if (!cpc)
-               return;
-
-       __dispose_candidate_process(cpc);
-
-       _D("Dispose hydra process %d", cpc->type);
-       if (cpc->hydra_pid > 0) {
-               _D("kill process %d", cpc->hydra_pid);
-               __kill_process(cpc->hydra_pid);
-               cpc->hydra_pid = HYDRA_NONE;
-       }
-
-       if (cpc->hydra_fd > 0) {
-               close(cpc->hydra_fd);
-               cpc->hydra_fd = -1;
-       }
-}
-
-static int __send_launchpad_loader(candidate_process_context_t *cpc,
-               app_pkt_t *pkt, const char *app_path, int clifd)
-{
-       int pid = -1;
-       int ret;
-
-       ret = _delete_sock_path(cpc->pid, getuid());
-       if (ret != 0)
-               return -1;
-
-       __candidate_process_real_launch(cpc->send_fd, pkt);
-       SECURE_LOGD("Request to candidate process, pid: %d, bin path: %s",
-               cpc->pid, app_path);
-
-       pid = cpc->pid;
-       cpc->pid = CANDIDATE_NONE;
-       __dispose_candidate_process(cpc);
-       __set_timer(cpc);
-       __update_slot_score(cpc);
-
-       return pid;
-}
-
-static int __normal_fork_exec(int argc, char **argv, const char *app_path)
-{
-       char *libdir;
-       char err_buf[1024];
-
-       _D("start real fork and exec");
-
-       libdir = _get_libdir(app_path);
-       if (libdir) {
-               setenv("LD_LIBRARY_PATH", libdir, 1);
-               free(libdir);
-       }
-
-       _close_all_fds();
-
-       if (execv(argv[LOADER_ARG_PATH], argv) < 0) { /* Flawfinder: ignore */
-               _send_message_to_logger(argv[LOADER_ARG_PATH],
-                       "Failed to execute a file. error(%d:%s)",
-                       errno, strerror_r(errno, err_buf, sizeof(err_buf)));
-               return -1;
-       }
-       /* never reach*/
-       return 0;
-}
-
-static int __create_launcher_argv(int *argc, char ***argv, const char *app_type)
-{
-       int launcher_argc;
-       char **launcher_argv;
-       launcher_info_h launcher_info;
-       const char *exe;
-       const char *extra_arg;
-       GList *extra_args;
-       GList *iter;
-       int i;
-
-       launcher_info = _launcher_info_find(launcher_info_list, app_type);
-       if (launcher_info == NULL)
-               return 0;
-
-       exe = _launcher_info_get_exe(launcher_info);
-       if (exe == NULL) {
-               _E("Failed to get launcher exe");
-               return -1;
-       }
-
-       extra_args = _launcher_info_get_extra_args(launcher_info);
-       launcher_argc = g_list_length(extra_args) + 1;
-       launcher_argv = (char **)calloc(launcher_argc, sizeof(char *));
-       if (launcher_argv == NULL) {
-               _E("out of memory");
-               return -1;
-       }
-
-       i = LOADER_ARG_PATH;
-       launcher_argv[i++] = strdup(exe);
-
-       iter = g_list_first(extra_args);
-       while (iter) {
-               extra_arg = (const char *)iter->data;
-               if (extra_arg)
-                       launcher_argv[i++] = strdup(extra_arg);
-
-               iter = g_list_next(iter);
-       }
-
-       *argc = launcher_argc;
-       *argv = launcher_argv;
-
-
-       return 0;
-}
-
-static void __destroy_launcher_argv(int argc, char **argv)
-{
-       int i;
-
-       if (argv == NULL)
-               return;
-
-       for (i = 0; i < argc; i++)
-               free(argv[i]);
-       free(argv);
-}
-
-static int __create_app_argv(int *argc, char ***argv, const char *app_path,
-               bundle *kb, const char *app_type)
-{
-       int new_argc;
-       char **new_argv;
-       bool attach = false;
-       struct app_arg debug_arg = {0,};
-       struct app_arg launcher_arg = {0,};
-       struct app_arg arg = {0,};
-       struct app_arg debug_extra_arg = {0,};
-       int ret;
-       int i;
-       int c;
-
-       ret = _debug_create_argv(&debug_arg.argc, &debug_arg.argv, &attach);
-       if (ret < 0) {
-               _E("Failed to create debugger argv");
-               return -1;
-       }
-
-       if (attach) {
-               *argc = debug_arg.argc;
-               *argv = debug_arg.argv;
-               return 0;
-       }
-
-       ret = _debug_create_extra_argv(&debug_extra_arg.argc,
-                       &debug_extra_arg.argv);
-       if (ret < 0) {
-               _E("Failed to create debugger extra argv");
-               _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
-               return -1;
-       }
-
-       ret = __create_launcher_argv(&launcher_arg.argc, &launcher_arg.argv,
-                       app_type);
-       if (ret < 0) {
-               _E("Failed to create launcher argv");
-               _debug_destroy_argv(debug_extra_arg.argc, debug_extra_arg.argv);
-               _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
-               return -1;
-       }
-
-       arg.argc = bundle_export_to_argv(kb, &arg.argv);
-       if (arg.argc <= 0) {
-               _E("Failed to export bundle");
-               __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
-               _debug_destroy_argv(debug_extra_arg.argc, debug_extra_arg.argv);
-               _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
-               return -1;
-       }
-       arg.argv[LOADER_ARG_PATH] = strdup(app_path);
-
-       new_argc = debug_arg.argc + launcher_arg.argc + arg.argc +
-               debug_extra_arg.argc;
-       if (new_argc == arg.argc) {
-               *argc = arg.argc;
-               *argv = arg.argv;
-               return 0;
-       }
-
-       new_argv = (char **)calloc(new_argc + 1, sizeof(char *));
-       if (new_argv == NULL) {
-               _E("out of memory");
-               free(arg.argv[LOADER_ARG_PATH]);
-               bundle_free_exported_argv(arg.argc, &arg.argv);
-               __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
-               _debug_destroy_argv(debug_extra_arg.argc, debug_extra_arg.argv);
-               _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
-               return -1;
-       }
-
-       c = LOADER_ARG_PATH;
-       for (i = 0; i < debug_arg.argc; i++)
-               new_argv[c++] = debug_arg.argv[i];
-       for (i = 0; i < launcher_arg.argc; i++)
-               new_argv[c++] = launcher_arg.argv[i];
-       for (i = 0; i < arg.argc; i++)
-               new_argv[c++] = arg.argv[i];
-       for (i = 0; i < debug_extra_arg.argc; i++)
-               new_argv[c++] = debug_extra_arg.argv[i];
-
-       *argc = new_argc;
-       *argv = new_argv;
-
-       return 0;
-}
-
-static void __real_launch(const char *app_path, bundle *kb,
-               appinfo_t *menu_info)
-{
-       int app_argc = 0;
-       char **app_argv;
-       int i;
-       int ret;
-
-       if (bundle_get_val(kb, AUL_K_DEBUG) != NULL)
-               putenv("TIZEN_DEBUGGING_PORT=1");
-
-       ret = __create_app_argv(&app_argc, &app_argv, app_path,
-                       kb, menu_info->app_type);
-       if (ret < 0) {
-               _E("Failed to create app argv");
-               exit(-1);
-       }
-
-       for (i = 0; i < app_argc; i++)
-               SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
-
-       PERF("setup argument done");
-       __normal_fork_exec(app_argc, app_argv, app_path);
-}
-
-static int __prepare_exec(const char *appid, const char *app_path,
-                       appinfo_t *menu_info, bundle *kb)
-{
-       char *file_name;
-       const char *enabled_light_user;
-       char process_name[AUL_PR_NAME];
-       int ret;
-
-       /* Set new session ID & new process group ID*/
-       /* In linux, child can set new session ID without check permission */
-       /* TODO : should be add to check permission in the kernel*/
-       setsid();
-
-       ret = _launchpad_plugin_prepare_app(appid, kb);
-       if (ret < 0) {
-               _E("_launchpad_plugin_prepare_app() is failed. error(%d)", ret);
-               return PAD_ERR_FAILED;
-       }
-
-       ret = _enable_external_pkg(kb, menu_info->pkgid,
-                       menu_info->global ? GLOBAL_USER : getuid());
-       if (ret < 0)
-               return PAD_ERR_FAILED;
-
-       if (menu_info->global)
-               ret = trust_anchor_launch(menu_info->pkgid, GLOBAL_USER);
-       else
-               ret = trust_anchor_launch(menu_info->pkgid, getuid());
-       if (ret != TRUST_ANCHOR_ERROR_NONE &&
-                       ret != TRUST_ANCHOR_ERROR_NOT_INSTALLED) {
-               _E("trust_anchor_launch() returns %d", ret);
-               return PAD_ERR_REJECTED;
-       }
-
-       ret = _mount_res_dir(menu_info->root_path, kb);
-       if (ret < 0)
-               return PAD_ERR_FAILED;
-
-       if (bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
-               _debug_change_mount_namespace();
-
-       /* SET PRIVILEGES*/
-       enabled_light_user = bundle_get_val(kb, AUL_K_ENABLED_LIGHT_USER);
-       _W("security_manager_prepare_app2 ++ %s", appid);
-       ret = security_manager_prepare_app2(appid, enabled_light_user);
-       _W("security_manager_prepare_app2 -- %s", appid);
-       if (ret != SECURITY_MANAGER_SUCCESS)
-               return PAD_ERR_REJECTED;
-
-       if (bundle_get_type(kb, AUL_K_SDK) == BUNDLE_TYPE_NONE)
-               _setup_stdio(basename(app_path));
-
-       /* SET DUMPABLE - for coredump*/
-       prctl(PR_SET_DUMPABLE, 1);
-
-       /* SET PROCESS NAME*/
-       if (app_path == NULL)
-               return PAD_ERR_INVALID_ARGUMENT;
-
-       file_name = strrchr(app_path, '/');
-       if (file_name == NULL)
-               return PAD_ERR_INVALID_PATH;
-
-       file_name++;
-       if (*file_name == '\0')
-               return PAD_ERR_INVALID_PATH;
-
-       memset(process_name, '\0', AUL_PR_NAME);
-       snprintf(process_name, AUL_PR_NAME, "%s", file_name);
-       prctl(PR_SET_NAME, process_name);
-
-       /* SET ENVIROMENT*/
-       _set_env(menu_info, kb);
-
-       ret = _wait_tep_mount(kb);
-       if (ret < 0)
-               return PAD_ERR_FAILED;
-
-       if (bundle_get_type(kb, AUL_K_SDK) == BUNDLE_TYPE_NONE) {
-               ret = _prepare_app_socket();
-               if (ret < 0)
-                       return PAD_ERR_FAILED;
-
-               ret = _prepare_id_file();
-               if (ret < 0)
-                       return PAD_ERR_FAILED;
-       }
-
-       _send_cmd_to_amd(APP_STARTUP_SIGNAL);
-       return 0;
-}
-
-static int __exec_app_process(void *arg)
-{
-       struct app_launch_arg *launch_arg = arg;
-       int ret;
-
-       _print_hwc_log("%d|after calling fork(). %s",
-                       getpid(), launch_arg->appid);
-       PERF("fork done");
-       _D("lock up test log(no error) : fork done");
-
-       if (bundle_get_type(launch_arg->kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
-               _debug_prepare_debugger(launch_arg->kb);
-
-       _signal_unblock_sigchld();
-
-       _delete_sock_path(getpid(), getuid());
-
-       PERF("prepare exec - first done");
-       ret = __prepare_exec(launch_arg->appid, launch_arg->app_path,
-                       launch_arg->menu_info, launch_arg->kb);
-       if (ret < 0)
-               return ret;
-
-       PERF("prepare exec - second done");
-       __real_launch(launch_arg->app_path, launch_arg->kb,
-                       launch_arg->menu_info);
-
-       return PAD_ERR_FAILED;
-}
-
-static int __launch_directly(const char *appid, const char *app_path, int clifd,
-               bundle *kb, appinfo_t *menu_info,
-               candidate_process_context_t *cpc)
-{
-       struct app_launch_arg arg;
-       int pid;
-
-       arg.appid = appid;
-       arg.app_path = app_path;
-       arg.menu_info = menu_info;
-       arg.kb = kb;
-
-       _print_hwc_log("before calling fork(). %s", appid);
-       pid = __fork_app_process(__exec_app_process, &arg, 0);
-       if (pid <= 0)
-               _E("failed to fork app process");
-
-       SECURE_LOGD("==> real launch pid : %d %s", pid, app_path);
-
-       return pid;
-}
-
-static int __create_sock_activation(void)
-{
-       int fds;
-       char launchpad_process_pool_sock_path[108];
-       int i;
-
-       fds = sd_listen_fds(0);
-       snprintf(launchpad_process_pool_sock_path,
-               sizeof(launchpad_process_pool_sock_path), "%s/daemons/%u/%s",
-                       SOCKET_PATH, getuid(), PROCESS_POOL_LAUNCHPAD_SOCK);
-
-       for (i = SD_LISTEN_FDS_START; i < SD_LISTEN_FDS_START + fds; ++i) {
-               if (sd_is_socket_unix(i, SOCK_STREAM, 1,
-                               launchpad_process_pool_sock_path, 0) > 0)
-                       return i;
-       }
-
-       _W("There is no socket stream");
-       return -1;
-}
-
-static int __get_launchpad_listen_fd(void)
-{
-       const char *val;
-
-       val = getenv("LAUNCHPAD_LISTEN_FD");
-       if (!val) {
-               _E("Failed to get LAUNCHPAD_LISTEN_FD");
-               return -1;
-       }
-
-       _W("Listen Fd: %s", val);
-       return atoi(val);
-}
-
-static int __launchpad_pre_init(int argc, char **argv)
-{
-       int fd;
-
-       /* create launchpad sock */
-       fd = __create_sock_activation();
-       if (fd >= 0)
-               return fd;
-
-       fd = __get_launchpad_listen_fd();
-       if (fd >= 0)
-               return fd;
-
-       fd = _create_server_sock(PROCESS_POOL_LAUNCHPAD_SOCK);
-       if (fd < 0) {
-               _E("server sock error %d", fd);
-               return -1;
-       }
-
-       return fd;
-}
-
-static bool __handle_loader_client_event(int fd, io_condition_e cond,
-               void *data)
-{
-       candidate_process_context_t *cpc = data;
-
-       if (cpc == NULL)
-               return false;
-
-       if (cond & (IO_HUP | IO_NVAL)) {
-               SECURE_LOGE("Type %d candidate process was "
-                               "(POLLHUP|POLLNVAL), pid: %d",
-                               cpc->type, cpc->pid);
-               cpc->pid = CANDIDATE_NONE;
-               __dispose_candidate_process(cpc);
-               __prepare_candidate_process(cpc->type, cpc->loader_id);
-               return false;
-       }
-
-       return true;
-
-}
-
-static bool __handle_hydra_client_event(int fd, io_condition_e cond,
-               void *data)
-{
-       candidate_process_context_t *cpc = data;
-       int recv_pid = -1;
-       int ret;
-
-       if (cpc == NULL)
-               return false;
-
-       if (cond & (IO_HUP | IO_NVAL)) {
-               SECURE_LOGE("Type %d hydra process was "
-                               "(POLLHUP|POLLNVAL), pid: %d",
-                               cpc->type, cpc->hydra_pid);
-               __dispose_hydra_process(cpc);
-               __prepare_candidate_process(cpc->type, cpc->loader_id);
-               return false;
-       }
-
-       if (cond & IO_IN) {
-               ret = recv(cpc->hydra_fd, &recv_pid, sizeof(recv_pid),
-                               MSG_WAITALL);
-               if (ret == -1) {
-                       _E("recv() is failed. errno(%d)", errno);
-               } else {
-                       _W("candidate process: %d", recv_pid);
-                       if (recv_pid > 1)
-                               cpc->pid = recv_pid;
-               }
-       }
-
-       return true;
-}
-
-static bool __handle_loader_event(int fd, io_condition_e cond, void *data)
-{
-       candidate_process_context_t *cpc = data;
-       int client_fd;
-       int client_pid;
-       int ret;
-
-       if (cpc == NULL)
-               return false;
-
-       if (!cpc->prepared) {
-               ret = __accept_candidate_process(fd, &client_fd, &client_pid,
-                                       cpc->is_hydra ? -1 : cpc->pid);
-               if (ret >= 0) {
-                       /* for hydra need to set pid to pid of non-hydra candidate, */
-                       /* which is connecting now */
-                       if (cpc->is_hydra)
-                               cpc->pid = client_pid;
-
-                       cpc->prepared = true;
-                       cpc->send_fd = client_fd;
-
-                       SECURE_LOGI("Type %d candidate process was connected, "
-                                       "pid: %d", cpc->type, cpc->pid);
-
-                       _print_hwc_log("Type %d candidate process was connected, "
-                                       "pid: %d", cpc->type, cpc->pid);
-                       cpc->client_channel = _io_channel_create(client_fd,
-                                       IO_IN | IO_HUP,
-                                       __handle_loader_client_event,
-                                       cpc);
-                       if (!cpc->client_channel)
-                               close(client_fd);
-               }
-       } else {
-               __refuse_candidate_process(fd);
-               _E("Refused candidate process connection");
-       }
-
-       return true;
-}
-
-static bool __handle_hydra_event(int fd, io_condition_e cond, void *data)
-{
-       candidate_process_context_t *cpc = data;
-       int client_fd;
-       int client_pid;
-       int ret;
-
-       if (cpc == NULL)
-               return false;
-
-       if (!cpc->prepared) {
-               ret = __accept_candidate_process(fd, &client_fd, &client_pid,
-                                       cpc->hydra_pid);
-               if (ret >= 0) {
-                       cpc->hydra_fd = client_fd;
-
-                       SECURE_LOGD("Type %d hydra process was connected,"
-                                       " pid: %d", cpc->type, cpc->hydra_pid);
-
-                       cpc->client_channel = _io_channel_create(client_fd,
-                                       IO_IN | IO_HUP,
-                                       __handle_hydra_client_event,
-                                       cpc);
-                       if (!cpc->client_channel)
-                               close(client_fd);
-               }
-       } else {
-               __refuse_candidate_process(fd);
-               _E("Refused hydra process connection");
-       }
-
-       return true;
-}
-
-static void __destroy_cleanup_info(struct cleanup_info_s *info)
-{
-       if (!info)
-               return;
-
-       free(info->appid);
-       free(info);
-}
-
-static struct cleanup_info_s *__create_cleanup_info(const char *appid, int pid)
-{
-       struct cleanup_info_s *info;
-
-       info = malloc(sizeof(struct cleanup_info_s));
-       if (!info) {
-               _E("Out of memory");
-               return NULL;
-       }
-
-       info->appid = strdup(appid);
-       if (!info->appid) {
-               _E("strdup(%s) is failed", appid);
-               __destroy_cleanup_info(info);
-               return NULL;
-       }
-
-       info->pid = pid;
-
-       return info;
-}
-
-static bool __cleanup_app_cb(void *user_data)
-{
-       struct cleanup_info_s *info = (struct cleanup_info_s *)user_data;
-
-       _W("security_manager_cleanup_app() ++");
-       security_manager_cleanup_app(info->appid, getuid(), info->pid);
-       _W("security_manager_cleanup_app() --");
-       __destroy_cleanup_info(info);
-       return false;
-}
-
-static void __handle_sigchild(int pid, void *user_data)
-{
-       candidate_process_context_t *cpc;
-       struct cleanup_info_s *info;
-       char *appid;
-       int ret = -1;
-
-       appid = g_hash_table_lookup(__pid_table, GINT_TO_POINTER(pid));
-       if (appid) {
-               info = __create_cleanup_info(appid, pid);
-               if (info)
-                       ret = _worker_add_job(__cleaner, __cleanup_app_cb, info);
-
-               if (ret != 0) {
-                       __destroy_cleanup_info(info);
-                       _W("security_manager_cleanup_app() ++");
-                       security_manager_cleanup_app(appid, getuid(), pid);
-                       _W("security_manager_cleanup_app() --");
-               }
-
-               g_hash_table_remove(__pid_table, GINT_TO_POINTER(pid));
-       }
-
-       _log_print("[SIGCHLD]", "pid(%7d)", pid);
-       cpc = __find_slot_from_pid(pid);
-       if (cpc != NULL) {
-               cpc->pid = CANDIDATE_NONE;
-               __dispose_candidate_process(cpc);
-               __prepare_candidate_process(cpc->type, cpc->loader_id);
-       } else {
-               cpc = __find_hydra_slot_from_pid(pid);
-               if (cpc != NULL) {
-                       cpc->hydra_pid = HYDRA_NONE;
-                       __dispose_hydra_process(cpc);
-                       __prepare_candidate_process(cpc->type, cpc->loader_id);
-               }
-       }
-
-       cpc = __find_slot_from_caller_pid(pid);
-       while (cpc) {
-               __remove_slot(LAUNCHPAD_LOADER_TYPE_DYNAMIC, cpc->loader_id);
-               cpc = __find_slot_from_caller_pid(pid);
-       }
-}
-
-static bool __handle_label_monitor(int fd, io_condition_e cond, void *data)
-{
-       candidate_process_context_t *cpc;
-       GList *iter = candidate_slot_list;
-
-       if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
-               _E("fd(%d), io_condition(%d)", fd, cond);
-               abort();
-               return false;
-       }
-
-       _D("fd(%d) condition(%d)", fd, cond);
-       _log_print("[LABEL]", "fd(%d), condition(%d)", fd, cond);
-       security_manager_app_labels_monitor_process(label_monitor);
-
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (cpc->is_hydra) {
-                       if (cpc->hydra_pid > 0) {
-                               __dispose_hydra_process(cpc);
-                               __prepare_candidate_process(cpc->type,
-                                               cpc->loader_id);
-                       }
-               } else if (cpc->pid > 0) {
-                       __dispose_candidate_process(cpc);
-                       __prepare_candidate_process(cpc->type, cpc->loader_id);
-               }
-
-               iter = g_list_next(iter);
-       }
-
-       return true;
-}
-
-static float __interpolator(float input, int cpu_max, int cpu_min)
-{
-       float ret;
-       float min = cpu_min / 100.0f;
-       float max = cpu_max / 100.0f;
-
-       if (input > 1.0f)
-               input = 1.0f;
-       if (input < 0.0f)
-               input = 0.0f;
-
-       ret = cos(input * PI) / 2.0f + 0.5f;
-       ret *= max - min;
-       ret += min;
-
-       return ret;
-}
-
-static void __update_threshold(candidate_process_context_t *cpc, float delta)
-{
-       static float pos = 0.0f;
-
-       pos += delta;
-       if (pos < 0.0f)
-               pos = 0.0f;
-
-       if (pos > 1.0f)
-               pos = 1.0f;
-
-       cpc->threshold = (int)(__interpolator(pos,
-                               cpc->threshold_max, cpc->threshold_min) * 100);
-       _D("[CPU] type:%d / delta:%f / input cursor : %f / threshold : %d",
-                       cpc->type, delta, pos, cpc->threshold);
-}
-
-static gboolean __handle_idle_checker(gpointer data)
-{
-       unsigned long long total = 0;
-       unsigned long long idle = 0;
-       int per;
-       candidate_process_context_t *cpc;
-
-       if (!data) {
-               _E("Critical error!");
-               __sequencer.idle_checker = 0;
-               __sequencer.running_cpc = NULL;
-               return G_SOURCE_REMOVE;
-       }
-
-       cpc = (candidate_process_context_t *)data;
-       if (cpc->app_check && !cpc->app_exists) {
-               _W("The application is not installed. loader(%s:%d)",
-                               cpc->loader_name, cpc->type);
-               __sequencer.idle_checker = 0;
-               __sequencer.running_cpc = NULL;
-               return G_SOURCE_REMOVE;
-       }
-
-       if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING) {
-               _W("Slot state is not running. loader(%s:%d)",
-                               cpc->loader_name, cpc->type);
-               __sequencer.idle_checker = 0;
-               __sequencer.running_cpc = NULL;
-               return G_SOURCE_REMOVE;
-       }
-
-       if (cpc->pid != CANDIDATE_NONE) {
-               _W("Slot is already running. %d:%s:%d",
-                               cpc->type, cpc->loader_name, cpc->pid);
-               __sequencer.idle_checker = 0;
-               __sequencer.running_cpc = NULL;
-               return G_SOURCE_REMOVE;
-       }
-
-       _get_cpu_idle(&total, &idle);
-       if (total == cpc->cpu_total_time)
-               total++;
-
-       per = (idle - cpc->cpu_idle_time) * 100 / (total - cpc->cpu_total_time);
-       _D("[CPU] Idle : %d / loader(%s:%d)", per, cpc->loader_name, cpc->type);
-
-       if (per >= cpc->threshold) {
-               __update_threshold(cpc, -0.02f * (per - cpc->threshold));
-               __prepare_candidate_process(cpc->type, cpc->loader_id);
-               cpc->touched = true;
-               __sequencer.idle_checker = 0;
-               __sequencer.running_cpc = NULL;
-               return G_SOURCE_REMOVE;
-       }
-
-       cpc->cpu_idle_time = idle;
-       cpc->cpu_total_time = total;
-       __update_threshold(cpc, 0.05f);
-
-       cpc->cpu_check_count++;
-       if (cpc->cpu_check_count == MAX_CPU_CHECK_COUNT) {
-               _W("CPU check count has exceeded %d times. loader(%s:%d)",
-                               cpc->cpu_check_count,
-                               cpc->loader_name,
-                               cpc->type);
-               __sequencer.idle_checker = 0;
-               __sequencer.running_cpc = NULL;
-               __sequencer_add_slot(cpc);
-               return G_SOURCE_REMOVE;
-       }
-
-       return G_SOURCE_CONTINUE;
-}
-
-static gboolean __on_boot_timeout_cb(gpointer user_data)
-{
-       candidate_process_context_t *context = user_data;
-
-       _W("type(%d), loader_name(%s)", context->type, context->loader_name);
-       context->on_boot_timer = 0;
-       if (context->pid != CANDIDATE_NONE) {
-               _E("Candidate process is already running. %d:%s:%d",
-                               context->type, context->loader_name,
-                               context->pid);
-       } else {
-               __prepare_candidate_process(context->type, context->loader_id);
-               context->touched = true;
-       }
-
-       return G_SOURCE_REMOVE;
-}
-
-static void __add_on_boot_timer(candidate_process_context_t *context)
-{
-       if (context->on_boot_timer != 0)
-               return;
-
-       context->on_boot_timer = g_timeout_add(context->on_boot_timeout,
-                       __on_boot_timeout_cb, context);
-}
-
-static int __add_idle_checker(int detection_method, GList *cur)
-{
-       candidate_process_context_t *cpc;
-       GList *iter = cur;
-
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (!cpc->touched && cpc->on_boot && cpc->on_boot_timeout > 0)
-                       __add_on_boot_timer(cpc);
-
-               if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING) {
-                       iter = g_list_next(iter);
-                       continue;
-               }
-
-               if (strcmp("null", cpc->loader_path) == 0) {
-                       iter = g_list_next(iter);
-                       continue;
-               }
-
-               if (!cpc->touched && !cpc->on_boot) {
-                       iter = g_list_next(iter);
-                       continue;
-               }
-
-               if (cpc->app_check && !cpc->app_exists) {
-                       iter = g_list_next(iter);
-                       continue;
-               }
-
-               if (cpc->pid == CANDIDATE_NONE &&
-                               (!cpc->touched ||
-                                (cpc->detection_method & detection_method))) {
-                       if (cpc->timer > 0) {
-                               g_source_remove(cpc->timer);
-                               cpc->timer = 0;
-                       }
-
-                       cpc->cur_event = detection_method;
-                       __sequencer_add_slot(cpc);
-                       __sequencer_run();
-               }
-
-               iter = g_list_next(iter);
-       }
-
-       return -1;
-}
-
-static int __dispatch_cmd_hint(bundle *kb, int detection_method)
-{
-       _W("cmd hint %d", detection_method);
-       __add_idle_checker(detection_method, candidate_slot_list);
-
-       return 0;
-}
-
-static int __dispatch_cmd_add_loader(bundle *kb)
-{
-       const char *add_slot_str = NULL;
-       const char *caller_pid = NULL;
-       const char *extra;
-       int lid, size;
-       char *loader_name;
-       candidate_process_context_t *cpc;
-       slot_info_t slot_info;
-
-       _W("cmd add loader");
-       add_slot_str = bundle_get_val(kb, AUL_K_LOADER_PATH);
-       caller_pid = bundle_get_val(kb, AUL_K_CALLER_PID);
-       extra = bundle_get_val(kb, AUL_K_LOADER_EXTRA);
-
-       if (add_slot_str == NULL || caller_pid == NULL)
-               return -1;
-
-       lid = __make_loader_id();
-       size = snprintf(0, 0, "%s%s%d", add_slot_str, caller_pid, lid);
-       loader_name = (char *)malloc(size + 1);
-       if (loader_name == NULL) {
-               _E("Out of memory");
-               return -1;
-       }
-
-       snprintf(loader_name, size, "%s%s%d", add_slot_str, caller_pid, lid);
-
-       slot_info.type = LAUNCHPAD_LOADER_TYPE_DYNAMIC;
-       slot_info.loader_id = lid;
-       slot_info.caller_pid = atoi(caller_pid);
-       slot_info.loader_name = loader_name;
-       slot_info.loader_path = add_slot_str;
-       slot_info.loader_extra = extra;
-       slot_info.detection_method = METHOD_TIMEOUT | METHOD_VISIBILITY;
-       slot_info.activation_method = METHOD_REQUEST | METHOD_AVAILABLE_MEMORY;
-       slot_info.deactivation_method = METHOD_TTL | METHOD_OUT_OF_MEMORY;
-       slot_info.ttl = 600;
-       slot_info.timeout_val = 2000;
-       slot_info.threshold_max = DEFAULT_CPU_THRESHOLD_MAX;
-       slot_info.threshold_min = DEFAULT_CPU_THRESHOLD_MIN;
-       slot_info.on_boot = false;
-       slot_info.app_exists = true;
-       slot_info.is_hydra = false;
-       slot_info.app_check = true;
-       slot_info.on_boot_timeout = 0;
-       slot_info.sched_priority = 0;
-
-       cpc = __add_slot(&slot_info);
-       free(loader_name);
-       if (cpc == NULL)
-               return -1;
-
-       __set_timer(cpc);
-       return lid;
-}
-
-static int __dispatch_cmd_add_app_defined_loader(bundle *kb)
-{
-       const char *loader_name;
-       int lid, len;
-       candidate_process_context_t *cpc;
-       loader_info_t *info;
-       bundle_raw *extra;
-       slot_info_t slot_info;
-
-       _W("cmd add defined loader");
-       loader_name = bundle_get_val(kb, AUL_K_LOADER_NAME);
-
-       if (loader_name == NULL) {
-               _E("loader_name is NULL");
-               return -EINVAL;
-       }
-
-       info = _loader_info_find_loader_by_loader_name(
-                       app_defined_loader_info_list, loader_name);
-       if (info == NULL || info->extra == NULL) {
-               _E("loader_name %s, info  %d", loader_name, info != NULL);
-               return -EINVAL;
-       }
-
-
-       cpc = __find_slot_from_loader_name(loader_name);
-       if (cpc == NULL) {
-               lid = __make_loader_id();
-               bundle_encode(info->extra, &extra, &len);
-               slot_info.type = LAUNCHPAD_LOADER_TYPE_DYNAMIC;
-               slot_info.loader_id = lid;
-               slot_info.caller_pid = 0;
-               slot_info.loader_name = loader_name;
-               slot_info.loader_path = "/usr/bin/app-defined-loader";
-               slot_info.loader_extra = (const char *)extra;
-               slot_info.detection_method = METHOD_TIMEOUT | METHOD_VISIBILITY;
-               slot_info.activation_method =
-                       METHOD_REQUEST | METHOD_AVAILABLE_MEMORY;
-               slot_info.deactivation_method =
-                       METHOD_TTL | METHOD_OUT_OF_MEMORY;
-               slot_info.ttl = info->ttl;
-               slot_info.timeout_val = 2000;
-               slot_info.threshold_max = DEFAULT_CPU_THRESHOLD_MAX;
-               slot_info.threshold_min = DEFAULT_CPU_THRESHOLD_MIN;
-               slot_info.on_boot = false;
-               slot_info.app_exists = true;
-               slot_info.is_hydra = false;
-               slot_info.app_check = true;
-               slot_info.on_boot_timeout = 0;
-               slot_info.sched_priority = 0;
-
-               cpc = __add_slot(&slot_info);
-               bundle_free_encoded_rawdata(&extra);
-               if (cpc == NULL) {
-                       _E("cpc is NULL");
-                       return -ENOMEM;
-               }
-       } else {
-               lid = cpc->loader_id;
-       }
-
-       if (cpc->pid == CANDIDATE_NONE)
-               __prepare_candidate_process(LAUNCHPAD_LOADER_TYPE_DYNAMIC, lid);
-
-       return lid;
-}
-
-static int __dispatch_cmd_remove_loader(bundle *kb)
-{
-       const char *id = bundle_get_val(kb, AUL_K_LOADER_ID);
-       int lid;
-
-       _W("cmd remove loader");
-       if (id) {
-               lid = atoi(id);
-               if (__remove_slot(LAUNCHPAD_LOADER_TYPE_DYNAMIC, lid) == 0)
-                       return 0;
-       }
-
-       return -1;
-}
-
-static int __check_caller_by_pid(int pid)
-{
-       int ret;
-       char buf[PATH_MAX] = { 0, };
-
-       ret = _proc_get_attr(pid, buf, sizeof(buf));
-       if (ret < 0)
-               return -1;
-
-       if (strcmp(buf, "User") == 0 ||
-                       strcmp(buf, "System") == 0 ||
-                       strcmp(buf, "System::Privileged") == 0)
-               return 0;
-
-       return -1;
-}
-
-static bool __is_hw_acc(const char *hwacc)
-{
-       if (strcmp(hwacc, "USE") == 0 ||
-               (strcmp(hwacc, "SYS") == 0 &&
-                       __sys_hwacc == SETTING_HW_ACCELERATION_ON))
-               return true;
-
-       return false;
-}
-
-static candidate_process_context_t *__find_available_slot(const char *hwacc,
-               const char *app_type, const char *loader_name,
-               candidate_process_context_t **org_cpc)
-{
-       int type;
-       candidate_process_context_t *cpc;
-       int *a_types;
-       int len = 0;
-       int i;
-
-       if (loader_name) {
-               type = _loader_info_find_type_by_loader_name(loader_info_list,
-                               loader_name);
-       } else {
-               type = _loader_info_find_type(loader_info_list,
-                               app_type, __is_hw_acc(hwacc));
-       }
-       cpc = __find_slot(type, PAD_LOADER_ID_STATIC);
-       if (!cpc)
-               return NULL;
-
-       *org_cpc = cpc;
-
-       if (cpc->prepared)
-               return cpc;
-
-       a_types = _loader_get_alternative_types(loader_info_list, type, &len);
-       if (!a_types)
-               return NULL;
-
-       for (i = 0; i < len; i++) {
-               cpc = __find_slot(a_types[i], PAD_LOADER_ID_STATIC);
-               if (!cpc)
-                       continue;
-               if (cpc->prepared) {
-                       free(a_types);
-                       return cpc;
-               }
-       }
-
-       free(a_types);
-       return NULL;
-}
-
-static void __update_slot(int type, bool app_exists)
-{
-       candidate_process_context_t *cpc;
-
-       cpc = __find_slot(type, PAD_LOADER_ID_STATIC);
-       if (!cpc)
-               return;
-
-       cpc->app_exists = app_exists;
-       if (cpc->app_check && !cpc->app_exists) {
-               if (cpc->pid > 0)
-                       __dispose_candidate_process(cpc);
-               __sequencer_remove_slot(cpc);
-               if (__sequencer_queue_is_empty())
-                       __sequencer_stop();
-       } else {
-               if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING)
-                       return;
-
-               if (!cpc->touched && !cpc->on_boot)
-                       return;
-
-               if (cpc->timer > 0) {
-                       g_source_remove(cpc->timer);
-                       cpc->timer = 0;
-               }
-
-               if (cpc->pid == CANDIDATE_NONE) {
-                       __sequencer_add_slot(cpc);
-                       __sequencer_run();
-               }
-       }
-}
-
-static void __foreach_loader_info(loader_info_t *info, void *data)
-{
-       struct app_info *ai = (struct app_info *)data;
-       bool exist;
-
-       exist = _loader_info_exist_app_type(info, ai->type);
-       if (!exist)
-               return;
-
-       info->app_exists = ai->exists;
-       __update_slot(info->type, info->app_exists);
-}
-
-static int __dispatch_cmd_update_app_type(bundle *b)
-{
-       int r;
-       struct app_info info;
-       const char *is_installed;
-
-       info.type = bundle_get_val(b, AUL_K_APP_TYPE);
-       if (!info.type)
-               return -1;
-
-       is_installed = bundle_get_val(b, AUL_K_IS_INSTALLED);
-       if (is_installed && !strcmp(is_installed, "true"))
-               info.exists = true;
-       else
-               info.exists = false;
-
-       _I("[LAUNCHPAD] type(%s), exists(%d)", info.type, info.exists);
-
-       r = _loader_info_foreach(loader_info_list, __foreach_loader_info,
-                       &info);
-       if (r != 0) {
-               _E("Failed to retrieve loader info");
-               return -1;
-       }
-
-       return 0;
-}
-
-static void __deactivate_slot(candidate_process_context_t *cpc)
-{
-       if (cpc->state == CANDIDATE_PROCESS_STATE_PAUSED)
-               return;
-
-       cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
-       if (cpc->is_hydra)
-               __dispose_hydra_process(cpc);
-       else
-               __dispose_candidate_process(cpc);
-}
-
-static void __activate_slot(candidate_process_context_t *cpc)
-{
-       if (cpc->state == CANDIDATE_PROCESS_STATE_RUNNING)
-               return;
-
-       cpc->state = CANDIDATE_PROCESS_STATE_RUNNING;
-       if (!cpc->touched && !cpc->on_boot)
-               return;
-
-       if ((cpc->app_check && !cpc->app_exists) || cpc->pid > CANDIDATE_NONE)
-               return;
-
-       if (cpc->detection_method & METHOD_TIMEOUT)
-               __set_timer(cpc);
-}
-
-static void __update_slot_state(candidate_process_context_t *cpc, int method,
-               bool force)
-{
-       switch (method) {
-       case METHOD_OUT_OF_MEMORY:
-               if ((force || cpc->deactivation_method & method) &&
-                               __is_low_memory()) {
-                       _W("Low memory, deactivate slot %d", cpc->type);
-                       __deactivate_slot(cpc);
-               } else {
-                       __activate_slot(cpc);
-               }
-               break;
-       case METHOD_TTL:
-               if (force || cpc->deactivation_method & method)
-                       __deactivate_slot(cpc);
-               break;
-       case METHOD_AVAILABLE_MEMORY:
-               if (force || cpc->activation_method & method)
-                       __activate_slot(cpc);
-               break;
-       case METHOD_REQUEST:
-               if (force || cpc->activation_method & method)
-                       __update_slot_state(cpc, METHOD_OUT_OF_MEMORY, force);
-               break;
-       default:
-               __activate_slot(cpc);
-               break;
-       }
-}
-
-static void __request_destroy(request_t *request)
-{
-       if (request == NULL)
-               return;
-
-       if (request->clifd > -1)
-               close(request->clifd);
-       if (request->menu_info)
-               _appinfo_free(request->menu_info);
-       if (request->kb)
-               bundle_free(request->kb);
-       if (request->pkt)
-               free(request->pkt);
-       free(request);
-}
-
-static int __request_create(int fd, request_t **request)
-{
-       struct ucred cr;
-       request_t *req;
-
-       if (request == NULL) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       req = calloc(1, sizeof(request_t));
-       if (req == NULL) {
-               _E("calloc() is failed");
-               return -ENOMEM;
-       }
-
-       req->clifd = -1;
-       req->pkt = _accept_recv_pkt_raw(fd, &req->clifd, &cr);
-       if (req->pkt == NULL) {
-               _E("_accept_recv_pkt_raw() is failed");
-               __request_destroy(req);
-               return -ECOMM;
-       }
-
-       req->kb = bundle_decode(req->pkt->data, req->pkt->len);
-       if (req->kb == NULL) {
-               _E("bundle_decode() is failed");
-               __real_send(req->clifd, -EINVAL);
-               req->clifd = -1;
-               __request_destroy(req);
-               return -EINVAL;
-       }
-
-       req->cmd = req->pkt->cmd;
-       req->caller_pid = cr.pid;
-       req->caller_uid = cr.uid;
-       *request = req;
-       return 0;
-}
-
-static void __request_send_result(request_h request, int result)
-{
-       if (request->clifd < 0)
-               return;
-
-       __real_send(request->clifd, result);
-       request->clifd = -1;
-}
-
-static int __visibility_request_handler(request_h request)
-{
-       int ret = __dispatch_cmd_hint(request->kb, METHOD_VISIBILITY);
-
-       __request_send_result(request, ret);
-       _D("[PAD_CMD_VISIBILITY] result: %d", ret);
-       return ret;
-}
-
-static int __add_loader_request_handler(request_h request)
-{
-       int ret = __dispatch_cmd_add_loader(request->kb);
-
-       __request_send_result(request, ret);
-       _D("[PAD_CMD_ADD_LOADER] result: %d", ret);
-       return ret;
-}
-
-static int __remove_loader_request_handler(request_h request)
-{
-       int ret = __dispatch_cmd_remove_loader(request->kb);
-
-       __request_send_result(request, ret);
-       _D("[PAD_CMD_REMOVE_LOADER] result: %d", ret);
-       return ret;
-}
-
-static int __make_default_slots_request_handler(request_h request)
-{
-       int ret = __add_default_slots();
-
-       __request_send_result(request, ret);
-       _D("[PAD_CMD_MAKE_DEFAULT_SLOTS] result: %d", ret);
-       return ret;
-}
-
-static int __prepare_app_defined_loader_request_handler(request_h request)
-{
-       int ret = __dispatch_cmd_add_app_defined_loader(request->kb);
-
-       __request_send_result(request, ret);
-       _D("[PAD_CMD_PREPARE_APP_DEFINED_LOADER] result: %d", ret);
-       return ret;
-}
-
-static int __demand_request_handler(request_h request)
-{
-       int ret = __dispatch_cmd_hint(request->kb, METHOD_DEMAND);
-
-       __request_send_result(request, ret);
-       _D("[PAD_CMD_DEMAND] result: %d", ret);
-       return ret;
-}
-
-static int __ping_request_handler(request_h request)
-{
-       __request_send_result(request, getpid());
-       _D("[PAD_CMD_PING] result: %d", getpid());
-       return 0;
-}
-
-static int __update_app_type_request_handler(request_h request)
-{
-       int ret = __dispatch_cmd_update_app_type(request->kb);
-
-       _D("[PAD_CMD_UPDATE_APP_TYPE] result: %d", ret);
-       return ret;
-}
-
-static int __connect_request_handler(request_h request)
-{
-       if (__client_fd != -1)
-               close(__client_fd);
-
-       __client_fd = request->clifd;
-       request->clifd = -1;
-       _D("[PAD_CMD_CONNECT] client fd: %d", __client_fd);
-       return 0;
-}
-
-static int __launch_request_prepare(request_h request)
-{
-       const appinfo_t *menu_info;
-       int type = -1;
-
-       request->menu_info = _appinfo_create(request->kb);
-       if (request->menu_info == NULL) {
-               _E("_appinfo_create() is failed");
-               return -1;
-       }
-
-       request->app_path = _appinfo_get_app_path(request->menu_info);
-       if (request->app_path == NULL) {
-               _E("_appinfo_get_app_path() is failed");
-               return -1;
-       }
-
-       if (request->app_path[0] != '/') {
-               _E("app path is not absolute path");
-               return -1;
-       }
-
-       menu_info = request->menu_info;
-       if (menu_info->hwacc == NULL) {
-               _E("Failed to find HW acceeleration type");
-               return -1;
-       }
-
-       SECURE_LOGD("appid: %s", menu_info->appid);
-       SECURE_LOGD("exec: %s", menu_info->app_path);
-       SECURE_LOGD("comp_type: %s", menu_info->comp_type);
-       SECURE_LOGD("internal pool: %s", menu_info->internal_pool);
-       SECURE_LOGD("hwacc: %s", menu_info->hwacc);
-       SECURE_LOGD("app_type: %s", menu_info->app_type);
-       SECURE_LOGD("pkg_type: %s", menu_info->pkg_type);
-
-       if (menu_info->comp_type && !strcmp(menu_info->comp_type, "svcapp")) {
-               request->loader_id = __get_loader_id(request->kb);
-               if (request->loader_id > PAD_LOADER_ID_DYNAMIC_BASE) {
-                       type = LAUNCHPAD_LOADER_TYPE_DYNAMIC;
-                       request->cpc = __find_slot(type, request->loader_id);
-                       if (request->cpc && !request->cpc->prepared)
-                               request->cpc = NULL;
-               } else {
-                       request->loader_id = PAD_LOADER_ID_DIRECT;
-               }
-       } else if (menu_info->comp_type && menu_info->app_type &&
-                       !strcmp(menu_info->comp_type, "widgetapp") &&
-                       !strcmp(menu_info->app_type, "webapp")) {
-               request->loader_id = PAD_LOADER_ID_DIRECT;
-       } else {
-               request->loader_id = __get_loader_id(request->kb);
-               if (request->loader_id <= PAD_LOADER_ID_STATIC) {
-                       request->cpc = __find_available_slot(menu_info->hwacc,
-                                       menu_info->app_type,
-                                       menu_info->loader_name,
-                                       &request->org_cpc);
-               } else {
-                       type = LAUNCHPAD_LOADER_TYPE_DYNAMIC;
-                       request->cpc = __find_slot(type, request->loader_id);
-                       if (request->cpc && !request->cpc->prepared)
-                               request->cpc = NULL;
-               }
-       }
-
-       _modify_bundle(request->kb, request->caller_pid, request->menu_info,
-                       request->cmd);
-       if (menu_info->appid == NULL) {
-               _E("Unable to get appid from app info");
-               return -1;
-       }
-
-       PERF("Getting package information & modifying bundle done");
-       return 0;
-}
-
-static void __launch_request_complete(request_h request)
-{
-       _memory_monitor_reset_timer();
-       __request_send_result(request, request->pid);
-
-       if (request->pid > 0) {
-               _dbus_send_app_launch_signal(request->pid,
-                               request->menu_info->appid);
-               g_hash_table_insert(__pid_table, GINT_TO_POINTER(request->pid),
-                               strdup(request->menu_info->appid));
-               _log_print("[LAUNCH]", "pid(%7d) | appid(%s)",
-                               request->pid, request->menu_info->appid);
-       }
-}
-
-static void __handle_direct_launch(request_h request)
-{
-       if (request->org_cpc && (!request->org_cpc->app_check ||
-                               request->org_cpc->app_exists) &&
-                       request->org_cpc->pid == CANDIDATE_NONE &&
-                       !__sequencer_slot_exist(request->org_cpc)) {
-               if (request->org_cpc->timer > 0) {
-                       g_source_remove(request->org_cpc->timer);
-                       request->org_cpc->timer = 0;
-               }
-
-               __update_slot_state(request->org_cpc, METHOD_REQUEST, true);
-               __set_timer(request->org_cpc);
-       }
-}
-
-static void __fork_processing(request_h request)
-{
-       if (bundle_get_type(request->kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
-               _debug_init();
-
-       _W("appid: %s", request->menu_info->appid);
-       request->pid = __launch_directly(request->menu_info->appid,
-                       request->app_path, request->clifd, request->kb,
-                       request->menu_info, NULL);
-       if (request->pid == -1) {
-               _E("Failed to create a child process. appid(%s)",
-                               request->menu_info->appid);
-       }
-
-       __request_send_result(request, request->pid);
-       _W("appid: %s, pid: %d", request->menu_info->appid, request->pid);
-       __handle_direct_launch(request);
-}
-
-static int __launch_request_do(request_h request)
-{
-       if (request->loader_id == PAD_LOADER_ID_DIRECT ||
-                       request->cpc == NULL) {
-               __fork_processing(request);
-               return 0;
-       }
-
-       _W("Launch %d type process. appid(%s)",
-                       request->cpc->type, request->menu_info->appid);
-       request->pid = __send_launchpad_loader(request->cpc, request->pkt,
-                       request->app_path, request->clifd);
-       return 0;
-}
-
-static int __launch_request_handler(request_h request)
-{
-       int ret;
-
-       traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "LAUNCHPAD:LAUNCH");
-       INIT_PERF(kb);
-       PERF("Packet processing start");
-
-       ret = __launch_request_prepare(request);
-       if (ret < 0) {
-               traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
-               __request_send_result(request, ret);
-               return ret;
-       }
-
-       ret = __launch_request_do(request);
-       if (ret < 0)
-               request->pid = ret;
-
-       __launch_request_complete(request);
-       traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
-       _D("[PAD_CMD_LAUNCH] appid: %s, result: %d",
-                       request->menu_info->appid, request->pid);
-       return 0;
-}
-
-static request_handler __request_handlers[] = {
-       [PAD_CMD_VISIBILITY] = __visibility_request_handler,
-       [PAD_CMD_ADD_LOADER] = __add_loader_request_handler,
-       [PAD_CMD_REMOVE_LOADER] = __remove_loader_request_handler,
-       [PAD_CMD_MAKE_DEFAULT_SLOTS] = __make_default_slots_request_handler,
-       [PAD_CMD_PREPARE_APP_DEFINED_LOADER] =
-               __prepare_app_defined_loader_request_handler,
-       [PAD_CMD_DEMAND] = __demand_request_handler,
-       [PAD_CMD_PING] = __ping_request_handler,
-       [PAD_CMD_UPDATE_APP_TYPE] = __update_app_type_request_handler,
-       [PAD_CMD_CONNECT] = __connect_request_handler,
-       [PAD_CMD_LAUNCH] = __launch_request_handler,
-};
-
-static bool __handle_launch_event(int fd, io_condition_e cond, void *data)
-{
-       request_t *request = NULL;
-       int ret;
-
-       if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
-               _E("fd(%d), condition(%d)", fd, cond);
-               g_idle_add(__launchpad_recovery_cb, __launchpad_channel);
-               __launchpad_channel = NULL;
-               return false;
-       }
-
-       ret = __request_create(fd, &request);
-       if (ret != 0)
-               return true;
-
-       _W("cmd(%d), caller(%d)", request->cmd, request->caller_pid);
-       if (request->caller_uid >= REGULAR_UID_MIN) {
-               if (__check_caller_by_pid(request->caller_pid) < 0) {
-                       _E("Permission denied. pid(%d)", request->caller_pid);
-                       __request_send_result(request, -EPERM);
-                       __request_destroy(request);
-                       return true;
-               }
-       }
-
-       if (request->cmd < 0 || request->cmd >= ARRAY_SIZE(__request_handlers)
-                       || __request_handlers[request->cmd] == NULL) {
-               _E("Unknown command: %d", request->cmd);
-               __request_send_result(request, -EINVAL);
-               __request_destroy(request);
-               return true;
-       }
-
-       __request_handlers[request->cmd](request);
-       __request_destroy(request);
-       return true;
-}
-
-static void __destroy_slot(candidate_process_context_t *cpc)
-{
-       if (!cpc)
-               return;
-
-       if (cpc->hydra_channel)
-               _io_channel_destroy(cpc->hydra_channel);
-
-       if (cpc->channel)
-               _io_channel_destroy(cpc->channel);
-
-       if (cpc->loader_extra)
-               free(cpc->loader_extra);
-
-       if (cpc->loader_path)
-               free(cpc->loader_path);
-
-       if (cpc->loader_name)
-               free(cpc->loader_name);
-
-       free(cpc);
-}
-
-static candidate_process_context_t *__create_slot(slot_info_t *info)
-{
-       candidate_process_context_t *cpc;
-
-       cpc = calloc(1, sizeof(candidate_process_context_t));
-       if (cpc == NULL) {
-               _E("Out of memory");
-               return NULL;
-       }
-
-       cpc->loader_name = strdup(info->loader_name);
-       if (cpc->loader_name == NULL) {
-               _E("Failed to duplicate loader name(%s)", info->loader_name);
-               __destroy_slot(cpc);
-               return NULL;
-       }
-
-       cpc->loader_path = strdup(info->loader_path);
-       if (cpc->loader_path == NULL) {
-               _E("Failed to duplicate loader path(%s)", info->loader_path);
-               __destroy_slot(cpc);
-               return NULL;
-       }
-
-       cpc->loader_extra =
-               info->loader_extra ? strdup(info->loader_extra) : strdup("");
-       if (cpc->loader_extra == NULL) {
-               _E("Failed to duplicate loader extra(%s)", info->loader_extra);
-               __destroy_slot(cpc);
-               return NULL;
-       }
-
-       cpc->type = info->type;
-       cpc->prepared = false;
-       cpc->pid = CANDIDATE_NONE;
-       cpc->hydra_pid = HYDRA_NONE;
-       cpc->caller_pid = info->caller_pid;
-       cpc->loader_id = info->loader_id;
-       cpc->send_fd = -1;
-       cpc->hydra_fd = -1;
-       cpc->last_exec_time = 0;
-       cpc->timer = 0;
-       cpc->detection_method = info->detection_method;
-       cpc->timeout_val = info->timeout_val;
-       cpc->cpu_total_time = 0;
-       cpc->cpu_idle_time = 0;
-       cpc->threshold = info->threshold_max;
-       cpc->threshold_max = info->threshold_max;
-       cpc->threshold_min = info->threshold_min;
-       cpc->on_boot = info->on_boot;
-       cpc->app_exists = info->app_exists;
-       cpc->touched = false;
-       cpc->cur_event = 0;
-       cpc->activation_method = info->activation_method;
-       cpc->deactivation_method = info->deactivation_method;
-       cpc->ttl = info->ttl;
-       cpc->live_timer = 0;
-       cpc->is_hydra = info->is_hydra;
-       cpc->app_check = info->app_check;
-       cpc->score = WIN_SCORE;
-       cpc->pss = 0;
-       cpc->cpu_check_count = 0;
-       cpc->on_boot_timeout = info->on_boot_timeout;
-       cpc->sched_priority = info->sched_priority;
-
-       if ((cpc->deactivation_method & METHOD_OUT_OF_MEMORY) &&
-                       __is_low_memory())
-               cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
-       else
-               cpc->state = CANDIDATE_PROCESS_STATE_RUNNING;
-
-       _W("loader(%s), type(%d), state(%d)",
-                       cpc->loader_name, cpc->type, cpc->state);
-       return cpc;
-}
-
-static candidate_process_context_t *__add_slot(slot_info_t *info)
-{
-       candidate_process_context_t *cpc;
-       int fd;
-       io_channel_h channel;
-       int hydra_fd;
-       io_channel_h hydra_channel;
-
-       if (info == NULL)
-               return NULL;
-
-       if (__find_slot(info->type, info->loader_id) != NULL)
-               return NULL;
-
-       cpc = __create_slot(info);
-       if (cpc == NULL)
-               return NULL;
-
-       fd = __listen_candidate_process(cpc->type, cpc->loader_id);
-       if (fd == -1) {
-               _E("[launchpad] Listening the socket to " \
-                               "the type %d candidate process failed.",
-                               cpc->type);
-               __destroy_slot(cpc);
-               return NULL;
-       }
-
-       channel = _io_channel_create(fd, IO_IN, __handle_loader_event, cpc);
-       if (!channel) {
-               close(fd);
-               __destroy_slot(cpc);
-               return NULL;
-       }
-
-       cpc->channel = channel;
-
-       if (info->is_hydra) {
-               hydra_fd = __listen_hydra_process(cpc->type, cpc->loader_id);
-               if (hydra_fd == -1) {
-                       _E("[launchpad] Listening the socket to " \
-                                       "the type %d hydra process failed.",
-                                       cpc->type);
-                       __destroy_slot(cpc);
-                       return NULL;
-               }
-
-               hydra_channel = _io_channel_create(hydra_fd, IO_IN,
-                               __handle_hydra_event, cpc);
-               if (!hydra_channel) {
-                       close(hydra_fd);
-                       __destroy_slot(cpc);
-                       return NULL;
-               }
-
-               cpc->hydra_channel = hydra_channel;
-       }
-
-       candidate_slot_list = g_list_append(candidate_slot_list, cpc);
-
-       return cpc;
-}
-
-static int __remove_slot(int type, int loader_id)
-{
-       candidate_process_context_t *cpc;
-       GList *iter;
-
-       iter = candidate_slot_list;
-       while (iter) {
-               cpc = (candidate_process_context_t *)iter->data;
-               if (type == cpc->type && loader_id == cpc->loader_id) {
-                       __dispose_candidate_process(cpc);
-                       candidate_slot_list = g_list_delete_link(
-                                       candidate_slot_list, iter);
-                       __destroy_slot(cpc);
-                       return 0;
-               }
-
-               iter = g_list_next(iter);
-       }
-
-       return -1;
-}
-
-static int __init_launchpad_fd(int argc, char **argv)
-{
-       io_condition_e cond;
-       int fd;
-
-       fd = __launchpad_pre_init(argc, argv);
-       if (fd < 0) {
-               _E("launchpad pre init failed");
-               return -1;
-       }
-
-       cond = IO_IN | IO_PRI | IO_HUP | IO_ERR | IO_NVAL;
-       __launchpad_channel = _io_channel_create(fd, cond,
-                       __handle_launch_event, NULL);
-       if (!__launchpad_channel) {
-               close(fd);
-               return -1;
-       }
-
-       return 0;
-}
-
-static bool __on_directory_create(const char *event_name, uint32_t mask,
-               void *user_data)
-{
-       if (!event_name) {
-               _E("Invalid parameter");
-               return true;
-       }
-
-       if (!strcmp(event_name, LOADERS_PATH)) {
-               _W("%s is created", LOADERS_PATH);
-               __init_app_defined_loader_monitor();
-               return false;
-       }
-
-       return true;
-}
-
-static bool __on_file_change(const char *event_name, uint32_t mask,
-               void *user_data)
-{
-       char buf[PATH_MAX];
-       char *ext;
-       loader_info_t* info;
-       candidate_process_context_t *cpc;
-
-       if (!event_name) {
-               _E("Invalid parameter");
-               return true;
-       }
-
-       ext = strrchr(event_name, '.');
-       if (ext == NULL || strcmp(ext, ".loader") != 0)
-               return true;
-
-       _W("event_name(%s), mask(%u)", event_name, mask);
-       if (mask & IN_CREATE) {
-               snprintf(buf, sizeof(buf), "%s/%s",
-                               APP_DEFINED_LOADER_INFO_PATH, event_name);
-               app_defined_loader_info_list = _loader_info_load_file(
-                               app_defined_loader_info_list, buf);
-       } else if (mask & IN_DELETE) {
-               snprintf(buf, ext - event_name + 1, "%s", event_name);
-
-               info = _loader_info_find_loader_by_loader_name(
-                               app_defined_loader_info_list, buf);
-               cpc = __find_slot_from_loader_name(info->name);
-               __remove_slot(cpc->type, cpc->loader_id);
-               app_defined_loader_info_list = _loader_info_unload(
-                               app_defined_loader_info_list, buf);
-       }
-
-       return true;
-}
-
-static void __init_app_defined_loader_monitor(void)
-{
-       int ret;
-
-       ret = access(APP_DEFINED_LOADER_INFO_PATH, F_OK);
-       if (ret < 0) {
-               _W("Failed to access %s", APP_DEFINED_LOADER_INFO_PATH);
-               ret = _inotify_add_watch(OPT_SHARE_PATH,
-                               IN_CREATE, __on_directory_create, NULL);
-               if (ret != 0)
-                       _E("Failed to add inotify watch %s", OPT_SHARE_PATH);
-
-               return;
-       }
-
-       ret = _inotify_add_watch(APP_DEFINED_LOADER_INFO_PATH,
-                       IN_CREATE | IN_DELETE, __on_file_change, NULL);
-
-       if (ret < 0) {
-               _E("Failed to add inotify watch %s",
-                               APP_DEFINED_LOADER_INFO_PATH);
-       }
-
-       return;
-
-}
-
-static int __init_label_monitor_fd(void)
-{
-       io_condition_e cond;
-       int r;
-       int fd = -1;
-
-       r = security_manager_app_labels_monitor_init(&label_monitor);
-       if (r != SECURITY_MANAGER_SUCCESS)
-               return -1;
-
-       r = security_manager_app_labels_monitor_process(label_monitor);
-       if (r != SECURITY_MANAGER_SUCCESS)
-               goto err;
-
-       security_manager_app_labels_monitor_get_fd(label_monitor, &fd);
-       if (fd < 0) {
-               _E("failed to get fd");
-               goto err;
-       }
-
-       cond = IO_IN | IO_PRI | IO_HUP | IO_ERR | IO_NVAL;
-       __label_monitor_channel = _io_channel_create(fd, cond,
-                       __handle_label_monitor, NULL);
-       if (!__label_monitor_channel)
-               goto err;
-
-       return 0;
-
-err:
-       if (fd > 0)
-               close(fd);
-
-       if (label_monitor) {
-               security_manager_app_labels_monitor_finish(label_monitor);
-               label_monitor = NULL;
-       }
-
-       return -1;
-}
-
-static int __verify_loader_caps(const char *loader)
-{
-       cap_t cap_d;
-       cap_flag_value_t eff_state;
-       cap_flag_value_t inh_state;
-       cap_value_t values[] = {CAP_SETGID, CAP_MAC_ADMIN};
-       int r;
-       int i;
-       int size = ARRAY_SIZE(values);
-
-       /* If Dytransition feature is enabled, CAP_MAC_ADMIN is unnecessary */
-       if (label_monitor)
-               size--;
-
-       cap_d = cap_get_file(loader);
-       if (!cap_d) {
-               _E("Failed to get cap from file(%s)", loader);
-               return -1;
-       }
-
-       for (i = 0; i < size; i++) {
-               r = cap_get_flag(cap_d, values[i], CAP_INHERITABLE, &inh_state);
-               if (r != 0) {
-                       _E("Failed to get cap inh - errno(%d)", errno);
-                       cap_free(cap_d);
-                       return -1;
-               }
-
-               r = cap_get_flag(cap_d, values[i], CAP_EFFECTIVE, &eff_state);
-               if (r != 0) {
-                       _E("Failed to get cap eff - errno(%d)", errno);
-                       cap_free(cap_d);
-                       return -1;
-               }
-
-               if ((inh_state != CAP_SET) || (eff_state != CAP_SET)) {
-                       _E("The %s doesn't have %d cap", loader, values[i]);
-                       cap_free(cap_d);
-                       return -1;
-               }
-       }
-       cap_free(cap_d);
-
-       return 0;
-}
-
-static void __get_app_type_string(loader_info_t *info, char buf[], int size)
-{
-       GList *iter = info->app_types;
-       char *app_type;
-       char *ptr = buf;
-       int len;
-
-       while (iter) {
-               app_type = (char *)iter->data;
-               iter = g_list_next(iter);
-               len = strlen(app_type);
-               if (size < len + 1)
-                       return;
-
-               strncpy(ptr, app_type, size);
-               ptr += len;
-               size -= len;
-               if (iter) {
-                       (*ptr++) = ' ';
-                       size--;
-               }
-       }
-}
-
-static void __add_slot_from_info(gpointer data, gpointer user_data)
-{
-       loader_info_t *info = (loader_info_t *)data;
-       candidate_process_context_t *cpc;
-       bundle_raw *extra = NULL;
-       int len;
-       char buf[2048] = {0, };
-       slot_info_t slot_info = {
-               .type = LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset,
-               .loader_name = info->name,
-               .loader_path = info->exe,
-               .threshold_max = info->cpu_threshold_max,
-               .threshold_min = info->cpu_threshold_min,
-               .app_exists = info->app_exists,
-               .is_hydra = info->is_hydra,
-               .app_check = info->app_check,
-               .on_boot_timeout = info->on_boot_timeout,
-               .sched_priority = info->sched_priority,
-       };
-
-       if (!strcmp(info->exe, "null")) {
-               slot_info.loader_id = PAD_LOADER_ID_DIRECT;
-
-               cpc = __add_slot(&slot_info);
-               if (cpc == NULL)
-                       return;
-
-               info->type = LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset;
-               user_slot_offset++;
-               return;
-       }
-
-       if (access(info->exe, F_OK | X_OK) == 0) {
-               if (__verify_loader_caps(info->exe) < 0)
-                       return;
-
-               if (info->extra)
-                       bundle_encode(info->extra, &extra, &len);
-
-               slot_info.loader_id = PAD_LOADER_ID_STATIC;
-               slot_info.loader_extra = (const char *)extra;
-               slot_info.detection_method = info->detection_method;
-               slot_info.activation_method = info->activation_method;
-               slot_info.deactivation_method = info->deactivation_method;
-               slot_info.ttl = info->ttl;
-               slot_info.timeout_val = info->timeout_val;
-               slot_info.on_boot = info->on_boot;
-
-               cpc = __add_slot(&slot_info);
-               bundle_free_encoded_rawdata(&extra);
-               if (cpc == NULL)
-                       return;
-
-               info->type = LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset;
-               user_slot_offset++;
-               __get_app_type_string(info, buf, sizeof(buf));
-               _I("candidate slot. app-type(%s) loader-type(%d)",
-                               buf, info->type);
-               _print_hwc_log("candidate slot. app-type(%s) loader-type(%d)",
-                               buf, info->type);
-       }
-}
-
-static int __add_default_slots(void)
-{
-       if (loader_info_list)
-               _loader_info_dispose(loader_info_list);
-
-       loader_info_list = _loader_info_load_dir(LOADER_INFO_PATH);
-       if (loader_info_list == NULL)
-               return -1;
-
-       user_slot_offset = 0;
-       g_list_foreach(loader_info_list, __add_slot_from_info, NULL);
-       __add_idle_checker(0, candidate_slot_list);
-
-       return 0;
-}
-
-static void __add_app_defined_loaders(void)
-{
-       app_defined_loader_info_list = _loader_info_load_dir(APP_DEFINED_LOADER_INFO_PATH);
-}
-
-static bool __is_low_memory(void)
-{
-       if (_memory_monitor_is_low_memory())
-               return true;
-
-       if (__memory_status_low >= MEMORY_STATUS_LOW)
-               return true;
-
-       return false;
-}
-
-static void __hw_acceleration_changed_cb(keynode_t *key, void *data)
-{
-       __sys_hwacc = vconf_keynode_get_int(key);
-       _D("sys hwacc: %d", __sys_hwacc);
-}
-
-static void __update_lang(keynode_t *node, void *user_data)
-{
-       char *lang;
-
-       lang = vconf_keynode_get_str(node);
-       if (!lang) {
-               _E("Failed to get language");
-               return;
-       }
-
-       setenv("LANG", lang, 1);
-}
-
-static void __region_format_changed_cb(keynode_t *node, void *data)
-{
-       char *region;
-
-       region = vconf_keynode_get_str(node);
-       if (!region) {
-               _E("Failed to get value");
-               return;
-       }
-
-       setenv("LC_CTYPE", region, 1);
-}
-
-static void __memory_status_low_changed_cb(keynode_t *node, void *data)
-{
-       candidate_process_context_t *cpc;
-       GList *iter;
-
-       __memory_status_low = vconf_keynode_get_int(node);
-       if (__memory_status_low >= MEMORY_STATUS_LOW) {
-               _W("Low memory");
-               iter = candidate_slot_list;
-               while (iter) {
-                       cpc = (candidate_process_context_t *)iter->data;
-                       __update_slot_state(cpc, METHOD_OUT_OF_MEMORY, false);
-                       iter = g_list_next(iter);
-               }
-       }
-}
-
-static void __memory_status_normal_changed_cb(keynode_t *node, void *data)
-{
-       candidate_process_context_t *cpc;
-       GList *iter;
-
-       __memory_status_normal = vconf_keynode_get_int(node);
-       if (__memory_status_normal == MEMORY_STATUS_NORMAL) {
-               _W("Normal");
-               iter = candidate_slot_list;
-               while (iter) {
-                       cpc = (candidate_process_context_t *)iter->data;
-                       __update_slot_state(cpc, METHOD_AVAILABLE_MEMORY, true);
-                       iter = g_list_next(iter);
-               }
-       }
-}
-
-static void __unregister_vconf_events(void)
-{
-       const char *key;
-       config_type_e type;
-
-       type = CONFIG_TYPE_MEMORY_STATUS_NORMAL_KEY;
-       key = _config_get_string_value(type);
-       vconf_ignore_key_changed(key, __memory_status_normal_changed_cb);
-
-       type = CONFIG_TYPE_MEMORY_STATUS_LOW_KEY;
-       key = _config_get_string_value(type);
-       vconf_ignore_key_changed(key, __memory_status_low_changed_cb);
-
-       vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT,
-                       __region_format_changed_cb);
-       vconf_ignore_key_changed(VCONFKEY_LANGSET,
-                       __update_lang);
-       vconf_ignore_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
-                       __hw_acceleration_changed_cb);
-}
-
-static int __register_vconf_events(void)
-{
-       int r;
-       char *lang;
-       char *region;
-       const char *key;
-       config_type_e type;
-
-       r = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &__sys_hwacc);
-       if (r != VCONF_OK)
-               _E("Failed to get vconf hw acceleration. err = %d", r);
-
-       r = vconf_notify_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
-                       __hw_acceleration_changed_cb, NULL);
-       if (r != VCONF_OK) {
-               _E("Failed to register callback for hw acceleration. err = %d",
-                               r);
-       }
-
-       lang = vconf_get_str(VCONFKEY_LANGSET);
-       if (lang) {
-               setenv("LANG", lang, 1);
-               free(lang);
-       }
-
-       r = vconf_notify_key_changed(VCONFKEY_LANGSET, __update_lang, NULL);
-       if (r != VCONF_OK)
-               _E("Failed to register callback for langset. err = %d", r);
-
-       region = vconf_get_str(VCONFKEY_REGIONFORMAT);
-       if (region) {
-               setenv("LC_CTYPE", region, 1);
-               free(region);
-       }
-
-       r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT,
-                       __region_format_changed_cb, NULL);
-       if (r != VCONF_OK)
-               _E("Failed to register callback for regionformat. err = %d", r);
-
-       type = CONFIG_TYPE_MEMORY_STATUS_LOW_KEY;
-       key = _config_get_string_value(type);
-       type = CONFIG_TYPE_MEMORY_STATUS_LOW_VALUE;
-       MEMORY_STATUS_LOW = _config_get_int_value(type);
-
-       r = vconf_get_int(key, &__memory_status_low);
-       if (r != VCONF_OK)
-               _E("Failed to get vconf low memory. err = %d", r);
-
-       r = vconf_notify_key_changed(key,
-                       __memory_status_low_changed_cb, NULL);
-       if (r != 0)
-               _E("Failed to register callback for low memory. err = %d", r);
-
-       type = CONFIG_TYPE_MEMORY_STATUS_NORMAL_KEY;
-       key = _config_get_string_value(type);
-       type = CONFIG_TYPE_MEMORY_STATUS_NORMAL_VALUE;
-       MEMORY_STATUS_NORMAL = _config_get_int_value(type);
-
-       r = vconf_get_int(key, &__memory_status_normal);
-       if (r != VCONF_OK)
-               _E("Failed to get vconf normal memory. err = %d", r);
-
-       r = vconf_notify_key_changed(key,
-                       __memory_status_normal_changed_cb, NULL);
-       if (r != 0)
-               _E("Failed to register callback for normal memory. err = %d", r);
-
-       return 0;
-}
-
-static bool __handle_logger(int fd, io_condition_e cond, void *data)
-{
-       app_pkt_t *pkt;
-       struct ucred cr;
-       int clifd = -1;
-
-       if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
-               _E("fd(%d), io_condition(%d)", fd, cond);
-               g_idle_add(__logger_recovery_cb, __logger_channel);
-               __logger_channel = NULL;
-               return false;
-       }
-
-       pkt = _accept_recv_pkt_raw(fd, &clifd, &cr);
-       if (!pkt) {
-               _E("Failed to receive the packet");
-               return true;
-       }
-
-       if (getuid() != cr.uid) {
-               _E("Invalid caller");
-               goto end;
-       }
-
-       if (pkt->len <= 0) {
-               _E("Invalid message");
-               goto end;
-       }
-
-       _E("[%d] %s", cr.pid, (const char *)pkt->data);
-       _log_print("[ERROR]", "pid(%7d) | message(%s)",
-                       cr.pid, (const char *)pkt->data);
-end:
-       if (clifd != -1)
-               close(clifd);
-
-       free(pkt);
-
-       return true;
-}
-
-static int __init_logger_fd(void)
-{
-       io_condition_e cond;
-       int fd;
-
-       fd = _create_server_sock(LAUNCHPAD_LOGGER_SOCK);
-       if (fd < 0) {
-               _E("Failed to create logger socker");
-               return -1;
-       }
-
-       cond = IO_IN | IO_PRI | IO_ERR | IO_HUP | IO_NVAL;
-       __logger_channel = _io_channel_create(fd, cond, __handle_logger, NULL);
-       if (!__logger_channel) {
-               close(fd);
-               return -1;
-       }
-
-       return 0;
-}
-
-static int __memory_monitor_cb(bool low_memory, void *user_data)
-{
-       candidate_process_context_t *cpc;
-
-       cpc = __get_running_slot(false);
-       if (!cpc && low_memory)
-               return -1;
-
-       if (low_memory) {
-               _W("Low memory");
-               __update_slots_pss();
-
-               candidate_slot_list = g_list_sort(candidate_slot_list,
-                               __compare_slot);
-               __pause_all_running_slots(false);
-       } else {
-               __resume_all_slots();
-       }
-
-       return 0;
-}
-
-static gboolean __logger_recovery_cb(gpointer data)
-{
-       io_channel_h channel = data;
-       int ret;
-
-       _io_channel_destroy(channel);
-
-       ret = __init_logger_fd();
-       if (ret < 0) {
-               _E("Failed to recover logger socket");
-               return G_SOURCE_REMOVE;
-       }
-
-       _E("[__RECOVERY__] Logger socket");
-
-       return G_SOURCE_REMOVE;
-}
-
-static gboolean __launchpad_recovery_cb(gpointer data)
-{
-       io_channel_h channel = data;
-       int ret;
-
-       _io_channel_destroy(channel);
-
-       ret = __init_launchpad_fd(0, NULL);
-       if (ret < 0) {
-               _E("Failed to recover launchpad socket");
-               abort();
-               return G_SOURCE_REMOVE;
-       }
-
-       _E("[__RECOVERY__] Launchpad socket");
-
-       return G_SOURCE_REMOVE;
-}
-
-static int __before_loop(int argc, char **argv)
-{
-       int ret;
-
-       _print_hwc_log("%s(%d): START", __FUNCTION__, __LINE__);
-       ret = __sequencer_init();
-       if (ret < 0) {
-               _E("Failed to initialize sequencer");
-               return -1;
-       }
-
-       ret = _signal_init();
-       if (ret < 0) {
-               _E("Failed to initialize signal");
-               return -1;
-       }
-
-       _signal_set_sigchld_cb(__handle_sigchild, NULL);
-
-       ret = __init_launchpad_fd(argc, argv);
-       if (ret != 0) {
-               _E("__init_launchpad_fd() failed");
-               return -1;
-       }
-
-       ret = __init_logger_fd();
-       if (ret != 0) {
-               _E("__init_logger_fd() failed");
-               return -1;
-       }
-
-       ret = __init_label_monitor_fd();
-       if (ret != 0)
-               _W("Failed to initialize label monitor");
-
-       ret = _config_init();
-       if (ret != 0)
-               _W("Failed to initialize config");
-
-       ret = _dbus_init();
-       if (ret != 0)
-               _W("Failed to initialize dbus");
-
-       _inotify_init();
-
-       MAX_CPU_CHECK_COUNT = _config_get_int_value(
-                       CONFIG_TYPE_CPU_CHECKER_MAX_COUNT);
-       __add_default_slots();
-       launcher_info_list = _launcher_info_load(LAUNCHER_INFO_PATH);
-
-       __add_app_defined_loaders();
-
-       ret = _send_cmd_to_amd(LAUNCHPAD_LAUNCH_SIGNAL);
-       if (ret < 0)
-               _W("Failed to send cmd(%d) to amd", LAUNCHPAD_LAUNCH_SIGNAL);
-
-       __pid_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-                       NULL, free);
-       if (!__pid_table) {
-               _E("Failed to create pid table");
-               return -1;
-       }
-
-       ret = _worker_create("cleaner+", &__cleaner);
-       if (ret < 0)
-               return ret;
-
-       __register_vconf_events();
-       __init_app_defined_loader_monitor();
-       _memory_monitor_init();
-       _memory_monitor_set_event_cb(__memory_monitor_cb, NULL);
-       _log_init();
-       _print_hwc_log("%s(%d): END", __FUNCTION__, __LINE__);
-
-       return 0;
-}
-
-static void __after_loop(void)
-{
-       _log_fini();
-       _memory_monitor_fini();
-       __unregister_vconf_events();
-       _worker_destroy(__cleaner);
-       if (__pid_table)
-               g_hash_table_destroy(__pid_table);
-
-       if (_send_cmd_to_amd(LAUNCHPAD_DEAD_SIGNAL) < 0)
-               _W("Failed to send cmd(%d) to amd", LAUNCHPAD_DEAD_SIGNAL);
-
-       _debug_fini();
-       _launcher_info_unload(launcher_info_list);
-       _dbus_fini();
-       _config_fini();
-       _inotify_fini();
-       _loader_info_dispose(app_defined_loader_info_list);
-
-       if (__label_monitor_channel)
-               _io_channel_destroy(__label_monitor_channel);
-
-       if (label_monitor)
-               security_manager_app_labels_monitor_finish(label_monitor);
-
-       if (__logger_channel)
-               _io_channel_destroy(__logger_channel);
-
-       if (__launchpad_channel)
-               _io_channel_destroy(__launchpad_channel);
-
-       _signal_fini();
-
-       __sequencer_fini();
-}
-
-int main(int argc, char **argv)
-{
-       GMainLoop *mainloop = NULL;
-
-       _print_hwc_log("%s(%d): START", __FUNCTION__, __LINE__);
-       prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
-
-       mainloop = g_main_loop_new(NULL, FALSE);
-       if (!mainloop) {
-               _E("Failed to create glib main loop");
-               return -1;
-       }
-
-       _print_hwc_log("%s(%d): __before_loop()", __FUNCTION__, __LINE__);
-       if (__before_loop(argc, argv) != 0) {
-               _E("process-pool Initialization failed!");
-               return -1;
-       }
-
-#ifdef TIZEN_FEATURE_PRIORITY_CHANGE
-       _set_priority(-12);
-#endif
-       _print_hwc_log("%s(%d): g_main_loop_run()", __FUNCTION__, __LINE__);
-       g_main_loop_run(mainloop);
-
-       __after_loop();
-
-       return -1;
-}
diff --git a/src/launchpad-process-pool/src/launchpad.cc b/src/launchpad-process-pool/src/launchpad.cc
new file mode 100644 (file)
index 0000000..a71168f
--- /dev/null
@@ -0,0 +1,3451 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bundle_internal.h>
+#include <errno.h>
+#include <glib.h>
+#include <linux/limits.h>
+#include <malloc.h>
+#include <math.h>
+#include <sched.h>
+#include <security-manager.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <systemd/sd-daemon.h>
+#include <time.h>
+#include <trust-anchor.h>
+#include <ttrace.h>
+#include <vconf.h>
+
+#include <algorithm>
+
+#include "key.h"
+#include "launcher_info.hh"
+#include "launchpad_common.h"
+#include "launchpad_config.h"
+#include "launchpad_dbus.h"
+#include "launchpad_debug.h"
+#include "launchpad_inotify.h"
+#include "launchpad_io_channel.h"
+#include "launchpad_log.h"
+#include "launchpad_memory_monitor.h"
+#include "launchpad_plugin.h"
+#include "launchpad_proc.h"
+#include "launchpad_signal.h"
+#include "launchpad_types.h"
+#include "launchpad_worker.h"
+#include "loader_info.hh"
+#include "perf.h"
+#include "slot_info.h"
+
+#define AUL_PR_NAME 16
+#define EXEC_CANDIDATE_EXPIRED 5
+#define EXEC_CANDIDATE_WAIT 1
+#define DIFF(a, b) (((a) > (b)) ? (a) - (b) : (b) - (a))
+#define CANDIDATE_NONE 0
+#define HYDRA_NONE 0
+#define PROCESS_POOL_LAUNCHPAD_SOCK ".launchpad-process-pool-sock"
+#define LAUNCHPAD_LOGGER_SOCK ".launchpad-logger-sock"
+#define LOADER_PATH_DEFAULT "/usr/bin/launchpad-loader"
+#define LOADER_INFO_PATH "/usr/share/aul"
+#define OPT_SHARE_PATH "/opt/share"
+#define LOADERS_PATH "loaders"
+#define APP_DEFINED_LOADER_INFO_PATH OPT_SHARE_PATH "/" LOADERS_PATH
+#define COMMON_LOADER_NAME "common-loader1"
+
+#define LAUNCHER_INFO_PATH LOADER_INFO_PATH
+#define REGULAR_UID_MIN 5000
+#define PAD_ERR_FAILED -1
+#define PAD_ERR_REJECTED -2
+#define PAD_ERR_INVALID_ARGUMENT -3
+#define PAD_ERR_INVALID_PATH -4
+#define CPU_CHECKER_TIMEOUT 1000
+#define PI 3.14159265
+#define WIN_SCORE 100
+#define LOSE_SCORE_RATE 0.7f
+
+enum candidate_process_state_e {
+  CANDIDATE_PROCESS_STATE_RUNNING,
+  CANDIDATE_PROCESS_STATE_PAUSED,
+};
+
+typedef struct {
+  int type;
+  bool prepared;
+  int pid; /* for hydra this pid is not the pid of hydra itself */
+  /* but pid of non-hydra candidate, which was forked from hydra */
+  int hydra_pid;
+  int loader_id;
+  int caller_pid;
+  int send_fd;
+  int hydra_fd;
+  int last_exec_time;
+  guint timer;
+  char* loader_name;
+  char* loader_path;
+  char* loader_extra;
+  int detection_method;
+  int timeout_val;
+  unsigned long long cpu_total_time;
+  unsigned long long cpu_idle_time;
+  int threshold;
+  int threshold_max;
+  int threshold_min;
+  int cur_event;
+  bool on_boot;
+  bool app_exists;
+  bool touched;
+  int activation_method;
+  int deactivation_method;
+  unsigned int ttl;
+  guint live_timer;
+  int state;
+  bool is_hydra;
+  bool app_check;
+  io_channel_h client_channel;
+  io_channel_h channel;
+  io_channel_h hydra_channel;
+  unsigned int score;
+  unsigned int pss;
+  int cpu_check_count;
+  int on_boot_timeout;
+  guint on_boot_timer;
+  int sched_priority;
+} candidate_process_context_t;
+
+typedef struct {
+  GPollFD* gpollfd;
+  int type;
+  int loader_id;
+} loader_context_t;
+
+typedef struct {
+  GQueue* queue;
+  guint timer;
+  guint idle_checker;
+  candidate_process_context_t* running_cpc;
+} sequencer;
+
+struct app_launch_arg {
+  const char* appid;
+  const char* app_path;
+  appinfo_t* menu_info;
+  bundle* kb;
+};
+
+struct app_arg {
+  int argc;
+  char** argv;
+};
+
+struct app_info {
+  const char* type;
+  bool exists;
+};
+
+struct cleanup_info_s {
+  char* appid;
+  int pid;
+};
+
+typedef struct candidate_info_s {
+  char** argv;
+  int argc;
+  int loader_id;
+  int type;
+  pid_t pid;
+} candidate_info_t;
+
+typedef struct request_s {
+  app_pkt_t* pkt;
+  appinfo_t* menu_info;
+  bundle* kb;
+  candidate_process_context_t* cpc;
+  candidate_process_context_t* org_cpc;
+  const char* app_path;
+  int clifd;
+  int cmd;
+  int loader_id;
+  pid_t caller_pid;
+  uid_t caller_uid;
+  pid_t pid; /* result */
+} request_t;
+
+typedef request_t* request_h;
+
+typedef int (*request_handler)(request_h request);
+
+namespace {
+
+int __sys_hwacc;
+std::unique_ptr<launchpad::LoaderInfoManager> loader_info_manager;
+std::unique_ptr<launchpad::LoaderInfoManager> app_defined_loader_info_manager;
+int user_slot_offset;
+GList* candidate_slot_list;
+app_labels_monitor* label_monitor;
+std::vector<launchpad::LauncherInfoPtr> launcher_info_list;
+GHashTable* __pid_table;
+int __memory_status_low;
+int __memory_status_normal;
+sequencer __sequencer;
+int MEMORY_STATUS_LOW;
+int MEMORY_STATUS_NORMAL;
+int MAX_CPU_CHECK_COUNT;
+
+io_channel_h __logger_channel;
+io_channel_h __label_monitor_channel;
+io_channel_h __launchpad_channel;
+int __client_fd = -1;
+worker_h __cleaner;
+
+}  // namespace
+
+static candidate_process_context_t* __add_slot(slot_info_t* info);
+static int __remove_slot(int type, int loader_id);
+static int __add_default_slots(void);
+static gboolean __handle_idle_checker(gpointer data);
+static int __add_idle_checker(int detection_method, GList* cur);
+static void __dispose_candidate_process(candidate_process_context_t* cpc);
+static bool __is_low_memory(void);
+static void __update_slot_state(candidate_process_context_t* cpc,
+                                launchpad::LoaderMethod method,
+                                bool force);
+static void __init_app_defined_loader_monitor(void);
+static gboolean __launchpad_recovery_cb(gpointer data);
+static gboolean __logger_recovery_cb(gpointer data);
+
+static gboolean __handle_queuing_slots(gpointer data) {
+  candidate_process_context_t* cpc;
+  unsigned long long total = 0;
+  unsigned long long idle = 0;
+
+  if (__sequencer.idle_checker > 0)
+    return G_SOURCE_CONTINUE;
+
+  if (g_queue_is_empty(__sequencer.queue)) {
+    __sequencer.timer = 0;
+    return G_SOURCE_REMOVE;
+  }
+
+  cpc = (candidate_process_context_t*)g_queue_pop_head(__sequencer.queue);
+  if (!cpc) {
+    _E("Critical error!");
+    __sequencer.timer = 0;
+    return G_SOURCE_REMOVE;
+    ;
+  }
+
+  if (cpc->app_check && !cpc->app_exists) {
+    _W("The application is not installed. Type(%d)", cpc->type);
+    return G_SOURCE_CONTINUE;
+  }
+
+  if (cpc->timer) {
+    g_source_remove(cpc->timer);
+    cpc->timer = 0;
+  }
+
+  if (cpc->pid != CANDIDATE_NONE) {
+    _W("The slot(%d) is already running. pid(%d)", cpc->type, cpc->pid);
+    return G_SOURCE_CONTINUE;
+  }
+
+  _get_cpu_idle(&total, &idle);
+  cpc->cpu_idle_time = idle;
+  cpc->cpu_total_time = total;
+  cpc->cpu_check_count = 0;
+
+  __sequencer.idle_checker =
+      g_timeout_add(CPU_CHECKER_TIMEOUT, __handle_idle_checker, cpc);
+  __sequencer.running_cpc = cpc;
+
+  _W("[__SEQUENCER__] Add idle checker. Type(%d)", cpc->type);
+
+  return G_SOURCE_CONTINUE;
+}
+
+static bool __sequencer_slot_is_running(candidate_process_context_t* cpc) {
+  if (__sequencer.running_cpc == cpc)
+    return true;
+
+  return false;
+}
+
+static bool __sequencer_slot_exist(candidate_process_context_t* cpc) {
+  GList* found;
+
+  found = g_queue_find(__sequencer.queue, cpc);
+  if (found)
+    return true;
+
+  return false;
+}
+
+static int __sequencer_add_slot(candidate_process_context_t* cpc) {
+  if (__sequencer_slot_exist(cpc)) {
+    _W("Already exists");
+    return -1;
+  }
+
+  if (__sequencer_slot_is_running(cpc)) {
+    _W("slot(%d) is running", cpc->type);
+    return -1;
+  }
+
+  g_queue_push_tail(__sequencer.queue, cpc);
+
+  return 0;
+}
+
+static void __sequencer_remove_slot(candidate_process_context_t* cpc) {
+  g_queue_remove(__sequencer.queue, cpc);
+}
+
+static void __sequencer_run(void) {
+  if (__sequencer.timer)
+    return;
+
+  __sequencer.timer = g_timeout_add(500, __handle_queuing_slots, nullptr);
+  if (!__sequencer.timer)
+    _E("Failed to add sequencer timer");
+}
+
+static void __sequencer_stop(void) {
+  if (!__sequencer.timer)
+    return;
+
+  g_source_remove(__sequencer.timer);
+  __sequencer.timer = 0;
+}
+
+static bool __sequencer_queue_is_empty(void) {
+  if (g_queue_is_empty(__sequencer.queue))
+    return true;
+
+  return false;
+}
+
+static int __sequencer_init(void) {
+  _D("[__SEQUENCER__] Init");
+
+  __sequencer.queue = g_queue_new();
+  if (!__sequencer.queue) {
+    _E("Out of memory");
+    return -1;
+  }
+
+  return 0;
+}
+
+static void __sequencer_fini(void) {
+  _D("[__SEQUENCER__] Finish");
+
+  if (__sequencer.idle_checker > 0)
+    g_source_remove(__sequencer.idle_checker);
+
+  if (__sequencer.timer > 0)
+    g_source_remove(__sequencer.timer);
+
+  g_queue_free(__sequencer.queue);
+}
+
+static int __make_loader_id(void) {
+  static int id = PAD_LOADER_ID_DYNAMIC_BASE;
+
+  return ++id;
+}
+
+static candidate_process_context_t* __find_slot_from_static_type(int type) {
+  candidate_process_context_t* cpc;
+  GList* iter = candidate_slot_list;
+
+  if (type == static_cast<int>(launchpad::LoaderType::Dynamic) ||
+      type == static_cast<int>(launchpad::LoaderType::Unsupported))
+    return nullptr;
+
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (type == cpc->type)
+      return cpc;
+
+    iter = g_list_next(iter);
+  }
+
+  return nullptr;
+}
+
+static candidate_process_context_t* __find_slot_from_pid(int pid) {
+  candidate_process_context_t* cpc;
+  GList* iter = candidate_slot_list;
+
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (pid == cpc->pid)
+      return cpc;
+
+    iter = g_list_next(iter);
+  }
+
+  return nullptr;
+}
+
+static candidate_process_context_t* __find_hydra_slot_from_pid(int pid) {
+  candidate_process_context_t* cpc;
+  GList* iter = candidate_slot_list;
+
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (cpc->is_hydra && pid == cpc->hydra_pid)
+      return cpc;
+
+    iter = g_list_next(iter);
+  }
+
+  return nullptr;
+}
+
+static candidate_process_context_t* __find_slot_from_caller_pid(
+    int caller_pid) {
+  candidate_process_context_t* cpc;
+  GList* iter = candidate_slot_list;
+
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (caller_pid == cpc->caller_pid)
+      return cpc;
+
+    iter = g_list_next(iter);
+  }
+
+  return nullptr;
+}
+
+static candidate_process_context_t* __find_slot_from_loader_id(int id) {
+  candidate_process_context_t* cpc;
+  GList* iter = candidate_slot_list;
+
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (id == cpc->loader_id)
+      return cpc;
+
+    iter = g_list_next(iter);
+  }
+
+  return nullptr;
+}
+
+static candidate_process_context_t* __find_slot_from_loader_name(
+    const char* loader_name) {
+  candidate_process_context_t* cpc;
+  GList* iter = candidate_slot_list;
+
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (strcmp(cpc->loader_name, loader_name) == 0)
+      return cpc;
+
+    iter = g_list_next(iter);
+  }
+
+  return nullptr;
+}
+
+static candidate_process_context_t* __find_slot(int type, int loader_id) {
+  if (type == static_cast<int>(launchpad::LoaderType::Dynamic))
+    return __find_slot_from_loader_id(loader_id);
+
+  return __find_slot_from_static_type(type);
+}
+
+static void __update_slot_score(candidate_process_context_t* slot) {
+  if (!slot)
+    return;
+
+  slot->score *= LOSE_SCORE_RATE;
+  slot->score += WIN_SCORE;
+}
+
+static void __update_slots_pss(void) {
+  candidate_process_context_t* cpc;
+  GList* iter;
+
+  iter = candidate_slot_list;
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    iter = g_list_next(iter);
+
+    if (cpc->pid == CANDIDATE_NONE)
+      continue;
+
+    _proc_get_mem_pss(cpc->pid, &cpc->pss);
+  }
+}
+
+static gint __compare_slot(gconstpointer a, gconstpointer b) {
+  candidate_process_context_t* slot_a = (candidate_process_context_t*)a;
+  candidate_process_context_t* slot_b = (candidate_process_context_t*)b;
+
+  if (slot_a->is_hydra && !slot_b->is_hydra)
+    return -1;
+  if (!slot_a->is_hydra && slot_b->is_hydra)
+    return 1;
+
+  if (slot_a->score < slot_b->score)
+    return 1;
+  if (slot_a->score > slot_b->score)
+    return -1;
+
+  if (slot_a->pss < slot_b->pss)
+    return -1;
+  if (slot_a->pss > slot_b->pss)
+    return 1;
+
+  return 0;
+}
+
+static candidate_process_context_t* __get_running_slot(bool is_hydra) {
+  candidate_process_context_t* cpc;
+  GList* iter;
+
+  iter = candidate_slot_list;
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (cpc->is_hydra == is_hydra && cpc->pid != CANDIDATE_NONE)
+      return cpc;
+
+    iter = g_list_next(iter);
+  }
+
+  return nullptr;
+}
+
+static void __pause_all_running_slots(bool is_hydra) {
+  candidate_process_context_t* cpc = nullptr;
+  GList* iter;
+
+  iter = g_list_last(candidate_slot_list);
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (cpc->is_hydra == is_hydra && cpc->pid != CANDIDATE_NONE) {
+      __update_slot_state(cpc, launchpad::LoaderMethod::OutOfMemory, true);
+      if (!_memory_monitor_is_low_memory())
+        return;
+    }
+
+    iter = g_list_previous(iter);
+  }
+}
+
+static void __resume_all_slots(void) {
+  candidate_process_context_t* cpc;
+  GList* iter;
+
+  iter = candidate_slot_list;
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    __update_slot_state(cpc, launchpad::LoaderMethod::AvailableMemory, true);
+
+    iter = g_list_next(iter);
+  }
+}
+
+static void __kill_process(int pid) {
+  char err_str[MAX_LOCAL_BUFSZ] = {
+      0,
+  };
+
+  if (kill(pid, SIGKILL) == -1) {
+    _E("send SIGKILL: %s", strerror_r(errno, err_str, sizeof(err_str)));
+  }
+}
+
+static void __refuse_candidate_process(int server_fd) {
+  int client_fd = -1;
+
+  if (server_fd == -1) {
+    _E("arguments error!");
+    goto error;
+  }
+
+  client_fd = accept(server_fd, nullptr, nullptr);
+  if (client_fd == -1) {
+    _E("accept error!");
+    goto error;
+  }
+
+  close(client_fd);
+  _D("refuse connection!");
+
+error:
+  return;
+}
+
+static int __accept_candidate_process(int server_fd,
+                                      int* out_client_fd,
+                                      int* out_client_pid,
+                                      int cpc_pid) {
+  int client_fd = -1;
+  int recv_pid = 0;
+  int ret;
+  socklen_t len;
+  struct ucred cred = {};
+
+  if (server_fd == -1 || out_client_fd == nullptr ||
+      out_client_pid == nullptr) {
+    _E("arguments error!");
+    goto error;
+  }
+
+  client_fd = accept(server_fd, nullptr, nullptr);
+  if (client_fd == -1) {
+    _E("accept error!");
+    goto error;
+  }
+
+  if (_set_sock_option(client_fd, 1) < 0) {
+    _E("Failed to set sock option");
+    goto error;
+  }
+
+  ret = recv(client_fd, &recv_pid, sizeof(recv_pid), MSG_WAITALL);
+  if (ret == -1) {
+    _E("recv error!");
+    goto error;
+  }
+
+  len = (socklen_t)sizeof(cred);
+  ret = getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &cred, &len);
+  if (ret < 0) {
+    _E("getsockopt error");
+    goto error;
+  }
+
+  if (cpc_pid != -1 && cred.pid != cpc_pid) {
+    _E("Invalid accept. pid(%d)", cred.pid);
+    goto error;
+  }
+
+  if (cred.pid != recv_pid)
+    _W("Not equal recv and real pid");
+
+  *out_client_fd = client_fd;
+  *out_client_pid = cred.pid;
+
+  return *out_client_fd;
+
+error:
+  if (client_fd != -1)
+    close(client_fd);
+
+  return -1;
+}
+
+static int __listen_addr(struct sockaddr_un* addr) {
+  int fd = -1;
+  fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+  if (fd < 0) {
+    _E("Socket error");
+    goto error;
+  }
+
+  unlink(addr->sun_path);
+
+  _D("bind to %s", addr->sun_path);
+  if (bind(fd, (struct sockaddr*)addr, sizeof(struct sockaddr_un)) < 0) {
+    _E("bind error");
+    goto error;
+  }
+
+  _D("listen to %s", addr->sun_path);
+  if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) {
+    _E("listen error");
+    goto error;
+  }
+
+  SECURE_LOGD("[launchpad] done, listen fd: %d", fd);
+  return fd;
+
+error:
+  if (fd != -1)
+    close(fd);
+
+  return -1;
+}
+
+static int __listen_candidate_process(int type, int loader_id) {
+  struct sockaddr_un addr;
+
+  _D("[launchpad] enter, type: %d", type);
+
+  memset(&addr, 0x00, sizeof(struct sockaddr_un));
+  addr.sun_family = AF_UNIX;
+  snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%u/%s%d-%d",
+           SOCKET_PATH, getuid(), LAUNCHPAD_LOADER_SOCKET_NAME, type,
+           loader_id);
+
+  return __listen_addr(&addr);
+}
+
+static int __listen_hydra_process(int type, int loader_id) {
+  struct sockaddr_un addr;
+
+  _D("[launchpad] enter, type: %d", type);
+
+  memset(&addr, 0x00, sizeof(struct sockaddr_un));
+  addr.sun_family = AF_UNIX;
+  snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%d/%s%d-%d",
+           SOCKET_PATH, getuid(), HYDRA_LOADER_SOCKET_NAME, type, loader_id);
+
+  return __listen_addr(&addr);
+}
+
+static int __get_loader_id(bundle* kb) {
+  const char* val;
+
+  val = bundle_get_val(kb, AUL_K_LOADER_ID);
+  if (val == nullptr)
+    return -1;
+  _W("Requested loader id: %s", val);
+
+  return atoi(val);
+}
+
+static int __candidate_process_real_launch(int candidate_fd, app_pkt_t* pkt) {
+  return _send_pkt_raw(candidate_fd, pkt);
+}
+
+static int __real_send(int clifd, int ret) {
+  if (clifd < 3) {
+    _E("Invalid parameter. clifd(%d)", clifd);
+    return -1;
+  }
+
+  if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
+    if (errno == EPIPE) {
+      _E("send failed due to EPIPE.");
+      close(clifd);
+      return -1;
+    }
+    _E("send fail to client");
+  }
+
+  close(clifd);
+  return 0;
+}
+
+static int __fork_app_process(int (*child_fn)(void*), void* arg,
+    int sched_priority) {
+  int pid;
+  int ret;
+
+  pid = fork();
+  if (pid == -1) {
+    _E("failed to fork child process");
+    return -1;
+  }
+
+  if (pid == 0) {
+    if (sched_priority != 0)
+      _set_priority(sched_priority);
+
+    _W("security_manager_prepare_app_candidate ++");
+    ret = security_manager_prepare_app_candidate();
+    _W("security_manager_prepare_app_candidate --");
+    if (ret != SECURITY_MANAGER_SUCCESS) {
+      _E("failed to prepare app candidate process (%d)", ret);
+      exit(1);
+    }
+
+    ret = child_fn(arg);
+    _E("failed to exec app process (%d)", errno);
+    exit(ret);
+  }
+
+  return pid;
+}
+
+static int __exec_loader_process(void* arg) {
+  char** argv = static_cast<char**>(arg);
+  char err_buf[1024];
+
+  _signal_unblock_sigchld();
+  _close_all_fds();
+  _setup_stdio(basename(argv[LOADER_ARG_PATH]));
+
+  if (execv(argv[LOADER_ARG_PATH], argv) < 0) {
+    _send_message_to_logger(argv[LOADER_ARG_PATH],
+                            "Failed to prepare candidate process. error(%d:%s)",
+                            errno, strerror_r(errno, err_buf, sizeof(err_buf)));
+  } else {
+    _D("Succeeded to prepare candidate_process");
+  }
+
+  return -1;
+}
+
+static gboolean __handle_deactivate_event(gpointer user_data) {
+  candidate_process_context_t* cpc;
+
+  cpc = (candidate_process_context_t*)user_data;
+  __update_slot_state(cpc, launchpad::LoaderMethod::Ttl, false);
+  _D("Deactivate event: type(%d)", cpc->type);
+
+  return G_SOURCE_REMOVE;
+}
+
+static void __set_live_timer(candidate_process_context_t* cpc) {
+  if (!cpc)
+    return;
+
+  if (cpc->deactivation_method & static_cast<int>(launchpad::LoaderMethod::Ttl)) {
+    if (cpc->live_timer == 0) {
+      cpc->live_timer =
+          g_timeout_add_seconds(cpc->ttl, __handle_deactivate_event, cpc);
+    }
+  }
+}
+
+static int __hydra_send_request(int fd, enum hydra_cmd cmd) {
+  int sent = 0;
+  int size = (int)sizeof(cmd);
+  int send_ret = 0;
+
+  while (sent != size) {
+    send_ret = send(fd, (char*)&cmd + sent, size - sent, MSG_NOSIGNAL);
+    if (send_ret == -1) {
+      _E("send error! (%d)", errno);
+      return -1;
+    }
+
+    sent += send_ret;
+    _D("send(%d: ret: %d) : %d / %d", fd, send_ret, sent, size);
+  }
+
+  return 0;
+}
+
+static int __hydra_send_launch_candidate_request(int fd) {
+  SECURE_LOGD("Send launch cmd to hydra, fd: %d", fd);
+  return __hydra_send_request(fd, LAUNCH_CANDIDATE);
+}
+
+static void __candidate_info_free(candidate_info_t* info) {
+  int i;
+
+  if (info == nullptr)
+    return;
+
+  if (info->argv) {
+    for (i = 0; i < info->argc; i++)
+      free(info->argv[i]);
+
+    free(info->argv);
+  }
+
+  free(info);
+}
+
+static int __candidate_info_create(candidate_process_context_t* cpt,
+                                   candidate_info_t** candidate_info) {
+  char type_str[12] = {
+      0,
+  };
+  char loader_id_str[12] = {
+      0,
+  };
+  char argbuf[LOADER_ARG_LEN];
+  candidate_info_t* info;
+
+  if (cpt == nullptr)
+    return -EINVAL;
+
+  info = static_cast<candidate_info_t*>(calloc(1, sizeof(candidate_info_t)));
+  if (info == nullptr) {
+    _E("calloc() is failed");
+    return -ENOMEM;
+  }
+
+  info->argv = static_cast<char**>(calloc(LOADER_ARG_DUMMY + 1, sizeof(char*)));
+  if (info->argv == nullptr) {
+    _E("calloc() is failed");
+    __candidate_info_free(info);
+    return -ENOMEM;
+  }
+
+  memset(argbuf, ' ', LOADER_ARG_LEN);
+  argbuf[LOADER_ARG_LEN - 1] = '\0';
+  info->argv[LOADER_ARG_DUMMY] = strdup(argbuf);
+
+  snprintf(loader_id_str, sizeof(loader_id_str), "%d", cpt->loader_id);
+  snprintf(type_str, sizeof(type_str), "%d", cpt->type);
+  info->argv[LOADER_ARG_PATH] = strdup(cpt->loader_path);
+  info->argv[LOADER_ARG_TYPE] = strdup(type_str);
+  info->argv[LOADER_ARG_ID] = strdup(loader_id_str);
+  info->argv[LOADER_ARG_HYDRA] = strdup(cpt->is_hydra ? "1" : "0");
+  info->argv[LOADER_ARG_EXTRA] = strdup(cpt->loader_extra);
+
+  info->argc = LOADER_ARG_DUMMY + 1;
+  info->type = cpt->type;
+  info->loader_id = cpt->loader_id;
+
+  *candidate_info = info;
+  return 0;
+}
+
+static int __prepare_candidate_process(int type, int loader_id) {
+  candidate_process_context_t* cpt = __find_slot(type, loader_id);
+  candidate_info_t* info;
+  int ret;
+
+  if (cpt == nullptr)
+    return -1;
+
+  if (cpt->is_hydra && cpt->hydra_pid != HYDRA_NONE)
+    return __hydra_send_launch_candidate_request(cpt->hydra_fd);
+
+  _D("prepare candidate process / type:%d", type);
+  ret = __candidate_info_create(cpt, &info);
+  if (ret < 0)
+    return ret;
+
+  info->pid = __fork_app_process(__exec_loader_process, info->argv,
+      cpt->sched_priority);
+  if (info->pid == -1) {
+    _E("Failed to create a child process. type: %d", type);
+    __candidate_info_free(info);
+    return -1;
+  }
+
+  _W("Candidate process. type: %d, loader_id: %d, pid: %d", info->type,
+     info->loader_id, info->pid);
+  cpt = __find_slot(info->type, info->loader_id);
+  if (cpt == nullptr) {
+    _E("Not found slot.");
+    __candidate_info_free(info);
+    return -1;
+  }
+
+  cpt->last_exec_time = time(nullptr);
+  if (cpt->is_hydra) {
+    cpt->hydra_pid = info->pid;
+  } else {
+    cpt->pid = info->pid;
+    __set_live_timer(cpt);
+  }
+
+  _log_print("[CANDIDATE]", "pid(%7d) | type(%d) | loader(%s)", info->pid,
+             cpt->loader_id, cpt->loader_name);
+  _memory_monitor_reset_timer();
+  __candidate_info_free(info);
+  return 0;
+}
+
+static gboolean __handle_timeout_event(gpointer user_data) {
+  candidate_process_context_t* cpc;
+
+  cpc = (candidate_process_context_t*)user_data;
+  cpc->timer = 0;
+
+  if (cpc->pid != CANDIDATE_NONE) {
+    _W("Candidate(%d) process(%d) is running", cpc->type, cpc->pid);
+    return G_SOURCE_REMOVE;
+  }
+
+  __sequencer_add_slot(cpc);
+  __sequencer_run();
+  return G_SOURCE_REMOVE;
+}
+
+static void __set_timer(candidate_process_context_t* cpc) {
+  if (cpc == nullptr || cpc->timer > 0)
+    return;
+
+  if ((cpc->detection_method & static_cast<int>(launchpad::LoaderMethod::Timeout)) &&
+      cpc->state == CANDIDATE_PROCESS_STATE_RUNNING) {
+    cpc->timer = g_timeout_add(cpc->timeout_val, __handle_timeout_event, cpc);
+  }
+}
+
+static void __reset_slot(candidate_process_context_t* cpc) {
+  if (cpc == nullptr)
+    return;
+
+  cpc->send_fd = -1;
+  cpc->prepared = false;
+  cpc->pid = CANDIDATE_NONE;
+  cpc->client_channel = nullptr;
+  cpc->timer = 0;
+  cpc->live_timer = 0;
+  cpc->on_boot_timer = 0;
+}
+
+static void __dispose_candidate_process(candidate_process_context_t* cpc) {
+  if (!cpc)
+    return;
+
+  _D("Dispose candidate process %d", cpc->type);
+  if (cpc->pid > 0) {
+    _D("kill process %d", cpc->pid);
+    __kill_process(cpc->pid);
+  }
+  if (cpc->live_timer > 0)
+    g_source_remove(cpc->live_timer);
+  if (cpc->client_channel)
+    _io_channel_destroy(cpc->client_channel);
+  if (cpc->timer > 0)
+    g_source_remove(cpc->timer);
+  if (cpc->send_fd > 0)
+    close(cpc->send_fd);
+  if (cpc->on_boot_timer > 0)
+    g_source_remove(cpc->on_boot_timer);
+  __reset_slot(cpc);
+}
+
+static void __dispose_hydra_process(candidate_process_context_t* cpc) {
+  if (!cpc)
+    return;
+
+  __dispose_candidate_process(cpc);
+
+  _D("Dispose hydra process %d", cpc->type);
+  if (cpc->hydra_pid > 0) {
+    _D("kill process %d", cpc->hydra_pid);
+    __kill_process(cpc->hydra_pid);
+    cpc->hydra_pid = HYDRA_NONE;
+  }
+
+  if (cpc->hydra_fd > 0) {
+    close(cpc->hydra_fd);
+    cpc->hydra_fd = -1;
+  }
+}
+
+static int __send_launchpad_loader(candidate_process_context_t* cpc,
+                                   app_pkt_t* pkt,
+                                   const char* app_path,
+                                   int clifd) {
+  int pid = -1;
+  int ret;
+
+  ret = _delete_sock_path(cpc->pid, getuid());
+  if (ret != 0)
+    return -1;
+
+  __candidate_process_real_launch(cpc->send_fd, pkt);
+  SECURE_LOGD("Request to candidate process, pid: %d, bin path: %s", cpc->pid,
+              app_path);
+
+  pid = cpc->pid;
+  cpc->pid = CANDIDATE_NONE;
+  __dispose_candidate_process(cpc);
+  __set_timer(cpc);
+  __update_slot_score(cpc);
+
+  return pid;
+}
+
+static int __normal_fork_exec(int argc, char** argv, const char* app_path) {
+  char* libdir;
+  char err_buf[1024];
+
+  _D("start real fork and exec");
+
+  libdir = _get_libdir(app_path);
+  if (libdir) {
+    setenv("LD_LIBRARY_PATH", libdir, 1);
+    free(libdir);
+  }
+
+  _close_all_fds();
+
+  if (execv(argv[LOADER_ARG_PATH], argv) < 0) { /* Flawfinder: ignore */
+    _send_message_to_logger(argv[LOADER_ARG_PATH],
+                            "Failed to execute a file. error(%d:%s)", errno,
+                            strerror_r(errno, err_buf, sizeof(err_buf)));
+    return -1;
+  }
+  /* never reach*/
+  return 0;
+}
+
+static int __create_launcher_argv(int* argc,
+                                  char*** argv,
+                                  const char* app_type) {
+  int launcher_argc;
+  char** launcher_argv;
+  launchpad::LauncherInfoPtr launcher_info;
+  const char* exe;
+  int i;
+
+  auto it = std::find_if(
+      launcher_info_list.begin(), launcher_info_list.end(),
+      [app_type](const launchpad::LauncherInfoPtr& info) -> bool {
+        return std::find_if(info->GetAppTypes().begin(),
+                            info->GetAppTypes().end(),
+                            [app_type](const std::string& type) -> bool {
+                              return strcmp(type.c_str(), app_type) == 0;
+                            }) != info->GetAppTypes().end();
+      });
+
+  if (it == launcher_info_list.end())
+    return 0;
+
+  launcher_info = *it;
+  exe = launcher_info->GetExe().c_str();
+
+  auto& extra_args = launcher_info->GetExtraArgs();
+  launcher_argc = extra_args.size() + 1;
+  launcher_argv = static_cast<char**>(calloc(launcher_argc, sizeof(char*)));
+  if (launcher_argv == nullptr) {
+    _E("out of memory");
+    return -1;
+  }
+
+  i = LOADER_ARG_PATH;
+  launcher_argv[i++] = strdup(exe);
+
+  for (auto& extra_arg : extra_args) {
+    launcher_argv[i++] = strdup(extra_arg.c_str());
+  }
+
+  *argc = launcher_argc;
+  *argv = launcher_argv;
+
+  return 0;
+}
+
+static void __destroy_launcher_argv(int argc, char** argv) {
+  int i;
+
+  if (argv == nullptr)
+    return;
+
+  for (i = 0; i < argc; i++)
+    free(argv[i]);
+  free(argv);
+}
+
+static int __create_app_argv(int* argc,
+                             char*** argv,
+                             const char* app_path,
+                             bundle* kb,
+                             const char* app_type) {
+  int new_argc;
+  char** new_argv;
+  bool attach = false;
+  struct app_arg debug_arg = {
+      0,
+  };
+  struct app_arg launcher_arg = {
+      0,
+  };
+  struct app_arg arg = {
+      0,
+  };
+  struct app_arg debug_extra_arg = {
+      0,
+  };
+  int ret;
+  int i;
+  int c;
+
+  ret = _debug_create_argv(&debug_arg.argc, &debug_arg.argv, &attach);
+  if (ret < 0) {
+    _E("Failed to create debugger argv");
+    return -1;
+  }
+
+  if (attach) {
+    *argc = debug_arg.argc;
+    *argv = debug_arg.argv;
+    return 0;
+  }
+
+  ret = _debug_create_extra_argv(&debug_extra_arg.argc, &debug_extra_arg.argv);
+  if (ret < 0) {
+    _E("Failed to create debugger extra argv");
+    _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
+    return -1;
+  }
+
+  ret =
+      __create_launcher_argv(&launcher_arg.argc, &launcher_arg.argv, app_type);
+  if (ret < 0) {
+    _E("Failed to create launcher argv");
+    _debug_destroy_argv(debug_extra_arg.argc, debug_extra_arg.argv);
+    _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
+    return -1;
+  }
+
+  arg.argc = bundle_export_to_argv(kb, &arg.argv);
+  if (arg.argc <= 0) {
+    _E("Failed to export bundle");
+    __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
+    _debug_destroy_argv(debug_extra_arg.argc, debug_extra_arg.argv);
+    _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
+    return -1;
+  }
+  arg.argv[LOADER_ARG_PATH] = strdup(app_path);
+
+  new_argc =
+      debug_arg.argc + launcher_arg.argc + arg.argc + debug_extra_arg.argc;
+  if (new_argc == arg.argc) {
+    *argc = arg.argc;
+    *argv = arg.argv;
+    return 0;
+  }
+
+  new_argv = (char**)calloc(new_argc + 1, sizeof(char*));
+  if (new_argv == nullptr) {
+    _E("out of memory");
+    free(arg.argv[LOADER_ARG_PATH]);
+    bundle_free_exported_argv(arg.argc, &arg.argv);
+    __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
+    _debug_destroy_argv(debug_extra_arg.argc, debug_extra_arg.argv);
+    _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
+    return -1;
+  }
+
+  c = LOADER_ARG_PATH;
+  for (i = 0; i < debug_arg.argc; i++)
+    new_argv[c++] = debug_arg.argv[i];
+  for (i = 0; i < launcher_arg.argc; i++)
+    new_argv[c++] = launcher_arg.argv[i];
+  for (i = 0; i < arg.argc; i++)
+    new_argv[c++] = arg.argv[i];
+  for (i = 0; i < debug_extra_arg.argc; i++)
+    new_argv[c++] = debug_extra_arg.argv[i];
+
+  *argc = new_argc;
+  *argv = new_argv;
+
+  return 0;
+}
+
+static void __real_launch(const char* app_path,
+                          bundle* kb,
+                          appinfo_t* menu_info) {
+  int app_argc = 0;
+  char** app_argv;
+  int i;
+  int ret;
+
+  if (bundle_get_val(kb, AUL_K_DEBUG) != nullptr)
+    putenv("TIZEN_DEBUGGING_PORT=1");
+
+  ret = __create_app_argv(&app_argc, &app_argv, app_path, kb,
+                          menu_info->app_type);
+  if (ret < 0) {
+    _E("Failed to create app argv");
+    exit(-1);
+  }
+
+  for (i = 0; i < app_argc; i++)
+    SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
+
+  PERF("setup argument done");
+  __normal_fork_exec(app_argc, app_argv, app_path);
+}
+
+static int __prepare_exec(const char* appid,
+                          const char* app_path,
+                          appinfo_t* menu_info,
+                          bundle* kb) {
+  char* file_name;
+  const char* enabled_light_user;
+  char process_name[AUL_PR_NAME];
+  int ret;
+
+  /* Set new session ID & new process group ID*/
+  /* In linux, child can set new session ID without check permission */
+  /* TODO : should be add to check permission in the kernel*/
+  setsid();
+
+  ret = _launchpad_plugin_prepare_app(appid, kb);
+  if (ret < 0) {
+    _E("_launchpad_plugin_prepare_app() is failed. error(%d)", ret);
+    return PAD_ERR_FAILED;
+  }
+
+  ret = _enable_external_pkg(kb, menu_info->pkgid,
+                             menu_info->global ? GLOBAL_USER : getuid());
+  if (ret < 0)
+    return PAD_ERR_FAILED;
+
+  if (menu_info->global)
+    ret = trust_anchor_launch(menu_info->pkgid, GLOBAL_USER);
+  else
+    ret = trust_anchor_launch(menu_info->pkgid, getuid());
+  if (ret != TRUST_ANCHOR_ERROR_NONE &&
+      ret != TRUST_ANCHOR_ERROR_NOT_INSTALLED) {
+    _E("trust_anchor_launch() returns %d", ret);
+    return PAD_ERR_REJECTED;
+  }
+
+  ret = _mount_res_dir(menu_info->root_path, kb);
+  if (ret < 0)
+    return PAD_ERR_FAILED;
+
+  if (bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
+    _debug_change_mount_namespace();
+
+  /* SET PRIVILEGES*/
+  enabled_light_user = bundle_get_val(kb, AUL_K_ENABLED_LIGHT_USER);
+  _W("security_manager_prepare_app2 ++ %s", appid);
+  ret = security_manager_prepare_app2(appid, enabled_light_user);
+  _W("security_manager_prepare_app2 -- %s", appid);
+  if (ret != SECURITY_MANAGER_SUCCESS)
+    return PAD_ERR_REJECTED;
+
+  if (bundle_get_type(kb, AUL_K_SDK) == BUNDLE_TYPE_NONE)
+    _setup_stdio(basename(app_path));
+
+  /* SET DUMPABLE - for coredump*/
+  prctl(PR_SET_DUMPABLE, 1);
+
+  /* SET PROCESS NAME*/
+  if (app_path == nullptr)
+    return PAD_ERR_INVALID_ARGUMENT;
+
+  file_name = const_cast<char*>(strrchr(app_path, '/'));
+  if (file_name == nullptr)
+    return PAD_ERR_INVALID_PATH;
+
+  file_name++;
+  if (*file_name == '\0')
+    return PAD_ERR_INVALID_PATH;
+
+  memset(process_name, '\0', AUL_PR_NAME);
+  snprintf(process_name, AUL_PR_NAME, "%s", file_name);
+  prctl(PR_SET_NAME, process_name);
+
+  /* SET ENVIROMENT*/
+  _set_env(menu_info, kb);
+
+  ret = _wait_tep_mount(kb);
+  if (ret < 0)
+    return PAD_ERR_FAILED;
+
+  if (bundle_get_type(kb, AUL_K_SDK) == BUNDLE_TYPE_NONE) {
+    ret = _prepare_app_socket();
+    if (ret < 0)
+      return PAD_ERR_FAILED;
+
+    ret = _prepare_id_file();
+    if (ret < 0)
+      return PAD_ERR_FAILED;
+  }
+
+  _send_cmd_to_amd(APP_STARTUP_SIGNAL);
+  return 0;
+}
+
+static int __exec_app_process(void* arg) {
+  auto* launch_arg = static_cast<app_launch_arg*>(arg);
+  int ret;
+
+  _print_hwc_log("%d|after calling fork(). %s", getpid(), launch_arg->appid);
+  PERF("fork done");
+  _D("lock up test log(no error) : fork done");
+
+  if (bundle_get_type(launch_arg->kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
+    _debug_prepare_debugger(launch_arg->kb);
+
+  _signal_unblock_sigchld();
+
+  _delete_sock_path(getpid(), getuid());
+
+  PERF("prepare exec - first done");
+  ret = __prepare_exec(launch_arg->appid, launch_arg->app_path,
+                       launch_arg->menu_info, launch_arg->kb);
+  if (ret < 0)
+    return ret;
+
+  PERF("prepare exec - second done");
+  __real_launch(launch_arg->app_path, launch_arg->kb, launch_arg->menu_info);
+
+  return PAD_ERR_FAILED;
+}
+
+static int __launch_directly(const char* appid,
+                             const char* app_path,
+                             int clifd,
+                             bundle* kb,
+                             appinfo_t* menu_info,
+                             candidate_process_context_t* cpc) {
+  struct app_launch_arg arg;
+  int pid;
+
+  arg.appid = appid;
+  arg.app_path = app_path;
+  arg.menu_info = menu_info;
+  arg.kb = kb;
+
+  _print_hwc_log("before calling fork(). %s", appid);
+  pid = __fork_app_process(__exec_app_process, &arg, 0);
+  if (pid <= 0)
+    _E("failed to fork app process");
+
+  SECURE_LOGD("==> real launch pid : %d %s", pid, app_path);
+
+  return pid;
+}
+
+static int __create_sock_activation(void) {
+  int fds;
+  char launchpad_process_pool_sock_path[108];
+  int i;
+
+  fds = sd_listen_fds(0);
+  snprintf(launchpad_process_pool_sock_path,
+           sizeof(launchpad_process_pool_sock_path), "%s/daemons/%u/%s",
+           SOCKET_PATH, getuid(), PROCESS_POOL_LAUNCHPAD_SOCK);
+
+  for (i = SD_LISTEN_FDS_START; i < SD_LISTEN_FDS_START + fds; ++i) {
+    if (sd_is_socket_unix(i, SOCK_STREAM, 1, launchpad_process_pool_sock_path,
+                          0) > 0)
+      return i;
+  }
+
+  _W("There is no socket stream");
+  return -1;
+}
+
+static int __get_launchpad_listen_fd(void) {
+  const char* val;
+
+  val = getenv("LAUNCHPAD_LISTEN_FD");
+  if (!val) {
+    _E("Failed to get LAUNCHPAD_LISTEN_FD");
+    return -1;
+  }
+
+  _W("Listen Fd: %s", val);
+  return atoi(val);
+}
+
+static int __launchpad_pre_init(int argc, char** argv) {
+  int fd;
+
+  /* create launchpad sock */
+  fd = __create_sock_activation();
+  if (fd >= 0)
+    return fd;
+
+  fd = __get_launchpad_listen_fd();
+  if (fd >= 0)
+    return fd;
+
+  fd = _create_server_sock(PROCESS_POOL_LAUNCHPAD_SOCK);
+  if (fd < 0) {
+    _E("server sock error %d", fd);
+    return -1;
+  }
+
+  return fd;
+}
+
+static bool __handle_loader_client_event(int fd,
+                                         io_condition_e cond,
+                                         void* data) {
+  auto* cpc = static_cast<candidate_process_context_t*>(data);
+
+  if (cpc == nullptr)
+    return false;
+
+  if (cond & (IO_HUP | IO_NVAL)) {
+    SECURE_LOGE(
+        "Type %d candidate process was "
+        "(POLLHUP|POLLNVAL), pid: %d",
+        cpc->type, cpc->pid);
+    cpc->pid = CANDIDATE_NONE;
+    __dispose_candidate_process(cpc);
+    __prepare_candidate_process(cpc->type, cpc->loader_id);
+    return false;
+  }
+
+  return true;
+}
+
+static bool __handle_hydra_client_event(int fd,
+                                        io_condition_e cond,
+                                        void* data) {
+  auto* cpc = static_cast<candidate_process_context_t*>(data);
+  int recv_pid = -1;
+  int ret;
+
+  if (cpc == nullptr)
+    return false;
+
+  if (cond & (IO_HUP | IO_NVAL)) {
+    SECURE_LOGE(
+        "Type %d hydra process was "
+        "(POLLHUP|POLLNVAL), pid: %d",
+        cpc->type, cpc->hydra_pid);
+    __dispose_hydra_process(cpc);
+    __prepare_candidate_process(cpc->type, cpc->loader_id);
+    return false;
+  }
+
+  if (cond & IO_IN) {
+    ret = recv(cpc->hydra_fd, &recv_pid, sizeof(recv_pid), MSG_WAITALL);
+    if (ret == -1) {
+      _E("recv() is failed. errno(%d)", errno);
+    } else {
+      _W("candidate process: %d", recv_pid);
+      if (recv_pid > 1)
+        cpc->pid = recv_pid;
+    }
+  }
+
+  return true;
+}
+
+static bool __handle_loader_event(int fd, io_condition_e cond, void* data) {
+  auto* cpc = static_cast<candidate_process_context_t*>(data);
+  int client_fd;
+  int client_pid;
+  int ret;
+
+  if (cpc == nullptr)
+    return false;
+
+  if (!cpc->prepared) {
+    ret = __accept_candidate_process(fd, &client_fd, &client_pid,
+                                     cpc->is_hydra ? -1 : cpc->pid);
+    if (ret >= 0) {
+      /* for hydra need to set pid to pid of non-hydra candidate, */
+      /* which is connecting now */
+      if (cpc->is_hydra)
+        cpc->pid = client_pid;
+
+      cpc->prepared = true;
+      cpc->send_fd = client_fd;
+
+      SECURE_LOGI(
+          "Type %d candidate process was connected, "
+          "pid: %d",
+          cpc->type, cpc->pid);
+
+      _print_hwc_log(
+          "Type %d candidate process was connected, "
+          "pid: %d",
+          cpc->type, cpc->pid);
+      cpc->client_channel = _io_channel_create(
+          client_fd, static_cast<io_condition_e>(IO_IN | IO_HUP),
+          __handle_loader_client_event, cpc);
+      if (!cpc->client_channel)
+        close(client_fd);
+    }
+  } else {
+    __refuse_candidate_process(fd);
+    _E("Refused candidate process connection");
+  }
+
+  return true;
+}
+
+static bool __handle_hydra_event(int fd, io_condition_e cond, void* data) {
+  auto* cpc = static_cast<candidate_process_context_t*>(data);
+  int client_fd;
+  int client_pid;
+  int ret;
+
+  if (cpc == nullptr)
+    return false;
+
+  if (!cpc->prepared) {
+    ret =
+        __accept_candidate_process(fd, &client_fd, &client_pid, cpc->hydra_pid);
+    if (ret >= 0) {
+      cpc->hydra_fd = client_fd;
+
+      SECURE_LOGD(
+          "Type %d hydra process was connected,"
+          " pid: %d",
+          cpc->type, cpc->hydra_pid);
+
+      cpc->client_channel = _io_channel_create(
+          client_fd, static_cast<io_condition_e>(IO_IN | IO_HUP),
+          __handle_hydra_client_event, cpc);
+      if (!cpc->client_channel)
+        close(client_fd);
+    }
+  } else {
+    __refuse_candidate_process(fd);
+    _E("Refused hydra process connection");
+  }
+
+  return true;
+}
+
+static void __destroy_cleanup_info(struct cleanup_info_s* info) {
+  if (!info)
+    return;
+
+  free(info->appid);
+  free(info);
+}
+
+static struct cleanup_info_s* __create_cleanup_info(const char* appid,
+                                                    int pid) {
+  struct cleanup_info_s* info;
+
+  info = static_cast<cleanup_info_s*>(malloc(sizeof(struct cleanup_info_s)));
+  if (!info) {
+    _E("Out of memory");
+    return nullptr;
+  }
+
+  info->appid = strdup(appid);
+  if (!info->appid) {
+    _E("strdup(%s) is failed", appid);
+    __destroy_cleanup_info(info);
+    return nullptr;
+  }
+
+  info->pid = pid;
+
+  return info;
+}
+
+static bool __cleanup_app_cb(void* user_data) {
+  struct cleanup_info_s* info = (struct cleanup_info_s*)user_data;
+
+  _W("security_manager_cleanup_app() ++");
+  security_manager_cleanup_app(info->appid, getuid(), info->pid);
+  _W("security_manager_cleanup_app() --");
+  __destroy_cleanup_info(info);
+  return false;
+}
+
+static void __handle_sigchild(int pid, void* user_data) {
+  candidate_process_context_t* cpc;
+  struct cleanup_info_s* info;
+  char* appid;
+  int ret = -1;
+
+  appid = static_cast<char*>(
+      g_hash_table_lookup(__pid_table, GINT_TO_POINTER(pid)));
+  if (appid) {
+    info = __create_cleanup_info(appid, pid);
+    if (info)
+      ret = _worker_add_job(__cleaner, __cleanup_app_cb, info);
+
+    if (ret != 0) {
+      __destroy_cleanup_info(info);
+      _W("security_manager_cleanup_app() ++");
+      security_manager_cleanup_app(appid, getuid(), pid);
+      _W("security_manager_cleanup_app() --");
+    }
+
+    g_hash_table_remove(__pid_table, GINT_TO_POINTER(pid));
+  }
+
+  _log_print("[SIGCHLD]", "pid(%7d)", pid);
+  cpc = __find_slot_from_pid(pid);
+  if (cpc != nullptr) {
+    cpc->pid = CANDIDATE_NONE;
+    __dispose_candidate_process(cpc);
+    __prepare_candidate_process(cpc->type, cpc->loader_id);
+  } else {
+    cpc = __find_hydra_slot_from_pid(pid);
+    if (cpc != nullptr) {
+      cpc->hydra_pid = HYDRA_NONE;
+      __dispose_hydra_process(cpc);
+      __prepare_candidate_process(cpc->type, cpc->loader_id);
+    }
+  }
+
+  cpc = __find_slot_from_caller_pid(pid);
+  while (cpc) {
+    __remove_slot(static_cast<int>(launchpad::LoaderType::Dynamic), cpc->loader_id);
+    cpc = __find_slot_from_caller_pid(pid);
+  }
+}
+
+static bool __handle_label_monitor(int fd, io_condition_e cond, void* data) {
+  candidate_process_context_t* cpc;
+  GList* iter = candidate_slot_list;
+
+  if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
+    _E("fd(%d), io_condition(%d)", fd, cond);
+    abort();
+    return false;
+  }
+
+  _D("fd(%d) condition(%d)", fd, cond);
+  _log_print("[LABEL]", "fd(%d), condition(%d)", fd, cond);
+  security_manager_app_labels_monitor_process(label_monitor);
+
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (cpc->is_hydra) {
+      if (cpc->hydra_pid > 0) {
+        __dispose_hydra_process(cpc);
+        __prepare_candidate_process(cpc->type, cpc->loader_id);
+      }
+    } else if (cpc->pid > 0) {
+      __dispose_candidate_process(cpc);
+      __prepare_candidate_process(cpc->type, cpc->loader_id);
+    }
+
+    iter = g_list_next(iter);
+  }
+
+  return true;
+}
+
+static float __interpolator(float input, int cpu_max, int cpu_min) {
+  float ret;
+  float min = cpu_min / 100.0f;
+  float max = cpu_max / 100.0f;
+
+  if (input > 1.0f)
+    input = 1.0f;
+  if (input < 0.0f)
+    input = 0.0f;
+
+  ret = cos(input * PI) / 2.0f + 0.5f;
+  ret *= max - min;
+  ret += min;
+
+  return ret;
+}
+
+static void __update_threshold(candidate_process_context_t* cpc, float delta) {
+  static float pos = 0.0f;
+
+  pos += delta;
+  if (pos < 0.0f)
+    pos = 0.0f;
+
+  if (pos > 1.0f)
+    pos = 1.0f;
+
+  cpc->threshold =
+      (int)(__interpolator(pos, cpc->threshold_max, cpc->threshold_min) * 100);
+  _D("[CPU] type:%d / delta:%f / input cursor : %f / threshold : %d", cpc->type,
+     delta, pos, cpc->threshold);
+}
+
+static gboolean __handle_idle_checker(gpointer data) {
+  unsigned long long total = 0;
+  unsigned long long idle = 0;
+  int per;
+  candidate_process_context_t* cpc;
+
+  if (!data) {
+    _E("Critical error!");
+    __sequencer.idle_checker = 0;
+    __sequencer.running_cpc = nullptr;
+    return G_SOURCE_REMOVE;
+  }
+
+  cpc = (candidate_process_context_t*)data;
+  if (cpc->app_check && !cpc->app_exists) {
+    _W("The application is not installed. loader(%s:%d)", cpc->loader_name,
+       cpc->type);
+    __sequencer.idle_checker = 0;
+    __sequencer.running_cpc = nullptr;
+    return G_SOURCE_REMOVE;
+  }
+
+  if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING) {
+    _W("Slot state is not running. loader(%s:%d)", cpc->loader_name, cpc->type);
+    __sequencer.idle_checker = 0;
+    __sequencer.running_cpc = nullptr;
+    return G_SOURCE_REMOVE;
+  }
+
+  if (cpc->pid != CANDIDATE_NONE) {
+    _W("Slot is already running. %d:%s:%d", cpc->type, cpc->loader_name,
+       cpc->pid);
+    __sequencer.idle_checker = 0;
+    __sequencer.running_cpc = nullptr;
+    return G_SOURCE_REMOVE;
+  }
+
+  _get_cpu_idle(&total, &idle);
+  if (total == cpc->cpu_total_time)
+    total++;
+
+  per = (idle - cpc->cpu_idle_time) * 100 / (total - cpc->cpu_total_time);
+  _D("[CPU] Idle : %d / loader(%s:%d)", per, cpc->loader_name, cpc->type);
+
+  if (per >= cpc->threshold) {
+    __update_threshold(cpc, -0.02f * (per - cpc->threshold));
+    __prepare_candidate_process(cpc->type, cpc->loader_id);
+    cpc->touched = true;
+    __sequencer.idle_checker = 0;
+    __sequencer.running_cpc = nullptr;
+    return G_SOURCE_REMOVE;
+  }
+
+  cpc->cpu_idle_time = idle;
+  cpc->cpu_total_time = total;
+  __update_threshold(cpc, 0.05f);
+
+  cpc->cpu_check_count++;
+  if (cpc->cpu_check_count == MAX_CPU_CHECK_COUNT) {
+    _W("CPU check count has exceeded %d times. loader(%s:%d)",
+       cpc->cpu_check_count, cpc->loader_name, cpc->type);
+    __sequencer.idle_checker = 0;
+    __sequencer.running_cpc = nullptr;
+    __sequencer_add_slot(cpc);
+    return G_SOURCE_REMOVE;
+  }
+
+  return G_SOURCE_CONTINUE;
+}
+
+static gboolean __on_boot_timeout_cb(gpointer user_data) {
+  auto* context = static_cast<candidate_process_context_t*>(user_data);
+
+  _W("type(%d), loader_name(%s)", context->type, context->loader_name);
+  context->on_boot_timer = 0;
+  if (context->pid != CANDIDATE_NONE) {
+    _E("Candidate process is already running. %d:%s:%d", context->type,
+       context->loader_name, context->pid);
+  } else {
+    __prepare_candidate_process(context->type, context->loader_id);
+    context->touched = true;
+  }
+
+  return G_SOURCE_REMOVE;
+}
+
+static void __add_on_boot_timer(candidate_process_context_t* context) {
+  if (context->on_boot_timer != 0)
+    return;
+
+  context->on_boot_timer =
+      g_timeout_add(context->on_boot_timeout, __on_boot_timeout_cb, context);
+}
+
+static int __add_idle_checker(int detection_method, GList* cur) {
+  candidate_process_context_t* cpc;
+  GList* iter = cur;
+
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (!cpc->touched && cpc->on_boot && cpc->on_boot_timeout > 0)
+      __add_on_boot_timer(cpc);
+
+    if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING) {
+      iter = g_list_next(iter);
+      continue;
+    }
+
+    if (strcmp("null", cpc->loader_path) == 0) {
+      iter = g_list_next(iter);
+      continue;
+    }
+
+    if (!cpc->touched && !cpc->on_boot) {
+      iter = g_list_next(iter);
+      continue;
+    }
+
+    if (cpc->app_check && !cpc->app_exists) {
+      iter = g_list_next(iter);
+      continue;
+    }
+
+    if (cpc->pid == CANDIDATE_NONE &&
+        (!cpc->touched || (cpc->detection_method & detection_method))) {
+      if (cpc->timer > 0) {
+        g_source_remove(cpc->timer);
+        cpc->timer = 0;
+      }
+
+      cpc->cur_event = detection_method;
+      __sequencer_add_slot(cpc);
+      __sequencer_run();
+    }
+
+    iter = g_list_next(iter);
+  }
+
+  return -1;
+}
+
+static int __dispatch_cmd_hint(bundle* kb, int detection_method) {
+  _W("cmd hint %d", detection_method);
+  __add_idle_checker(detection_method, candidate_slot_list);
+
+  return 0;
+}
+
+static int __dispatch_cmd_add_loader(bundle* kb) {
+  const char* add_slot_str = nullptr;
+  const char* caller_pid = nullptr;
+  const char* extra;
+  int lid, size;
+  char* loader_name;
+  candidate_process_context_t* cpc;
+  slot_info_t slot_info;
+
+  _W("cmd add loader");
+  add_slot_str = bundle_get_val(kb, AUL_K_LOADER_PATH);
+  caller_pid = bundle_get_val(kb, AUL_K_CALLER_PID);
+  extra = bundle_get_val(kb, AUL_K_LOADER_EXTRA);
+
+  if (add_slot_str == nullptr || caller_pid == nullptr)
+    return -1;
+
+  lid = __make_loader_id();
+  size = snprintf(0, 0, "%s%s%d", add_slot_str, caller_pid, lid);
+  loader_name = (char*)malloc(size + 1);
+  if (loader_name == nullptr) {
+    _E("Out of memory");
+    return -1;
+  }
+
+  snprintf(loader_name, size, "%s%s%d", add_slot_str, caller_pid, lid);
+
+  slot_info.type = static_cast<int>(launchpad::LoaderType::Dynamic);
+  slot_info.loader_id = lid;
+  slot_info.caller_pid = atoi(caller_pid);
+  slot_info.loader_name = loader_name;
+  slot_info.loader_path = add_slot_str;
+  slot_info.loader_extra = extra;
+  slot_info.detection_method = static_cast<int>(
+      launchpad::LoaderMethod::Timeout | launchpad::LoaderMethod::Visibility);
+  slot_info.activation_method =
+      static_cast<int>(launchpad::LoaderMethod::Request |
+                       launchpad::LoaderMethod::AvailableMemory);
+  slot_info.deactivation_method = static_cast<int>(
+      launchpad::LoaderMethod::Ttl | launchpad::LoaderMethod::OutOfMemory);
+  slot_info.ttl = 600;
+  slot_info.timeout_val = 2000;
+  slot_info.threshold_max = launchpad::DefaultCpuThresholdMax;
+  slot_info.threshold_min = launchpad::DefaultCpuThresholdMin;
+  slot_info.on_boot = false;
+  slot_info.app_exists = true;
+  slot_info.is_hydra = false;
+  slot_info.app_check = true;
+  slot_info.on_boot_timeout = 0;
+  slot_info.sched_priority = 0;
+
+  cpc = __add_slot(&slot_info);
+  free(loader_name);
+  if (cpc == nullptr)
+    return -1;
+
+  __set_timer(cpc);
+  return lid;
+}
+
+static int __dispatch_cmd_add_app_defined_loader(bundle* kb) {
+  const char* loader_name;
+  int lid, len;
+  candidate_process_context_t* cpc;
+  launchpad::LoaderInfoPtr info;
+  bundle_raw* extra;
+  slot_info_t slot_info;
+
+  _W("cmd add defined loader");
+  loader_name = bundle_get_val(kb, AUL_K_LOADER_NAME);
+
+  if (loader_name == nullptr) {
+    _E("loader_name is nullptr");
+    return -EINVAL;
+  }
+
+  info = app_defined_loader_info_manager->FindLoaderInfo(loader_name);
+  if (info == nullptr) {
+    _E("loader_name %s, info  %d", loader_name, info != nullptr);
+    return -EINVAL;
+  }
+
+  cpc = __find_slot_from_loader_name(loader_name);
+  if (cpc == nullptr) {
+    lid = __make_loader_id();
+    bundle_encode(info->GetExtra().GetHandle(), &extra, &len);
+    slot_info.type = static_cast<int>(launchpad::LoaderType::Dynamic);
+    slot_info.loader_id = lid;
+    slot_info.caller_pid = 0;
+    slot_info.loader_name = loader_name;
+    slot_info.loader_path = "/usr/bin/app-defined-loader";
+    slot_info.loader_extra = (const char*)extra;
+    slot_info.detection_method = static_cast<int>(launchpad::LoaderMethod::Timeout) | static_cast<int>(launchpad::LoaderMethod::Visibility);
+    slot_info.activation_method = static_cast<int>(launchpad::LoaderMethod::Request) | static_cast<int>(launchpad::LoaderMethod::AvailableMemory);
+    slot_info.deactivation_method = static_cast<int>(launchpad::LoaderMethod::Ttl) | static_cast<int>(launchpad::LoaderMethod::OutOfMemory);
+    slot_info.ttl = info->GetTtl();
+    slot_info.timeout_val = 2000;
+    slot_info.threshold_max = launchpad::DefaultCpuThresholdMax;
+    slot_info.threshold_min = launchpad::DefaultCpuThresholdMin;
+    slot_info.on_boot = false;
+    slot_info.app_exists = true;
+    slot_info.is_hydra = false;
+    slot_info.app_check = true;
+    slot_info.on_boot_timeout = 0;
+    slot_info.sched_priority = 0;
+
+    cpc = __add_slot(&slot_info);
+    bundle_free_encoded_rawdata(&extra);
+    if (cpc == nullptr) {
+      _E("cpc is nullptr");
+      return -ENOMEM;
+    }
+  } else {
+    lid = cpc->loader_id;
+  }
+
+  if (cpc->pid == CANDIDATE_NONE)
+    __prepare_candidate_process(static_cast<int>(launchpad::LoaderType::Dynamic), lid);
+
+  return lid;
+}
+
+static int __dispatch_cmd_remove_loader(bundle* kb) {
+  const char* id = bundle_get_val(kb, AUL_K_LOADER_ID);
+  int lid;
+
+  _W("cmd remove loader");
+  if (id) {
+    lid = atoi(id);
+    if (__remove_slot(static_cast<int>(launchpad::LoaderType::Dynamic), lid) == 0)
+      return 0;
+  }
+
+  return -1;
+}
+
+static int __check_caller_by_pid(int pid) {
+  int ret;
+  char buf[PATH_MAX] = {
+      0,
+  };
+
+  ret = _proc_get_attr(pid, buf, sizeof(buf));
+  if (ret < 0)
+    return -1;
+
+  if (strcmp(buf, "User") == 0 || strcmp(buf, "System") == 0 ||
+      strcmp(buf, "System::Privileged") == 0)
+    return 0;
+
+  return -1;
+}
+
+static bool __is_hw_acc(const char* hwacc) {
+  if (strcmp(hwacc, "USE") == 0 ||
+      (strcmp(hwacc, "SYS") == 0 && __sys_hwacc == SETTING_HW_ACCELERATION_ON))
+    return true;
+
+  return false;
+}
+
+static candidate_process_context_t* __find_available_slot(
+    const char* hwacc,
+    const char* app_type,
+    const char* loader_name,
+    candidate_process_context_t** org_cpc) {
+  launchpad::LoaderType type = launchpad::LoaderType::Unsupported;
+  candidate_process_context_t* cpc;
+
+  if (loader_name) {
+    for (auto& info : loader_info_manager->GetLoaderInfoList()) {
+      if (info->GetName() == loader_name) {
+        type = info->GetType();
+        break;
+      }
+    }
+  } else {
+    if (__is_hw_acc(hwacc))
+      type = loader_info_manager->FindHwType(app_type);
+    else
+      type = loader_info_manager->FindSwType(app_type);
+  }
+
+  cpc = __find_slot(static_cast<int>(type), PAD_LOADER_ID_STATIC);
+  if (!cpc)
+    return nullptr;
+
+  *org_cpc = cpc;
+
+  if (cpc->prepared)
+    return cpc;
+
+  auto a_types = loader_info_manager->GetAlternativeTypes(type);
+  if (a_types.empty())
+    return nullptr;
+
+  for (auto& a_type : a_types) {
+    cpc =  __find_slot(static_cast<int>(a_type), PAD_LOADER_ID_STATIC);
+    if (!cpc)
+      continue;
+    if (cpc->prepared) {
+      return cpc;
+    }
+  }
+
+  return nullptr;
+}
+
+static void __update_slot(int type, bool app_exists) {
+  candidate_process_context_t* cpc;
+
+  cpc = __find_slot(type, PAD_LOADER_ID_STATIC);
+  if (!cpc)
+    return;
+
+  cpc->app_exists = app_exists;
+  if (cpc->app_check && !cpc->app_exists) {
+    if (cpc->pid > 0)
+      __dispose_candidate_process(cpc);
+    __sequencer_remove_slot(cpc);
+    if (__sequencer_queue_is_empty())
+      __sequencer_stop();
+  } else {
+    if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING)
+      return;
+
+    if (!cpc->touched && !cpc->on_boot)
+      return;
+
+    if (cpc->timer > 0) {
+      g_source_remove(cpc->timer);
+      cpc->timer = 0;
+    }
+
+    if (cpc->pid == CANDIDATE_NONE) {
+      __sequencer_add_slot(cpc);
+      __sequencer_run();
+    }
+  }
+}
+
+static void __foreach_loader_info(const launchpad::LoaderInfoPtr& info,
+    void* data) {
+  struct app_info* ai = (struct app_info*)data;
+  auto it = std::find_if(
+      info->GetAppTypes().begin(), info->GetAppTypes().end(),
+      [&](const std::string& type) -> bool { return type == ai->type; });
+
+  if (it == info->GetAppTypes().end())
+    return;
+
+  info->SetAppExists(ai->exists);
+  __update_slot(static_cast<int>(info->GetType()), info->IsAppExists());
+}
+
+static int __dispatch_cmd_update_app_type(bundle* b) {
+  int r;
+  struct app_info info;
+  const char* is_installed;
+
+  info.type = bundle_get_val(b, AUL_K_APP_TYPE);
+  if (!info.type)
+    return -1;
+
+  is_installed = bundle_get_val(b, AUL_K_IS_INSTALLED);
+  if (is_installed && !strcmp(is_installed, "true"))
+    info.exists = true;
+  else
+    info.exists = false;
+
+  _I("[LAUNCHPAD] type(%s), exists(%d)", info.type, info.exists);
+
+  for (auto& linfo : loader_info_manager->GetLoaderInfoList()) {
+    __foreach_loader_info(linfo, &info);
+  }
+
+  return 0;
+}
+
+static void __deactivate_slot(candidate_process_context_t* cpc) {
+  if (cpc->state == CANDIDATE_PROCESS_STATE_PAUSED)
+    return;
+
+  cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
+  if (cpc->is_hydra)
+    __dispose_hydra_process(cpc);
+  else
+    __dispose_candidate_process(cpc);
+}
+
+static void __activate_slot(candidate_process_context_t* cpc) {
+  if (cpc->state == CANDIDATE_PROCESS_STATE_RUNNING)
+    return;
+
+  cpc->state = CANDIDATE_PROCESS_STATE_RUNNING;
+  if (!cpc->touched && !cpc->on_boot)
+    return;
+
+  if ((cpc->app_check && !cpc->app_exists) || cpc->pid > CANDIDATE_NONE)
+    return;
+
+  if (cpc->detection_method & static_cast<int>(launchpad::LoaderMethod::Timeout))
+    __set_timer(cpc);
+}
+
+static void __update_slot_state(candidate_process_context_t* cpc,
+                                launchpad::LoaderMethod method,
+                                bool force) {
+  switch (method) {
+    case launchpad::LoaderMethod::OutOfMemory:
+      if ((force || cpc->deactivation_method & static_cast<int>(method)) && __is_low_memory()) {
+        _W("Low memory, deactivate slot %d", cpc->type);
+        __deactivate_slot(cpc);
+      } else {
+        __activate_slot(cpc);
+      }
+      break;
+    case launchpad::LoaderMethod::Ttl:
+      if (force || cpc->deactivation_method & static_cast<int>(method))
+        __deactivate_slot(cpc);
+      break;
+    case launchpad::LoaderMethod::AvailableMemory:
+      if (force || cpc->activation_method & static_cast<int>(method))
+        __activate_slot(cpc);
+      break;
+    case launchpad::LoaderMethod::Request:
+      if (force || cpc->activation_method & static_cast<int>(method))
+        __update_slot_state(cpc, launchpad::LoaderMethod::OutOfMemory, force);
+      break;
+    default:
+      __activate_slot(cpc);
+      break;
+  }
+}
+
+static void __request_destroy(request_t* request) {
+  if (request == nullptr)
+    return;
+
+  if (request->clifd > -1)
+    close(request->clifd);
+  if (request->menu_info)
+    _appinfo_free(request->menu_info);
+  if (request->kb)
+    bundle_free(request->kb);
+  if (request->pkt)
+    free(request->pkt);
+  free(request);
+}
+
+static int __request_create(int fd, request_t** request) {
+  struct ucred cr;
+  request_t* req;
+
+  if (request == nullptr) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  req = static_cast<request_t*>(calloc(1, sizeof(request_t)));
+  if (req == nullptr) {
+    _E("calloc() is failed");
+    return -ENOMEM;
+  }
+
+  req->clifd = -1;
+  req->pkt = _accept_recv_pkt_raw(fd, &req->clifd, &cr);
+  if (req->pkt == nullptr) {
+    _E("_accept_recv_pkt_raw() is failed");
+    __request_destroy(req);
+    return -ECOMM;
+  }
+
+  req->kb = bundle_decode(req->pkt->data, req->pkt->len);
+  if (req->kb == nullptr) {
+    _E("bundle_decode() is failed");
+    __real_send(req->clifd, -EINVAL);
+    req->clifd = -1;
+    __request_destroy(req);
+    return -EINVAL;
+  }
+
+  req->cmd = req->pkt->cmd;
+  req->caller_pid = cr.pid;
+  req->caller_uid = cr.uid;
+  *request = req;
+  return 0;
+}
+
+static void __request_send_result(request_h request, int result) {
+  if (request->clifd < 0)
+    return;
+
+  __real_send(request->clifd, result);
+  request->clifd = -1;
+}
+
+static int __visibility_request_handler(request_h request) {
+  int ret = __dispatch_cmd_hint(request->kb,
+      static_cast<int>(launchpad::LoaderMethod::Visibility));
+
+  __request_send_result(request, ret);
+  _D("[PAD_CMD_VISIBILITY] result: %d", ret);
+  return ret;
+}
+
+static int __add_loader_request_handler(request_h request) {
+  int ret = __dispatch_cmd_add_loader(request->kb);
+
+  __request_send_result(request, ret);
+  _D("[PAD_CMD_ADD_LOADER] result: %d", ret);
+  return ret;
+}
+
+static int __remove_loader_request_handler(request_h request) {
+  int ret = __dispatch_cmd_remove_loader(request->kb);
+
+  __request_send_result(request, ret);
+  _D("[PAD_CMD_REMOVE_LOADER] result: %d", ret);
+  return ret;
+}
+
+static int __make_default_slots_request_handler(request_h request) {
+  int ret = __add_default_slots();
+
+  __request_send_result(request, ret);
+  _D("[PAD_CMD_MAKE_DEFAULT_SLOTS] result: %d", ret);
+  return ret;
+}
+
+static int __prepare_app_defined_loader_request_handler(request_h request) {
+  int ret = __dispatch_cmd_add_app_defined_loader(request->kb);
+
+  __request_send_result(request, ret);
+  _D("[PAD_CMD_PREPARE_APP_DEFINED_LOADER] result: %d", ret);
+  return ret;
+}
+
+static int __demand_request_handler(request_h request) {
+  int ret = __dispatch_cmd_hint(request->kb,
+      static_cast<int>(launchpad::LoaderMethod::Demand));
+
+  __request_send_result(request, ret);
+  _D("[PAD_CMD_DEMAND] result: %d", ret);
+  return ret;
+}
+
+static int __ping_request_handler(request_h request) {
+  __request_send_result(request, getpid());
+  _D("[PAD_CMD_PING] result: %d", getpid());
+  return 0;
+}
+
+static int __update_app_type_request_handler(request_h request) {
+  int ret = __dispatch_cmd_update_app_type(request->kb);
+
+  _D("[PAD_CMD_UPDATE_APP_TYPE] result: %d", ret);
+  return ret;
+}
+
+static int __connect_request_handler(request_h request) {
+  if (__client_fd != -1)
+    close(__client_fd);
+
+  __client_fd = request->clifd;
+  request->clifd = -1;
+  _D("[PAD_CMD_CONNECT] client fd: %d", __client_fd);
+  return 0;
+}
+
+static int __launch_request_prepare(request_h request) {
+  const appinfo_t* menu_info;
+  int type = -1;
+
+  request->menu_info = _appinfo_create(request->kb);
+  if (request->menu_info == nullptr) {
+    _E("_appinfo_create() is failed");
+    return -1;
+  }
+
+  request->app_path = _appinfo_get_app_path(request->menu_info);
+  if (request->app_path == nullptr) {
+    _E("_appinfo_get_app_path() is failed");
+    return -1;
+  }
+
+  if (request->app_path[0] != '/') {
+    _E("app path is not absolute path");
+    return -1;
+  }
+
+  menu_info = request->menu_info;
+  if (menu_info->hwacc == nullptr) {
+    _E("Failed to find HW acceeleration type");
+    return -1;
+  }
+
+  SECURE_LOGD("appid: %s", menu_info->appid);
+  SECURE_LOGD("exec: %s", menu_info->app_path);
+  SECURE_LOGD("comp_type: %s", menu_info->comp_type);
+  SECURE_LOGD("internal pool: %s", menu_info->internal_pool);
+  SECURE_LOGD("hwacc: %s", menu_info->hwacc);
+  SECURE_LOGD("app_type: %s", menu_info->app_type);
+  SECURE_LOGD("pkg_type: %s", menu_info->pkg_type);
+
+  if (menu_info->comp_type && !strcmp(menu_info->comp_type, "svcapp")) {
+    request->loader_id = __get_loader_id(request->kb);
+    if (request->loader_id > PAD_LOADER_ID_DYNAMIC_BASE) {
+      type = static_cast<int>(launchpad::LoaderType::Dynamic);
+      request->cpc = __find_slot(type, request->loader_id);
+      if (request->cpc && !request->cpc->prepared)
+        request->cpc = nullptr;
+    } else {
+      request->loader_id = PAD_LOADER_ID_DIRECT;
+    }
+  } else if (menu_info->comp_type && menu_info->app_type &&
+             !strcmp(menu_info->comp_type, "widgetapp") &&
+             !strcmp(menu_info->app_type, "webapp")) {
+    request->loader_id = PAD_LOADER_ID_DIRECT;
+  } else {
+    request->loader_id = __get_loader_id(request->kb);
+    if (request->loader_id <= PAD_LOADER_ID_STATIC) {
+      request->cpc =
+          __find_available_slot(menu_info->hwacc, menu_info->app_type,
+                                menu_info->loader_name, &request->org_cpc);
+    } else {
+      type = static_cast<int>(launchpad::LoaderType::Dynamic);
+      request->cpc = __find_slot(type, request->loader_id);
+      if (request->cpc && !request->cpc->prepared)
+        request->cpc = nullptr;
+    }
+  }
+
+  _modify_bundle(request->kb, request->caller_pid, request->menu_info,
+                 request->cmd);
+  if (menu_info->appid == nullptr) {
+    _E("Unable to get appid from app info");
+    return -1;
+  }
+
+  PERF("Getting package information & modifying bundle done");
+  return 0;
+}
+
+static void __launch_request_complete(request_h request) {
+  _memory_monitor_reset_timer();
+  __request_send_result(request, request->pid);
+
+  if (request->pid > 0) {
+    _dbus_send_app_launch_signal(request->pid, request->menu_info->appid);
+    g_hash_table_insert(__pid_table, GINT_TO_POINTER(request->pid),
+                        strdup(request->menu_info->appid));
+    _log_print("[LAUNCH]", "pid(%7d) | appid(%s)", request->pid,
+               request->menu_info->appid);
+  }
+}
+
+static void __handle_direct_launch(request_h request) {
+  if (request->org_cpc &&
+      (!request->org_cpc->app_check || request->org_cpc->app_exists) &&
+      request->org_cpc->pid == CANDIDATE_NONE &&
+      !__sequencer_slot_exist(request->org_cpc)) {
+    if (request->org_cpc->timer > 0) {
+      g_source_remove(request->org_cpc->timer);
+      request->org_cpc->timer = 0;
+    }
+
+    __update_slot_state(request->org_cpc, launchpad::LoaderMethod::Request, true);
+    __set_timer(request->org_cpc);
+  }
+}
+
+static void __fork_processing(request_h request) {
+  if (bundle_get_type(request->kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
+    _debug_init();
+
+  _W("appid: %s", request->menu_info->appid);
+  request->pid = __launch_directly(request->menu_info->appid, request->app_path,
+                                   request->clifd, request->kb,
+                                   request->menu_info, nullptr);
+  if (request->pid == -1) {
+    _E("Failed to create a child process. appid(%s)",
+       request->menu_info->appid);
+  }
+
+  __request_send_result(request, request->pid);
+  _W("appid: %s, pid: %d", request->menu_info->appid, request->pid);
+  __handle_direct_launch(request);
+}
+
+static int __launch_request_do(request_h request) {
+  if (request->loader_id == PAD_LOADER_ID_DIRECT || request->cpc == nullptr) {
+    __fork_processing(request);
+    return 0;
+  }
+
+  _W("Launch %d type process. appid(%s)", request->cpc->type,
+     request->menu_info->appid);
+  request->pid = __send_launchpad_loader(request->cpc, request->pkt,
+                                         request->app_path, request->clifd);
+  return 0;
+}
+
+static int __launch_request_handler(request_h request) {
+  int ret;
+
+  traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "LAUNCHPAD:LAUNCH");
+  INIT_PERF(kb);
+  PERF("Packet processing start");
+
+  ret = __launch_request_prepare(request);
+  if (ret < 0) {
+    traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+    __request_send_result(request, ret);
+    return ret;
+  }
+
+  ret = __launch_request_do(request);
+  if (ret < 0)
+    request->pid = ret;
+
+  __launch_request_complete(request);
+  traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+  _D("[PAD_CMD_LAUNCH] appid: %s, result: %d", request->menu_info->appid,
+     request->pid);
+  return 0;
+}
+
+static request_handler __request_handlers[PAD_CMD_CONNECT + 1] = {};
+
+static bool __handle_launch_event(int fd, io_condition_e cond, void* data) {
+  request_t* request = nullptr;
+  int ret;
+
+  if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
+    _E("fd(%d), condition(%d)", fd, cond);
+    g_idle_add(__launchpad_recovery_cb, __launchpad_channel);
+    __launchpad_channel = nullptr;
+    return false;
+  }
+
+  ret = __request_create(fd, &request);
+  if (ret != 0)
+    return true;
+
+  _W("cmd(%d), caller(%d)", request->cmd, request->caller_pid);
+  if (request->caller_uid >= REGULAR_UID_MIN) {
+    if (__check_caller_by_pid(request->caller_pid) < 0) {
+      _E("Permission denied. pid(%d)", request->caller_pid);
+      __request_send_result(request, -EPERM);
+      __request_destroy(request);
+      return true;
+    }
+  }
+
+  if (request->cmd < 0 || request->cmd >= ARRAY_SIZE(__request_handlers) ||
+      __request_handlers[request->cmd] == nullptr) {
+    _E("Unknown command: %d", request->cmd);
+    __request_send_result(request, -EINVAL);
+    __request_destroy(request);
+    return true;
+  }
+
+  __request_handlers[request->cmd](request);
+  __request_destroy(request);
+  return true;
+}
+
+static void __destroy_slot(candidate_process_context_t* cpc) {
+  if (!cpc)
+    return;
+
+  if (cpc->hydra_channel)
+    _io_channel_destroy(cpc->hydra_channel);
+
+  if (cpc->channel)
+    _io_channel_destroy(cpc->channel);
+
+  if (cpc->loader_extra)
+    free(cpc->loader_extra);
+
+  if (cpc->loader_path)
+    free(cpc->loader_path);
+
+  if (cpc->loader_name)
+    free(cpc->loader_name);
+
+  free(cpc);
+}
+
+static candidate_process_context_t* __create_slot(slot_info_t* info) {
+  candidate_process_context_t* cpc;
+
+  cpc = static_cast<candidate_process_context_t*>(
+      calloc(1, sizeof(candidate_process_context_t)));
+  if (cpc == nullptr) {
+    _E("Out of memory");
+    return nullptr;
+  }
+
+  cpc->loader_name = strdup(info->loader_name);
+  if (cpc->loader_name == nullptr) {
+    _E("Failed to duplicate loader name(%s)", info->loader_name);
+    __destroy_slot(cpc);
+    return nullptr;
+  }
+
+  cpc->loader_path = strdup(info->loader_path);
+  if (cpc->loader_path == nullptr) {
+    _E("Failed to duplicate loader path(%s)", info->loader_path);
+    __destroy_slot(cpc);
+    return nullptr;
+  }
+
+  cpc->loader_extra =
+      info->loader_extra ? strdup(info->loader_extra) : strdup("");
+  if (cpc->loader_extra == nullptr) {
+    _E("Failed to duplicate loader extra(%s)", info->loader_extra);
+    __destroy_slot(cpc);
+    return nullptr;
+  }
+
+  cpc->type = info->type;
+  cpc->prepared = false;
+  cpc->pid = CANDIDATE_NONE;
+  cpc->hydra_pid = HYDRA_NONE;
+  cpc->caller_pid = info->caller_pid;
+  cpc->loader_id = info->loader_id;
+  cpc->send_fd = -1;
+  cpc->hydra_fd = -1;
+  cpc->last_exec_time = 0;
+  cpc->timer = 0;
+  cpc->detection_method = info->detection_method;
+  cpc->timeout_val = info->timeout_val;
+  cpc->cpu_total_time = 0;
+  cpc->cpu_idle_time = 0;
+  cpc->threshold = info->threshold_max;
+  cpc->threshold_max = info->threshold_max;
+  cpc->threshold_min = info->threshold_min;
+  cpc->on_boot = info->on_boot;
+  cpc->app_exists = info->app_exists;
+  cpc->touched = false;
+  cpc->cur_event = 0;
+  cpc->activation_method = info->activation_method;
+  cpc->deactivation_method = info->deactivation_method;
+  cpc->ttl = info->ttl;
+  cpc->live_timer = 0;
+  cpc->is_hydra = info->is_hydra;
+  cpc->app_check = info->app_check;
+  cpc->score = WIN_SCORE;
+  cpc->pss = 0;
+  cpc->cpu_check_count = 0;
+  cpc->on_boot_timeout = info->on_boot_timeout;
+  cpc->sched_priority = info->sched_priority;
+
+  if ((cpc->deactivation_method & static_cast<int>(launchpad::LoaderMethod::OutOfMemory)) && __is_low_memory())
+    cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
+  else
+    cpc->state = CANDIDATE_PROCESS_STATE_RUNNING;
+
+  _W("loader(%s), type(%d), state(%d)", cpc->loader_name, cpc->type,
+     cpc->state);
+  return cpc;
+}
+
+static candidate_process_context_t* __add_slot(slot_info_t* info) {
+  candidate_process_context_t* cpc;
+  int fd;
+  io_channel_h channel;
+  int hydra_fd;
+  io_channel_h hydra_channel;
+
+  if (info == nullptr)
+    return nullptr;
+
+  if (__find_slot(info->type, info->loader_id) != nullptr)
+    return nullptr;
+
+  cpc = __create_slot(info);
+  if (cpc == nullptr)
+    return nullptr;
+
+  fd = __listen_candidate_process(cpc->type, cpc->loader_id);
+  if (fd == -1) {
+    _E("[launchpad] Listening the socket to "
+       "the type %d candidate process failed.",
+       cpc->type);
+    __destroy_slot(cpc);
+    return nullptr;
+  }
+
+  channel = _io_channel_create(fd, IO_IN, __handle_loader_event, cpc);
+  if (!channel) {
+    close(fd);
+    __destroy_slot(cpc);
+    return nullptr;
+  }
+
+  cpc->channel = channel;
+
+  if (info->is_hydra) {
+    hydra_fd = __listen_hydra_process(cpc->type, cpc->loader_id);
+    if (hydra_fd == -1) {
+      _E("[launchpad] Listening the socket to "
+         "the type %d hydra process failed.",
+         cpc->type);
+      __destroy_slot(cpc);
+      return nullptr;
+    }
+
+    hydra_channel =
+        _io_channel_create(hydra_fd, IO_IN, __handle_hydra_event, cpc);
+    if (!hydra_channel) {
+      close(hydra_fd);
+      __destroy_slot(cpc);
+      return nullptr;
+    }
+
+    cpc->hydra_channel = hydra_channel;
+  }
+
+  candidate_slot_list = g_list_append(candidate_slot_list, cpc);
+
+  return cpc;
+}
+
+static int __remove_slot(int type, int loader_id) {
+  candidate_process_context_t* cpc;
+  GList* iter;
+
+  iter = candidate_slot_list;
+  while (iter) {
+    cpc = (candidate_process_context_t*)iter->data;
+    if (type == cpc->type && loader_id == cpc->loader_id) {
+      __dispose_candidate_process(cpc);
+      candidate_slot_list = g_list_delete_link(candidate_slot_list, iter);
+      __destroy_slot(cpc);
+      return 0;
+    }
+
+    iter = g_list_next(iter);
+  }
+
+  return -1;
+}
+
+static int __init_launchpad_fd(int argc, char** argv) {
+  int fd;
+
+  fd = __launchpad_pre_init(argc, argv);
+  if (fd < 0) {
+    _E("launchpad pre init failed");
+    return -1;
+  }
+
+  auto cond = IO_IN | IO_PRI | IO_HUP | IO_ERR | IO_NVAL;
+  __launchpad_channel = _io_channel_create(
+      fd, static_cast<io_condition_e>(cond), __handle_launch_event, nullptr);
+  if (!__launchpad_channel) {
+    close(fd);
+    return -1;
+  }
+
+  return 0;
+}
+
+static bool __on_directory_create(const char* event_name,
+                                  uint32_t mask,
+                                  void* user_data) {
+  if (!event_name) {
+    _E("Invalid parameter");
+    return true;
+  }
+
+  if (!strcmp(event_name, LOADERS_PATH)) {
+    _W("%s is created", LOADERS_PATH);
+    __init_app_defined_loader_monitor();
+    return false;
+  }
+
+  return true;
+}
+
+static bool __on_file_change(const char* event_name,
+                             uint32_t mask,
+                             void* user_data) {
+  char buf[PATH_MAX];
+  char* ext;
+  launchpad::LoaderInfoPtr info;
+  candidate_process_context_t* cpc;
+
+  if (!event_name) {
+    _E("Invalid parameter");
+    return true;
+  }
+
+  ext = const_cast<char*>(strrchr(event_name, '.'));
+  if (ext == nullptr || strcmp(ext, ".loader") != 0)
+    return true;
+
+  _W("event_name(%s), mask(%u)", event_name, mask);
+  if (mask & IN_CREATE) {
+    app_defined_loader_info_manager->LoadFile(event_name);
+  } else if (mask & IN_DELETE) {
+    snprintf(buf, ext - event_name + 1, "%s", event_name);
+
+    info = app_defined_loader_info_manager->FindLoaderInfo(buf);
+    cpc = __find_slot_from_loader_name(info->GetName().c_str());
+    __remove_slot(cpc->type, cpc->loader_id);
+    app_defined_loader_info_manager->Unload(buf);
+  }
+
+  return true;
+}
+
+static void __init_app_defined_loader_monitor(void) {
+  int ret;
+
+  ret = access(APP_DEFINED_LOADER_INFO_PATH, F_OK);
+  if (ret < 0) {
+    _W("Failed to access %s", APP_DEFINED_LOADER_INFO_PATH);
+    ret = _inotify_add_watch(OPT_SHARE_PATH, IN_CREATE, __on_directory_create,
+                             nullptr);
+    if (ret != 0)
+      _E("Failed to add inotify watch %s", OPT_SHARE_PATH);
+
+    return;
+  }
+
+  ret = _inotify_add_watch(APP_DEFINED_LOADER_INFO_PATH, IN_CREATE | IN_DELETE,
+                           __on_file_change, nullptr);
+
+  if (ret < 0) {
+    _E("Failed to add inotify watch %s", APP_DEFINED_LOADER_INFO_PATH);
+  }
+
+  return;
+}
+
+static int __init_label_monitor_fd(void) {
+  int r;
+  int fd = -1;
+
+  auto err_handler = [&]() -> int {
+    if (fd > 0)
+      close(fd);
+
+    if (label_monitor) {
+      security_manager_app_labels_monitor_finish(label_monitor);
+      label_monitor = nullptr;
+    }
+    return -1;
+  };
+
+  r = security_manager_app_labels_monitor_init(&label_monitor);
+  if (r != SECURITY_MANAGER_SUCCESS)
+    return -1;
+
+  r = security_manager_app_labels_monitor_process(label_monitor);
+  if (r != SECURITY_MANAGER_SUCCESS)
+    return err_handler();
+
+  security_manager_app_labels_monitor_get_fd(label_monitor, &fd);
+  if (fd < 0) {
+    _E("failed to get fd");
+    return err_handler();
+  }
+
+  auto cond = IO_IN | IO_PRI | IO_HUP | IO_ERR | IO_NVAL;
+  __label_monitor_channel = _io_channel_create(
+      fd, static_cast<io_condition_e>(cond), __handle_label_monitor, nullptr);
+  if (!__label_monitor_channel)
+    return err_handler();
+
+  return 0;
+
+
+}
+
+static int __verify_loader_caps(const char* loader) {
+  cap_t cap_d;
+  cap_flag_value_t eff_state;
+  cap_flag_value_t inh_state;
+  cap_value_t values[] = {CAP_SETGID, CAP_MAC_ADMIN};
+  int r;
+  int i;
+  int size = ARRAY_SIZE(values);
+
+  /* If Dytransition feature is enabled, CAP_MAC_ADMIN is unnecessary */
+  if (label_monitor)
+    size--;
+
+  cap_d = cap_get_file(loader);
+  if (!cap_d) {
+    _E("Failed to get cap from file(%s)", loader);
+    return -1;
+  }
+
+  for (i = 0; i < size; i++) {
+    r = cap_get_flag(cap_d, values[i], CAP_INHERITABLE, &inh_state);
+    if (r != 0) {
+      _E("Failed to get cap inh - errno(%d)", errno);
+      cap_free(cap_d);
+      return -1;
+    }
+
+    r = cap_get_flag(cap_d, values[i], CAP_EFFECTIVE, &eff_state);
+    if (r != 0) {
+      _E("Failed to get cap eff - errno(%d)", errno);
+      cap_free(cap_d);
+      return -1;
+    }
+
+    if ((inh_state != CAP_SET) || (eff_state != CAP_SET)) {
+      _E("The %s doesn't have %d cap", loader, values[i]);
+      cap_free(cap_d);
+      return -1;
+    }
+  }
+  cap_free(cap_d);
+
+  return 0;
+}
+
+static void __get_app_type_string(const launchpad::LoaderInfoPtr& info,
+    char buf[], int size) {
+  char* ptr = buf;
+
+  for (auto& app_type : info->GetAppTypes()) {
+    if (size < app_type.size() + 1)
+      return;
+
+    strncpy(ptr, app_type.c_str(), size);
+    ptr += app_type.size();
+    size -= app_type.size();
+    (*ptr++) = ' ';
+    size--;
+  }
+}
+
+static void __add_slot_from_info(const launchpad::LoaderInfoPtr& info) {
+  candidate_process_context_t* cpc;
+  bundle_raw* extra = nullptr;
+  int len;
+  char buf[2048] = {
+      0,
+  };
+
+  // TODO(changyu.choi): slot_info will be implemented to refer to loader_info
+  slot_info_t slot_info = {
+    .type = LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset,
+    .loader_name = info->GetName().c_str(),
+    .loader_path = info->GetExe().c_str(),
+    .threshold_max = info->GetCpuThresholdMax(),
+    .threshold_min = info->GetCpuThresholdMin(),
+    .app_exists = info->IsAppExists(),
+    .is_hydra = info->IsHydraEnabled(),
+    .app_check = info->IsNeededAppCheck(),
+    .on_boot_timeout = info->GetOnbootTimeout(),
+    .sched_priority = info->GetSchedPriority()
+  };
+
+  if (info->GetExe() == "null") {
+    slot_info.loader_id = PAD_LOADER_ID_DIRECT;
+
+    cpc = __add_slot(&slot_info);
+    if (cpc == nullptr)
+      return;
+
+    info->SetType(static_cast<launchpad::LoaderType>(
+        static_cast<int>(launchpad::LoaderType::User) + user_slot_offset));
+    user_slot_offset++;
+    return;
+  } else if (access(info->GetExe().c_str(), F_OK | X_OK) == 0) {
+    if (__verify_loader_caps(info->GetExe().c_str()) < 0)
+      return;
+
+    bundle_encode(info->GetExtra().GetHandle(), &extra, &len);
+
+    slot_info.loader_id = PAD_LOADER_ID_STATIC;
+    slot_info.loader_extra = (const char*)extra;
+    slot_info.detection_method = static_cast<int>(info->GetDetectionMethod());
+    slot_info.activation_method = static_cast<int>(info->GetActivationMethod());
+    slot_info.deactivation_method = static_cast<int>(info->GetDeactivationMethod());
+    slot_info.ttl = info->GetTtl();
+    slot_info.timeout_val = info->GetTimeoutVal();
+    slot_info.on_boot = info->IsOnBoot();
+
+    cpc = __add_slot(&slot_info);
+    bundle_free_encoded_rawdata(&extra);
+    if (cpc == nullptr)
+      return;
+
+    info->SetType(static_cast<launchpad::LoaderType>(
+        static_cast<int>(launchpad::LoaderType::User) + user_slot_offset));
+    user_slot_offset++;
+    __get_app_type_string(info, buf, sizeof(buf));
+    _I("candidate slot. app-type(%s) loader-type(%d)", buf,
+       static_cast<int>(info->GetType()));
+    _print_hwc_log("candidate slot. app-type(%s) loader-type(%d)", buf,
+                   static_cast<int>(info->GetType()));
+  }
+}
+
+static int __add_default_slots(void) {
+  loader_info_manager =
+      std::make_unique<launchpad::LoaderInfoManager>(LOADER_INFO_PATH);
+
+  loader_info_manager->Load();
+  user_slot_offset = 0;
+  for (auto& info : loader_info_manager->GetLoaderInfoList()) {
+    __add_slot_from_info(info);
+  }
+  __add_idle_checker(0, candidate_slot_list);
+
+  return 0;
+}
+
+static void __add_app_defined_loaders(void) {
+  app_defined_loader_info_manager =
+      std::make_unique<launchpad::LoaderInfoManager>(
+          APP_DEFINED_LOADER_INFO_PATH);
+
+  app_defined_loader_info_manager->Load();
+}
+
+static bool __is_low_memory(void) {
+  if (_memory_monitor_is_low_memory())
+    return true;
+
+  if (__memory_status_low >= MEMORY_STATUS_LOW)
+    return true;
+
+  return false;
+}
+
+static void __hw_acceleration_changed_cb(keynode_t* key, void* data) {
+  __sys_hwacc = vconf_keynode_get_int(key);
+  _D("sys hwacc: %d", __sys_hwacc);
+}
+
+static void __update_lang(keynode_t* node, void* user_data) {
+  char* lang;
+
+  lang = vconf_keynode_get_str(node);
+  if (!lang) {
+    _E("Failed to get language");
+    return;
+  }
+
+  setenv("LANG", lang, 1);
+}
+
+static void __region_format_changed_cb(keynode_t* node, void* data) {
+  char* region;
+
+  region = vconf_keynode_get_str(node);
+  if (!region) {
+    _E("Failed to get value");
+    return;
+  }
+
+  setenv("LC_CTYPE", region, 1);
+}
+
+static void __memory_status_low_changed_cb(keynode_t* node, void* data) {
+  candidate_process_context_t* cpc;
+  GList* iter;
+
+  __memory_status_low = vconf_keynode_get_int(node);
+  if (__memory_status_low >= MEMORY_STATUS_LOW) {
+    _W("Low memory");
+    iter = candidate_slot_list;
+    while (iter) {
+      cpc = (candidate_process_context_t*)iter->data;
+      __update_slot_state(cpc, launchpad::LoaderMethod::OutOfMemory, false);
+      iter = g_list_next(iter);
+    }
+  }
+}
+
+static void __memory_status_normal_changed_cb(keynode_t* node, void* data) {
+  candidate_process_context_t* cpc;
+  GList* iter;
+
+  __memory_status_normal = vconf_keynode_get_int(node);
+  if (__memory_status_normal == MEMORY_STATUS_NORMAL) {
+    _W("Normal");
+    iter = candidate_slot_list;
+    while (iter) {
+      cpc = (candidate_process_context_t*)iter->data;
+      __update_slot_state(cpc, launchpad::LoaderMethod::AvailableMemory, true);
+      iter = g_list_next(iter);
+    }
+  }
+}
+
+static void __unregister_vconf_events(void) {
+  const char* key;
+  config_type_e type;
+
+  type = CONFIG_TYPE_MEMORY_STATUS_NORMAL_KEY;
+  key = _config_get_string_value(type);
+  vconf_ignore_key_changed(key, __memory_status_normal_changed_cb);
+
+  type = CONFIG_TYPE_MEMORY_STATUS_LOW_KEY;
+  key = _config_get_string_value(type);
+  vconf_ignore_key_changed(key, __memory_status_low_changed_cb);
+
+  vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __region_format_changed_cb);
+  vconf_ignore_key_changed(VCONFKEY_LANGSET, __update_lang);
+  vconf_ignore_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
+                           __hw_acceleration_changed_cb);
+}
+
+static int __register_vconf_events(void) {
+  int r;
+  char* lang;
+  char* region;
+  const char* key;
+  config_type_e type;
+
+  r = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &__sys_hwacc);
+  if (r != VCONF_OK)
+    _E("Failed to get vconf hw acceleration. err = %d", r);
+
+  r = vconf_notify_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
+                               __hw_acceleration_changed_cb, nullptr);
+  if (r != VCONF_OK) {
+    _E("Failed to register callback for hw acceleration. err = %d", r);
+  }
+
+  lang = vconf_get_str(VCONFKEY_LANGSET);
+  if (lang) {
+    setenv("LANG", lang, 1);
+    free(lang);
+  }
+
+  r = vconf_notify_key_changed(VCONFKEY_LANGSET, __update_lang, nullptr);
+  if (r != VCONF_OK)
+    _E("Failed to register callback for langset. err = %d", r);
+
+  region = vconf_get_str(VCONFKEY_REGIONFORMAT);
+  if (region) {
+    setenv("LC_CTYPE", region, 1);
+    free(region);
+  }
+
+  r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT,
+                               __region_format_changed_cb, nullptr);
+  if (r != VCONF_OK)
+    _E("Failed to register callback for regionformat. err = %d", r);
+
+  type = CONFIG_TYPE_MEMORY_STATUS_LOW_KEY;
+  key = _config_get_string_value(type);
+  type = CONFIG_TYPE_MEMORY_STATUS_LOW_VALUE;
+  MEMORY_STATUS_LOW = _config_get_int_value(type);
+
+  r = vconf_get_int(key, &__memory_status_low);
+  if (r != VCONF_OK)
+    _E("Failed to get vconf low memory. err = %d", r);
+
+  r = vconf_notify_key_changed(key, __memory_status_low_changed_cb, nullptr);
+  if (r != 0)
+    _E("Failed to register callback for low memory. err = %d", r);
+
+  type = CONFIG_TYPE_MEMORY_STATUS_NORMAL_KEY;
+  key = _config_get_string_value(type);
+  type = CONFIG_TYPE_MEMORY_STATUS_NORMAL_VALUE;
+  MEMORY_STATUS_NORMAL = _config_get_int_value(type);
+
+  r = vconf_get_int(key, &__memory_status_normal);
+  if (r != VCONF_OK)
+    _E("Failed to get vconf normal memory. err = %d", r);
+
+  r = vconf_notify_key_changed(key, __memory_status_normal_changed_cb, nullptr);
+  if (r != 0)
+    _E("Failed to register callback for normal memory. err = %d", r);
+
+  return 0;
+}
+
+static bool __handle_logger(int fd, io_condition_e cond, void* data) {
+  app_pkt_t* pkt;
+  struct ucred cr;
+  int clifd = -1;
+
+  if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
+    _E("fd(%d), io_condition(%d)", fd, cond);
+    g_idle_add(__logger_recovery_cb, __logger_channel);
+    __logger_channel = nullptr;
+    return false;
+  }
+
+  pkt = _accept_recv_pkt_raw(fd, &clifd, &cr);
+  if (!pkt) {
+    _E("Failed to receive the packet");
+    return true;
+  }
+
+  if (getuid() != cr.uid) {
+    _E("Invalid caller");
+    goto end;
+  }
+
+  if (pkt->len <= 0) {
+    _E("Invalid message");
+    goto end;
+  }
+
+  _E("[%d] %s", cr.pid, (const char*)pkt->data);
+  _log_print("[ERROR]", "pid(%7d) | message(%s)", cr.pid,
+             (const char*)pkt->data);
+end:
+  if (clifd != -1)
+    close(clifd);
+
+  free(pkt);
+
+  return true;
+}
+
+static int __init_logger_fd(void) {
+  int fd;
+
+  fd = _create_server_sock(LAUNCHPAD_LOGGER_SOCK);
+  if (fd < 0) {
+    _E("Failed to create logger socker");
+    return -1;
+  }
+
+  auto cond = IO_IN | IO_PRI | IO_ERR | IO_HUP | IO_NVAL;
+  __logger_channel = _io_channel_create(fd, static_cast<io_condition_e>(cond),
+                                        __handle_logger, nullptr);
+  if (!__logger_channel) {
+    close(fd);
+    return -1;
+  }
+
+  return 0;
+}
+
+static int __memory_monitor_cb(bool low_memory, void* user_data) {
+  candidate_process_context_t* cpc;
+
+  cpc = __get_running_slot(false);
+  if (!cpc && low_memory)
+    return -1;
+
+  if (low_memory) {
+    _W("Low memory");
+    __update_slots_pss();
+
+    candidate_slot_list = g_list_sort(candidate_slot_list, __compare_slot);
+    __pause_all_running_slots(false);
+  } else {
+    __resume_all_slots();
+  }
+
+  return 0;
+}
+
+static gboolean __logger_recovery_cb(gpointer data) {
+  auto channel = static_cast<io_channel_h>(data);
+  int ret;
+
+  _io_channel_destroy(channel);
+
+  ret = __init_logger_fd();
+  if (ret < 0) {
+    _E("Failed to recover logger socket");
+    return G_SOURCE_REMOVE;
+  }
+
+  _E("[__RECOVERY__] Logger socket");
+
+  return G_SOURCE_REMOVE;
+}
+
+static gboolean __launchpad_recovery_cb(gpointer data) {
+  auto channel = static_cast<io_channel_h>(data);
+  int ret;
+
+  _io_channel_destroy(channel);
+
+  ret = __init_launchpad_fd(0, nullptr);
+  if (ret < 0) {
+    _E("Failed to recover launchpad socket");
+    abort();
+    return G_SOURCE_REMOVE;
+  }
+
+  _E("[__RECOVERY__] Launchpad socket");
+
+  return G_SOURCE_REMOVE;
+}
+
+static int __before_loop(int argc, char** argv) {
+  __request_handlers[PAD_CMD_VISIBILITY] = __visibility_request_handler;
+  __request_handlers[PAD_CMD_ADD_LOADER] = __add_loader_request_handler;
+  __request_handlers[PAD_CMD_REMOVE_LOADER] = __remove_loader_request_handler;
+  __request_handlers[PAD_CMD_MAKE_DEFAULT_SLOTS] =
+      __make_default_slots_request_handler;
+  __request_handlers[PAD_CMD_PREPARE_APP_DEFINED_LOADER] =
+      __prepare_app_defined_loader_request_handler;
+  __request_handlers[PAD_CMD_DEMAND] = __demand_request_handler;
+  __request_handlers[PAD_CMD_PING] = __ping_request_handler;
+  __request_handlers[PAD_CMD_UPDATE_APP_TYPE] =
+      __update_app_type_request_handler;
+  __request_handlers[PAD_CMD_CONNECT] = __connect_request_handler;
+  __request_handlers[PAD_CMD_LAUNCH] = __launch_request_handler;
+
+  _print_hwc_log("%s(%d): START", __FUNCTION__, __LINE__);
+  int ret = __sequencer_init();
+  if (ret < 0) {
+    _E("Failed to initialize sequencer");
+    return -1;
+  }
+
+  ret = _signal_init();
+  if (ret < 0) {
+    _E("Failed to initialize signal");
+    return -1;
+  }
+
+  _signal_set_sigchld_cb(__handle_sigchild, nullptr);
+
+  ret = __init_launchpad_fd(argc, argv);
+  if (ret != 0) {
+    _E("__init_launchpad_fd() failed");
+    return -1;
+  }
+
+  ret = __init_logger_fd();
+  if (ret != 0) {
+    _E("__init_logger_fd() failed");
+    return -1;
+  }
+
+  ret = __init_label_monitor_fd();
+  if (ret != 0)
+    _W("Failed to initialize label monitor");
+
+  ret = _config_init();
+  if (ret != 0)
+    _W("Failed to initialize config");
+
+  ret = _dbus_init();
+  if (ret != 0)
+    _W("Failed to initialize dbus");
+
+  _inotify_init();
+
+  MAX_CPU_CHECK_COUNT =
+      _config_get_int_value(CONFIG_TYPE_CPU_CHECKER_MAX_COUNT);
+  __add_default_slots();
+
+  launchpad::LauncherInfoInflator inflator;
+  launcher_info_list = inflator.Inflate(LAUNCHER_INFO_PATH);
+
+  __add_app_defined_loaders();
+
+  ret = _send_cmd_to_amd(LAUNCHPAD_LAUNCH_SIGNAL);
+  if (ret < 0)
+    _W("Failed to send cmd(%d) to amd", LAUNCHPAD_LAUNCH_SIGNAL);
+
+  __pid_table =
+      g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr, free);
+  if (!__pid_table) {
+    _E("Failed to create pid table");
+    return -1;
+  }
+
+  ret = _worker_create("cleaner+", &__cleaner);
+  if (ret < 0)
+    return ret;
+
+  __register_vconf_events();
+  __init_app_defined_loader_monitor();
+  _memory_monitor_init();
+  _memory_monitor_set_event_cb(__memory_monitor_cb, nullptr);
+  _log_init();
+  _print_hwc_log("%s(%d): END", __FUNCTION__, __LINE__);
+
+  return 0;
+}
+
+static void __after_loop(void) {
+  _log_fini();
+  _memory_monitor_fini();
+  __unregister_vconf_events();
+  _worker_destroy(__cleaner);
+  if (__pid_table)
+    g_hash_table_destroy(__pid_table);
+
+  if (_send_cmd_to_amd(LAUNCHPAD_DEAD_SIGNAL) < 0)
+    _W("Failed to send cmd(%d) to amd", LAUNCHPAD_DEAD_SIGNAL);
+
+  _debug_fini();
+  launcher_info_list.clear();
+  _dbus_fini();
+  _config_fini();
+  _inotify_fini();
+  app_defined_loader_info_manager->Dispose();
+
+  if (__label_monitor_channel)
+    _io_channel_destroy(__label_monitor_channel);
+
+  if (label_monitor)
+    security_manager_app_labels_monitor_finish(label_monitor);
+
+  if (__logger_channel)
+    _io_channel_destroy(__logger_channel);
+
+  if (__launchpad_channel)
+    _io_channel_destroy(__launchpad_channel);
+
+  _signal_fini();
+
+  __sequencer_fini();
+}
+
+int main(int argc, char** argv) {
+  GMainLoop* mainloop = nullptr;
+
+  _print_hwc_log("%s(%d): START", __FUNCTION__, __LINE__);
+  prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
+
+  mainloop = g_main_loop_new(nullptr, FALSE);
+  if (!mainloop) {
+    _E("Failed to create glib main loop");
+    return -1;
+  }
+
+  _print_hwc_log("%s(%d): __before_loop()", __FUNCTION__, __LINE__);
+  if (__before_loop(argc, argv) != 0) {
+    _E("process-pool Initialization failed!");
+    return -1;
+  }
+
+#ifdef TIZEN_FEATURE_PRIORITY_CHANGE
+  _set_priority(-12);
+#endif
+  _print_hwc_log("%s(%d): g_main_loop_run()", __FUNCTION__, __LINE__);
+  g_main_loop_run(mainloop);
+
+  __after_loop();
+
+  return -1;
+}
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#define _GNU_SOURCE
 #include <stdio.h>
 #include <malloc.h>
 #include <stdlib.h>
diff --git a/src/launchpad-process-pool/src/launchpad_dbus.c b/src/launchpad-process-pool/src/launchpad_dbus.c
deleted file mode 100644 (file)
index 0b3f298..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <gio/gio.h>
-#include <glib.h>
-
-#include "launchpad_dbus.h"
-#include "log_private.h"
-
-#define AUL_DBUS_PATH                   "/aul/dbus_handler"
-#define AUL_DBUS_SIGNAL_INTERFACE       "org.tizen.aul.signal"
-#define AUL_DBUS_APPDEAD_SIGNAL         "app_dead"
-#define AUL_DBUS_APPLAUNCH_SIGNAL       "app_launch"
-
-#define PENDING_ITEM_INTERVAL           1000
-
-#define GET_CONNECTION_ERROR_THRESHOLD  10
-#define GET_CONNECTION_ERROR_MODULO     1000
-typedef enum {
-       APP_SIGNAL_DEAD,
-       APP_SIGNAL_LAUNCH,
-} app_signal_e;
-
-typedef struct pending_item_s {
-       char *app_id;
-       int pid;
-       app_signal_e app_signal;
-} pending_item_t;
-
-static GList *__pending_items;
-static guint __timer;
-static GDBusConnection *__conn;
-
-static void __set_pending_item_timer(void);
-
-static void __destroy_pending_item(gpointer data)
-{
-       pending_item_t *item = data;
-
-       free(item->app_id);
-       free(item);
-}
-
-static pending_item_t *__create_pending_item(const char *app_id,
-               int pid, app_signal_e app_signal)
-{
-       pending_item_t *item;
-
-       item = calloc(1, sizeof(pending_item_t));
-       if (!item) {
-               _E("Out of memory");
-               return NULL;
-       }
-
-       if (app_id) {
-               item->app_id = strdup(app_id);
-               if (!item->app_id) {
-                       _E("Failed to duplicate app ID(%s)", app_id);
-                       __destroy_pending_item(item);
-                       return NULL;
-               }
-       }
-
-       item->pid = pid;
-       item->app_signal = app_signal;
-
-       return item;
-}
-
-static GDBusConnection *__get_connection(void)
-{
-       GError *error = NULL;
-       static unsigned int error_count = 0;
-
-       if (__conn)
-               return __conn;
-
-       __conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
-       if (!__conn) {
-               error_count++;
-               if (error_count < GET_CONNECTION_ERROR_THRESHOLD ||
-                               error_count % GET_CONNECTION_ERROR_MODULO == 0) {
-                       _E("g_bus_get_sync() is failed. error(%s)",
-                               error ? error->message : "Unknown");
-               }
-
-               g_clear_error(&error);
-               return NULL;
-       }
-
-       return __conn;
-}
-
-static int __emit_signal(const char *path,
-               const char *interface,
-               const char *signal,
-               GVariant *param)
-{
-       GDBusConnection *conn;
-       GError *error = NULL;
-       gboolean ret;
-
-       conn = __get_connection();
-       if (!conn)
-               return -1;
-
-       ret = g_dbus_connection_emit_signal(conn,
-                       NULL,
-                       path,
-                       interface,
-                       signal,
-                       param,
-                       &error);
-       if (ret != TRUE) {
-               _E("g_dbus_connection_emit_signal() is failed. error(%s)",
-                               error ? error->message : "Unknown");
-               g_clear_error(&error);
-               return -1;
-       }
-
-       ret = g_dbus_connection_flush_sync(conn, NULL, &error);
-       if (ret != TRUE) {
-               _E("g_dbus_connection_flush_sync() is failed. error(%s)",
-                               error ? error->message : "Unknown");
-               g_clear_error(&error);
-               return -1;
-       }
-
-       return 0;
-}
-
-static int __emit_app_launch_signal(int pid, const char *app_id)
-{
-       int ret;
-
-       ret = __emit_signal(AUL_DBUS_PATH,
-                       AUL_DBUS_SIGNAL_INTERFACE,
-                       AUL_DBUS_APPLAUNCH_SIGNAL,
-                       g_variant_new("(us)", pid, app_id));
-       if (ret < 0)
-               return ret;
-
-       _D("App launch. pid(%d), app_id(%s)", pid, app_id);
-
-       return 0;
-}
-
-static int __emit_app_dead_signal(int pid)
-{
-       int ret;
-
-       ret = __emit_signal(AUL_DBUS_PATH,
-                       AUL_DBUS_SIGNAL_INTERFACE,
-                       AUL_DBUS_APPDEAD_SIGNAL,
-                       g_variant_new("(u)", pid));
-       if (ret < 0)
-               return ret;
-
-       _D("App dead. pid(%d)", pid);
-
-       return 0;
-}
-
-static gboolean __flush_pending_item(gpointer data)
-{
-       pending_item_t *item;
-       GList *iter;
-       int ret;
-
-       if (!__pending_items) {
-               __timer = 0;
-               return G_SOURCE_REMOVE;
-       }
-
-       iter = __pending_items;
-       while (iter) {
-               item = (pending_item_t *)iter->data;
-               if (item->app_signal == APP_SIGNAL_DEAD)
-                       ret = __emit_app_dead_signal(item->pid);
-               else
-                       ret = __emit_app_launch_signal(item->pid, item->app_id);
-
-               if (ret < 0)
-                       return G_SOURCE_CONTINUE;
-
-               iter = g_list_next(iter);
-               __pending_items = g_list_remove(__pending_items, item);
-               __destroy_pending_item(item);
-       }
-
-       __timer = 0;
-       return G_SOURCE_REMOVE;
-}
-
-static void __set_pending_item_timer(void)
-{
-       if (__timer)
-               return;
-
-       __timer = g_timeout_add(PENDING_ITEM_INTERVAL,
-                       __flush_pending_item, NULL);
-}
-
-static void __unset_pending_item_timer(void)
-{
-       if (!__timer)
-               return;
-
-       g_source_remove(__timer);
-       __timer = 0;
-}
-
-int _dbus_send_app_launch_signal(int pid, const char *app_id)
-{
-       pending_item_t *item;
-       int ret;
-
-       if (pid <= 1 || !app_id) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       ret = __emit_app_launch_signal(pid, app_id);
-       if (ret < 0) {
-               item = __create_pending_item(app_id, pid, APP_SIGNAL_LAUNCH);
-               if (!item)
-                       return -ENOMEM;
-
-               _W("Pend app launch signal. pid(%d), app_id(%s)", pid, app_id);
-               __pending_items = g_list_append(__pending_items, item);
-               __set_pending_item_timer();
-       }
-
-       return 0;
-}
-
-int _dbus_send_app_dead_signal(int pid)
-{
-       pending_item_t *item;
-       int ret;
-
-       if (pid <= 1) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       ret = __emit_app_dead_signal(pid);
-       if (ret < 0) {
-               item = __create_pending_item(NULL, pid, APP_SIGNAL_DEAD);
-               if (!item)
-                       return -ENOMEM;
-
-               _W("Pend app dead signal. pid(%d)", pid);
-               __pending_items = g_list_append(__pending_items, item);
-               __set_pending_item_timer();
-       }
-
-       return 0;
-}
-
-int _dbus_init(void)
-{
-       GDBusConnection *conn;
-
-       _D("DBUS_INIT");
-       conn = __get_connection();
-       if (!conn)
-               return -1;
-
-       return 0;
-}
-
-void _dbus_fini(void)
-{
-       _D("DBUS_FINI");
-       if (__pending_items)
-               g_list_free_full(__pending_items, __destroy_pending_item);
-
-       __unset_pending_item_timer();
-
-       if (__conn)
-               g_object_unref(__conn);
-}
diff --git a/src/launchpad-process-pool/src/launchpad_dbus.cc b/src/launchpad-process-pool/src/launchpad_dbus.cc
new file mode 100644 (file)
index 0000000..7beff3d
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gio/gio.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "launchpad_dbus.h"
+#include "log_private.h"
+
+#define AUL_DBUS_PATH "/aul/dbus_handler"
+#define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal"
+#define AUL_DBUS_APPDEAD_SIGNAL "app_dead"
+#define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch"
+
+#define PENDING_ITEM_INTERVAL 1000
+
+#define GET_CONNECTION_ERROR_THRESHOLD 10
+#define GET_CONNECTION_ERROR_MODULO 1000
+typedef enum {
+  APP_SIGNAL_DEAD,
+  APP_SIGNAL_LAUNCH,
+} app_signal_e;
+
+typedef struct pending_item_s {
+  char* app_id;
+  int pid;
+  app_signal_e app_signal;
+} pending_item_t;
+
+static GList* __pending_items;
+static guint __timer;
+static GDBusConnection* __conn;
+
+static void __set_pending_item_timer(void);
+
+static void __destroy_pending_item(gpointer data) {
+  auto* item = static_cast<pending_item_t*>(data);
+
+  free(item->app_id);
+  free(item);
+}
+
+static pending_item_t* __create_pending_item(const char* app_id,
+                                             int pid,
+                                             app_signal_e app_signal) {
+  pending_item_t* item;
+
+  item = static_cast<pending_item_t*>(calloc(1, sizeof(pending_item_t)));
+  if (!item) {
+    _E("Out of memory");
+    return nullptr;
+  }
+
+  if (app_id) {
+    item->app_id = strdup(app_id);
+    if (!item->app_id) {
+      _E("Failed to duplicate app ID(%s)", app_id);
+      __destroy_pending_item(item);
+      return nullptr;
+    }
+  }
+
+  item->pid = pid;
+  item->app_signal = app_signal;
+
+  return item;
+}
+
+static GDBusConnection* __get_connection(void) {
+  GError* error = nullptr;
+  static unsigned int error_count = 0;
+
+  if (__conn)
+    return __conn;
+
+  __conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
+  if (!__conn) {
+    error_count++;
+    if (error_count < GET_CONNECTION_ERROR_THRESHOLD ||
+        error_count % GET_CONNECTION_ERROR_MODULO == 0) {
+      _E("g_bus_get_sync() is failed. error(%s)",
+         error ? error->message : "Unknown");
+    }
+
+    g_clear_error(&error);
+    return nullptr;
+  }
+
+  return __conn;
+}
+
+static int __emit_signal(const char* path,
+                         const char* interface,
+                         const char* signal,
+                         GVariant* param) {
+  GDBusConnection* conn;
+  GError* error = nullptr;
+  gboolean ret;
+
+  conn = __get_connection();
+  if (!conn)
+    return -1;
+
+  ret = g_dbus_connection_emit_signal(conn, nullptr, path, interface, signal,
+                                      param, &error);
+  if (ret != TRUE) {
+    _E("g_dbus_connection_emit_signal() is failed. error(%s)",
+       error ? error->message : "Unknown");
+    g_clear_error(&error);
+    return -1;
+  }
+
+  ret = g_dbus_connection_flush_sync(conn, nullptr, &error);
+  if (ret != TRUE) {
+    _E("g_dbus_connection_flush_sync() is failed. error(%s)",
+       error ? error->message : "Unknown");
+    g_clear_error(&error);
+    return -1;
+  }
+
+  return 0;
+}
+
+static int __emit_app_launch_signal(int pid, const char* app_id) {
+  int ret;
+
+  ret = __emit_signal(AUL_DBUS_PATH, AUL_DBUS_SIGNAL_INTERFACE,
+                      AUL_DBUS_APPLAUNCH_SIGNAL,
+                      g_variant_new("(us)", pid, app_id));
+  if (ret < 0)
+    return ret;
+
+  _D("App launch. pid(%d), app_id(%s)", pid, app_id);
+
+  return 0;
+}
+
+static int __emit_app_dead_signal(int pid) {
+  int ret;
+
+  ret = __emit_signal(AUL_DBUS_PATH, AUL_DBUS_SIGNAL_INTERFACE,
+                      AUL_DBUS_APPDEAD_SIGNAL, g_variant_new("(u)", pid));
+  if (ret < 0)
+    return ret;
+
+  _D("App dead. pid(%d)", pid);
+
+  return 0;
+}
+
+static gboolean __flush_pending_item(gpointer data) {
+  pending_item_t* item;
+  GList* iter;
+  int ret;
+
+  if (!__pending_items) {
+    __timer = 0;
+    return G_SOURCE_REMOVE;
+  }
+
+  iter = __pending_items;
+  while (iter) {
+    item = (pending_item_t*)iter->data;
+    if (item->app_signal == APP_SIGNAL_DEAD)
+      ret = __emit_app_dead_signal(item->pid);
+    else
+      ret = __emit_app_launch_signal(item->pid, item->app_id);
+
+    if (ret < 0)
+      return G_SOURCE_CONTINUE;
+
+    iter = g_list_next(iter);
+    __pending_items = g_list_remove(__pending_items, item);
+    __destroy_pending_item(item);
+  }
+
+  __timer = 0;
+  return G_SOURCE_REMOVE;
+}
+
+static void __set_pending_item_timer(void) {
+  if (__timer)
+    return;
+
+  __timer = g_timeout_add(PENDING_ITEM_INTERVAL, __flush_pending_item, nullptr);
+}
+
+static void __unset_pending_item_timer(void) {
+  if (!__timer)
+    return;
+
+  g_source_remove(__timer);
+  __timer = 0;
+}
+
+int _dbus_send_app_launch_signal(int pid, const char* app_id) {
+  pending_item_t* item;
+  int ret;
+
+  if (pid <= 1 || !app_id) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  ret = __emit_app_launch_signal(pid, app_id);
+  if (ret < 0) {
+    item = __create_pending_item(app_id, pid, APP_SIGNAL_LAUNCH);
+    if (!item)
+      return -ENOMEM;
+
+    _W("Pend app launch signal. pid(%d), app_id(%s)", pid, app_id);
+    __pending_items = g_list_append(__pending_items, item);
+    __set_pending_item_timer();
+  }
+
+  return 0;
+}
+
+int _dbus_send_app_dead_signal(int pid) {
+  pending_item_t* item;
+  int ret;
+
+  if (pid <= 1) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  ret = __emit_app_dead_signal(pid);
+  if (ret < 0) {
+    item = __create_pending_item(nullptr, pid, APP_SIGNAL_DEAD);
+    if (!item)
+      return -ENOMEM;
+
+    _W("Pend app dead signal. pid(%d)", pid);
+    __pending_items = g_list_append(__pending_items, item);
+    __set_pending_item_timer();
+  }
+
+  return 0;
+}
+
+int _dbus_init(void) {
+  GDBusConnection* conn;
+
+  _D("DBUS_INIT");
+  conn = __get_connection();
+  if (!conn)
+    return -1;
+
+  return 0;
+}
+
+void _dbus_fini(void) {
+  _D("DBUS_FINI");
+  if (__pending_items)
+    g_list_free_full(__pending_items, __destroy_pending_item);
+
+  __unset_pending_item_timer();
+
+  if (__conn)
+    g_object_unref(__conn);
+}
diff --git a/src/launchpad-process-pool/src/launchpad_debug.c b/src/launchpad-process-pool/src/launchpad_debug.c
deleted file mode 100644 (file)
index da59159..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <linux/limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <bundle_internal.h>
-#include <ctype.h>
-
-#include "debugger_info.h"
-#include "key.h"
-#include "launchpad_common.h"
-#include "launchpad_debug.h"
-#include "launchpad_types.h"
-
-#define DEBUGGER_INFO_PATH "/usr/share/aul"
-
-static int __debug_initialized;
-static GList *__debugger_info_list;
-static debugger_info_h __debugger_info;
-static GList *__debug_argv_list;
-static GList *__extra_argv_list;
-
-int _debug_change_mount_namespace(void)
-{
-       const char *pid_str;
-       char buf[PATH_MAX];
-       int ret;
-       int fd;
-
-       pid_str = getenv("TARGET_PID");
-       if (pid_str == NULL)
-               return 0;
-
-       snprintf(buf, sizeof(buf), "/proc/%s/ns/mnt", pid_str);
-       fd = open(buf, O_RDONLY);
-       if (fd < 0) {
-               _E("open() is failed. path(%s), errno(%d)", buf, errno);
-               return -1;
-       }
-
-       ret = setns(fd, CLONE_NEWNS);
-       close(fd);
-       if (ret != 0)
-               _E("setns() is failed. errno(%d)", errno);
-
-       return ret;
-}
-
-int _debug_create_extra_argv(int *argc, char ***argv)
-{
-       int new_argc;
-       char **new_argv;
-       const char *extra_argv;
-       GList *iter;
-       int i;
-
-       if (argc == NULL || argv == NULL) {
-               _E("[DEBUG] Invalid parameter");
-               return -1;
-       }
-
-       if (__debugger_info == NULL)
-               return 0;
-
-       new_argc = g_list_length(__extra_argv_list);
-       if (new_argc == 0)
-               return 0;
-
-       new_argv = (char **)calloc(new_argc, sizeof(char *));
-       if (new_argv == NULL) {
-               _E("out of memory");
-               return -1;
-       }
-
-       i = LOADER_ARG_PATH;
-       iter = g_list_first(__extra_argv_list);
-       while (iter) {
-               extra_argv = (const char *)iter->data;
-               if (extra_argv)
-                       new_argv[i++] = strdup(extra_argv);
-
-               iter = g_list_next(iter);
-       }
-
-       *argc = new_argc;
-       *argv = new_argv;
-       _D("[DEBUG] argc: %d, i: %d", *argc, i);
-
-       return 0;
-}
-
-int _debug_create_argv(int *argc, char ***argv, bool *attach)
-{
-       int new_argc = 0;
-       char **new_argv;
-       const char *exe;
-       const char *debug_argv;
-       const char *attach_str;
-       GList *iter;
-       GList *list;
-       int i;
-
-       if (argc == NULL || argv == NULL || attach == NULL) {
-               _E("[DEBUG] Invalid parameter");
-               return -1;
-       }
-
-       if (__debugger_info == NULL)
-               return 0;
-
-       exe = _debugger_info_get_exe(__debugger_info);
-       if (exe == NULL)
-               return 0;
-
-       attach_str = _debugger_info_get_attach(__debugger_info);
-       if (attach_str && strcasecmp(attach_str, "true") == 0) {
-               *attach = true;
-               new_argc++;
-       }
-
-       list = _debugger_info_get_default_opt_list(__debugger_info);
-       new_argc += g_list_length(__debug_argv_list) + g_list_length(list) + 1;
-       new_argv = (char **)calloc(new_argc, sizeof(char *));
-       if (new_argv == NULL) {
-               _E("out of memory");
-               return -1;
-       }
-
-       i = LOADER_ARG_PATH;
-       new_argv[i++] = strdup(exe);
-
-       iter = g_list_first(list);
-       while (iter) {
-               debug_argv = (const char *)iter->data;
-               if (debug_argv)
-                       new_argv[i++] = strdup(debug_argv);
-
-               iter = g_list_next(iter);
-       }
-
-       iter = g_list_first(__debug_argv_list);
-       while (iter) {
-               debug_argv = (const char *)iter->data;
-               if (debug_argv)
-                       new_argv[i++] = strdup(debug_argv);
-
-               iter = g_list_next(iter);
-       }
-
-       *argc = new_argc;
-       *argv = new_argv;
-       _D("[DEBUG] argc: %d, argv[0]: %s",
-                       new_argc, new_argv[LOADER_ARG_PATH]);
-
-       return 0;
-}
-
-void _debug_destroy_argv(int argc, char **argv)
-{
-       int i;
-
-       if (argv == NULL)
-               return;
-
-       for (i = 0; i < argc; i++)
-               free(argv[i]);
-       free(argv);
-}
-
-int _debug_get_caller_pid(bundle *kb)
-{
-       const char *pid_str;
-       int pid;
-
-       pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
-       if (pid_str == NULL)
-               pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
-
-       if (pid_str == NULL)
-               return -1;
-
-       pid = atoi(pid_str);
-       if (pid <= 1)
-               return -1;
-
-       return pid;
-}
-
-static int __redirect_std_fds(bundle *kb)
-{
-       char path[PATH_MAX];
-       char err_buf[1024];
-       int fd;
-       int caller_pid;
-
-       if (kb == NULL) {
-               _E("[DEBUG] Invalid parameter");
-               return -1;
-       }
-
-       caller_pid = _debug_get_caller_pid(kb);
-       if (caller_pid < 0) {
-               _E("[DEBUG] Failed to get caller pid");
-               return -1;
-       }
-
-       /* stdin */
-       snprintf(path, sizeof(path), "/proc/%d/fd/0", caller_pid);
-       fd = open(path, O_RDONLY);
-       if (fd < 0) {
-               _E("[DEBUG] Failed to open %s [%s]", path,
-                               strerror_r(errno, err_buf, sizeof(err_buf)));
-               return -1;
-       }
-       dup2(fd, 0);
-       close(fd);
-
-       /* stdout */
-       snprintf(path, sizeof(path), "/proc/%d/fd/1", caller_pid);
-       fd = open(path, O_WRONLY);
-       if (fd < 0) {
-               _E("[DEBUG] Failed to open %s [%s]", path,
-                               strerror_r(errno, err_buf, sizeof(err_buf)));
-               return -1;
-       }
-       dup2(fd, 1);
-       close(fd);
-
-       /* stderr */
-       snprintf(path, sizeof(path), "/proc/%d/fd/2", caller_pid);
-       fd = open(path, O_WRONLY);
-       if (fd < 0) {
-               _E("[DEBUG] Failed to open %s [%s]", path,
-                               strerror_r(errno, err_buf, sizeof(err_buf)));
-               return -1;
-       }
-       dup2(fd, 2);
-       close(fd);
-
-       return 0;
-}
-
-static void __add_extra_argv(gpointer data, gpointer user_data)
-{
-       const char *key = (const char *)data;
-       bundle *kb = (bundle *)user_data;
-       const char *str;
-       const char **str_arr = NULL;
-       int len = 0;
-       int i;
-
-       if (key == NULL || kb == NULL)
-               return;
-
-       _D("[DEBUG] key: %s", key);
-       if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
-               str_arr = bundle_get_str_array(kb, key, &len);
-       } else {
-               str = bundle_get_val(kb, key);
-               if (str) {
-                       str_arr = &str;
-                       len = 1;
-               }
-       }
-
-       for (i = 0; i < len; i++) {
-               if (str_arr[i] == NULL)
-                       break;
-
-               __extra_argv_list = g_list_append(__extra_argv_list,
-                               strdup(str_arr[i]));
-       }
-
-       if (str_arr)
-               bundle_del(kb, key);
-}
-
-static void __add_debug_argv(gpointer data, gpointer user_data)
-{
-       const char *key = (const char *)data;
-       bundle *kb = (bundle *)user_data;
-       const char *str;
-       const char **str_arr = NULL;
-       int len = 0;
-       int i;
-
-       if (key == NULL || kb == NULL)
-               return;
-
-       _D("[DEBUG] key: %s", key);
-       if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
-               str_arr = bundle_get_str_array(kb, key, &len);
-       } else {
-               str = bundle_get_val(kb, key);
-               if (str) {
-                       str_arr = &str;
-                       len = 1;
-               }
-       }
-
-       for (i = 0; i < len; i++) {
-               if (str_arr[i] == NULL)
-                       break;
-
-               __debug_argv_list = g_list_append(__debug_argv_list,
-                               strdup(str_arr[i]));
-               if (!strcmp(key, "__DLP_ATTACH_ARG__")) {
-                       if (isdigit(str_arr[i][0])) {
-                               _D("Target PID: %s", str_arr[i]);
-                               setenv("TARGET_PID", str_arr[i], 1);
-                       }
-               }
-       }
-
-       if (str_arr)
-               bundle_del(kb, key);
-}
-
-static void __set_debug_env(gpointer data, gpointer user_data)
-{
-       const char *key = (const char *)data;
-       bundle *kb = (bundle *)user_data;
-       const char *str;
-       const char **str_arr = NULL;
-       int len = 0;
-       int i;
-       char buf[LINE_MAX] = {0,};
-
-       if (key == NULL || kb == NULL)
-               return;
-
-       _D("[DEBUG] key: %s", key);
-       if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
-               str_arr = bundle_get_str_array(kb, key, &len);
-       } else {
-               str = bundle_get_val(kb, key);
-               if (str) {
-                       str_arr = &str;
-                       len = 1;
-               }
-       }
-
-       if (str_arr == NULL)
-               return;
-
-       strncat(buf, str_arr[0], sizeof(buf) - strlen(buf) - 1);
-       for (i = 1; i < len; i++) {
-               if (str_arr[i] == NULL)
-                       break;
-
-               strncat(buf, ",", sizeof(buf) - strlen(buf) - 1);
-               strncat(buf, str_arr[i], sizeof(buf) - strlen(buf) - 1);
-       }
-
-       bundle_del(kb, key);
-       _D("[DEBUG] name: %s, value: %s", key, buf);
-       setenv(key, buf, 1);
-}
-
-static void __remove_file(gpointer data, gpointer user_data)
-{
-       const char *file = (const char *)data;
-
-       if (file == NULL)
-               return;
-
-       _D("[DEBUG] file: %s", file);
-       if (access(file, F_OK) == 0) {
-               if (remove(file) != 0)
-                       _W("[DEBUG] Failed to remove %s", file);
-       }
-}
-
-void _debug_prepare_debugger(bundle *kb)
-{
-       const char *debugger;
-       GList *list;
-       int ret;
-
-       if (kb == NULL)
-               return;
-
-       debugger = bundle_get_val(kb, AUL_K_SDK);
-       if (debugger == NULL)
-               return;
-
-       if (!strcmp(debugger, "ASAN"))
-               setenv("TIZEN_ASAN_ACTIVATION", "1", 1);
-
-       ret = __redirect_std_fds(kb);
-       if (ret < 0)
-               _E("[DEBUG] Failed to redirect standard fds");
-
-       _D("[DEBUG] debugger: %s", debugger);
-       __debugger_info = _debugger_info_find(__debugger_info_list, debugger);
-       if (__debugger_info == NULL)
-               return;
-
-       list = _debugger_info_get_unlink_list(__debugger_info);
-       g_list_foreach(list, __remove_file, NULL);
-
-       list = _debugger_info_get_extra_env_list(__debugger_info);
-       g_list_foreach(list, __set_debug_env, kb);
-
-       list = _debugger_info_get_extra_key_list(__debugger_info);
-       g_list_foreach(list, __add_debug_argv, kb);
-
-       list = _debugger_info_get_last_extra_key_list(__debugger_info);
-       g_list_foreach(list, __add_extra_argv, kb);
-}
-
-int _debug_init(void)
-{
-       if (__debug_initialized)
-               return 0;
-
-       __debugger_info_list = _debugger_info_load(DEBUGGER_INFO_PATH);
-       if (__debugger_info_list == NULL)
-               return -1;
-
-       __debug_initialized = 1;
-
-       return 0;
-}
-
-void _debug_fini(void)
-{
-       if (!__debug_initialized)
-               return;
-
-       _debugger_info_unload(__debugger_info_list);
-}
diff --git a/src/launchpad-process-pool/src/launchpad_debug.cc b/src/launchpad-process-pool/src/launchpad_debug.cc
new file mode 100644 (file)
index 0000000..12f8bdc
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bundle_internal.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <linux/limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <algorithm>
+
+#include "debugger_info.hh"
+#include "key.h"
+#include "launchpad_common.h"
+#include "launchpad_debug.h"
+#include "launchpad_types.h"
+
+#define DEBUGGER_INFO_PATH "/usr/share/aul"
+
+namespace {
+
+int __debug_initialized;
+std::vector<launchpad::DebuggerInfoPtr> __debugger_info_list;
+launchpad::DebuggerInfoPtr __debugger_info;
+std::vector<std::string> __debug_argv_list;
+std::vector<std::string> __extra_argv_list;
+
+}  // namespace
+
+int _debug_change_mount_namespace(void) {
+  const char* pid_str;
+  char buf[PATH_MAX];
+  int ret;
+  int fd;
+
+  pid_str = getenv("TARGET_PID");
+  if (pid_str == nullptr)
+    return 0;
+
+  snprintf(buf, sizeof(buf), "/proc/%s/ns/mnt", pid_str);
+  fd = open(buf, O_RDONLY);
+  if (fd < 0) {
+    _E("open() is failed. path(%s), errno(%d)", buf, errno);
+    return -1;
+  }
+
+  ret = setns(fd, CLONE_NEWNS);
+  close(fd);
+  if (ret != 0)
+    _E("setns() is failed. errno(%d)", errno);
+
+  return ret;
+}
+
+int _debug_create_extra_argv(int* argc, char*** argv) {
+  int new_argc;
+  char** new_argv;
+  int i;
+
+  if (argc == nullptr || argv == nullptr) {
+    _E("[DEBUG] Invalid parameter");
+    return -1;
+  }
+
+  if (__debugger_info == nullptr)
+    return 0;
+
+  new_argc = __extra_argv_list.size();
+  if (new_argc == 0)
+    return 0;
+
+  new_argv = static_cast<char**>(calloc(new_argc, sizeof(char*)));
+  if (new_argv == nullptr) {
+    _E("out of memory");
+    return -1;
+  }
+
+  i = LOADER_ARG_PATH;
+  for (auto& argv : __extra_argv_list) {
+    new_argv[i++] = strdup(argv.c_str());
+  }
+
+  *argc = new_argc;
+  *argv = new_argv;
+  _D("[DEBUG] argc: %d, i: %d", *argc, i);
+
+  return 0;
+}
+
+int _debug_create_argv(int* argc, char*** argv, bool* attach) {
+  int new_argc = 0;
+  char** new_argv;
+  const char* exe;
+  const char* attach_str;
+  int i;
+
+  if (argc == nullptr || argv == nullptr || attach == nullptr) {
+    _E("[DEBUG] Invalid parameter");
+    return -1;
+  }
+
+  if (__debugger_info == nullptr)
+    return 0;
+
+  exe = __debugger_info->GetExe().data();
+  if (exe == nullptr)
+    return 0;
+
+  attach_str = __debugger_info->GetAttachInfo().c_str();
+  if (attach_str && strcasecmp(attach_str, "true") == 0) {
+    *attach = true;
+    new_argc++;
+  }
+
+  auto list = __debugger_info->GetDefaultOptList();
+  new_argc += __debug_argv_list.size() + list.size() + 1;
+  new_argv = static_cast<char**>(calloc(new_argc, sizeof(char*)));
+  if (new_argv == nullptr) {
+    _E("out of memory");
+    return -1;
+  }
+
+  i = LOADER_ARG_PATH;
+  new_argv[i++] = strdup(exe);
+
+  for (auto& debug_argv : list) {
+    new_argv[i++] = strdup(debug_argv.c_str());
+  }
+
+  for (auto& debug_argv : __debug_argv_list) {
+    new_argv[i++] = strdup(debug_argv.c_str());
+  }
+
+  *argc = new_argc;
+  *argv = new_argv;
+  _D("[DEBUG] argc: %d, argv[0]: %s", new_argc, new_argv[LOADER_ARG_PATH]);
+
+  return 0;
+}
+
+void _debug_destroy_argv(int argc, char** argv) {
+  int i;
+
+  if (argv == nullptr)
+    return;
+
+  for (i = 0; i < argc; i++)
+    free(argv[i]);
+  free(argv);
+}
+
+int _debug_get_caller_pid(bundle* kb) {
+  const char* pid_str;
+  int pid;
+
+  pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
+  if (pid_str == nullptr)
+    pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
+
+  if (pid_str == nullptr)
+    return -1;
+
+  pid = atoi(pid_str);
+  if (pid <= 1)
+    return -1;
+
+  return pid;
+}
+
+static int __redirect_std_fds(bundle* kb) {
+  char path[PATH_MAX];
+  char err_buf[1024];
+  int fd;
+  int caller_pid;
+
+  if (kb == nullptr) {
+    _E("[DEBUG] Invalid parameter");
+    return -1;
+  }
+
+  caller_pid = _debug_get_caller_pid(kb);
+  if (caller_pid < 0) {
+    _E("[DEBUG] Failed to get caller pid");
+    return -1;
+  }
+
+  /* stdin */
+  snprintf(path, sizeof(path), "/proc/%d/fd/0", caller_pid);
+  fd = open(path, O_RDONLY);
+  if (fd < 0) {
+    _E("[DEBUG] Failed to open %s [%s]", path,
+       strerror_r(errno, err_buf, sizeof(err_buf)));
+    return -1;
+  }
+  dup2(fd, 0);
+  close(fd);
+
+  /* stdout */
+  snprintf(path, sizeof(path), "/proc/%d/fd/1", caller_pid);
+  fd = open(path, O_WRONLY);
+  if (fd < 0) {
+    _E("[DEBUG] Failed to open %s [%s]", path,
+       strerror_r(errno, err_buf, sizeof(err_buf)));
+    return -1;
+  }
+  dup2(fd, 1);
+  close(fd);
+
+  /* stderr */
+  snprintf(path, sizeof(path), "/proc/%d/fd/2", caller_pid);
+  fd = open(path, O_WRONLY);
+  if (fd < 0) {
+    _E("[DEBUG] Failed to open %s [%s]", path,
+       strerror_r(errno, err_buf, sizeof(err_buf)));
+    return -1;
+  }
+  dup2(fd, 2);
+  close(fd);
+
+  return 0;
+}
+
+static void __add_extra_argv(const std::string& key, bundle* kb) {
+  const char* str;
+  const char** str_arr = nullptr;
+  int len = 0;
+  int i;
+
+  _D("[DEBUG] key: %s", key.c_str());
+  if (bundle_get_type(kb, key.c_str()) & BUNDLE_TYPE_ARRAY) {
+    str_arr = bundle_get_str_array(kb, key.c_str(), &len);
+  } else {
+    str = bundle_get_val(kb, key.c_str());
+    if (str) {
+      str_arr = &str;
+      len = 1;
+    }
+  }
+
+  for (i = 0; i < len; i++) {
+    if (str_arr[i] == nullptr)
+      break;
+
+    __extra_argv_list.push_back(str_arr[i]);
+  }
+
+  if (str_arr)
+    bundle_del(kb, key.c_str());
+}
+
+static void __add_debug_argv(const std::string& key, bundle* kb) {
+  const char* str;
+  const char** str_arr = nullptr;
+  int len = 0;
+  int i;
+
+  _D("[DEBUG] key: %s", key.c_str());
+  if (bundle_get_type(kb, key.c_str()) & BUNDLE_TYPE_ARRAY) {
+    str_arr = bundle_get_str_array(kb, key.c_str(), &len);
+  } else {
+    str = bundle_get_val(kb, key.c_str());
+    if (str) {
+      str_arr = &str;
+      len = 1;
+    }
+  }
+
+  for (i = 0; i < len; i++) {
+    if (str_arr[i] == nullptr)
+      break;
+
+    __debug_argv_list.push_back(str_arr[i]);
+    if (!strcmp(key.c_str(), "__DLP_ATTACH_ARG__")) {
+      if (isdigit(str_arr[i][0])) {
+        _D("Target PID: %s", str_arr[i]);
+        setenv("TARGET_PID", str_arr[i], 1);
+      }
+    }
+  }
+
+  if (str_arr)
+    bundle_del(kb, key.c_str());
+}
+
+static void __set_debug_env(const std::string& key, bundle* kb) {
+  const char* str;
+  const char** str_arr = nullptr;
+  int len = 0;
+  int i;
+  char buf[LINE_MAX] = {
+      0,
+  };
+
+  _D("[DEBUG] key: %s", key.c_str());
+  if (bundle_get_type(kb, key.c_str()) & BUNDLE_TYPE_ARRAY) {
+    str_arr = bundle_get_str_array(kb, key.c_str(), &len);
+  } else {
+    str = bundle_get_val(kb, key.c_str());
+    if (str) {
+      str_arr = &str;
+      len = 1;
+    }
+  }
+
+  if (str_arr == nullptr)
+    return;
+
+  strncat(buf, str_arr[0], sizeof(buf) - strlen(buf) - 1);
+  for (i = 1; i < len; i++) {
+    if (str_arr[i] == nullptr)
+      break;
+
+    strncat(buf, ",", sizeof(buf) - strlen(buf) - 1);
+    strncat(buf, str_arr[i], sizeof(buf) - strlen(buf) - 1);
+  }
+
+  bundle_del(kb, key.c_str());
+  _D("[DEBUG] name: %s, value: %s", key.c_str(), buf);
+  setenv(key.c_str(), buf, 1);
+}
+
+static void __remove_file(const std::string& file) {
+  _D("[DEBUG] file: %s", file.c_str());
+  if (access(file.c_str(), F_OK) == 0) {
+    if (remove(file.c_str()) != 0)
+      _W("[DEBUG] Failed to remove %s", file.c_str());
+  }
+}
+
+void _debug_prepare_debugger(bundle* kb) {
+  const char* debugger;
+  int ret;
+
+  if (kb == nullptr)
+    return;
+
+  debugger = bundle_get_val(kb, AUL_K_SDK);
+  if (debugger == nullptr)
+    return;
+
+  if (!strcmp(debugger, "ASAN"))
+    setenv("TIZEN_ASAN_ACTIVATION", "1", 1);
+
+  ret = __redirect_std_fds(kb);
+  if (ret < 0)
+    _E("[DEBUG] Failed to redirect standard fds");
+
+  _D("[DEBUG] debugger: %s", debugger);
+  auto it =
+      std::find_if(__debugger_info_list.begin(), __debugger_info_list.end(),
+                   [&](const launchpad::DebuggerInfoPtr& info) -> bool {
+                     return strcasecmp(info->GetExe().c_str(), debugger) == 0;
+                   });
+  if (it == __debugger_info_list.end())
+    return;
+
+  __debugger_info = *it;
+  for (auto& unlink_file : __debugger_info->GetUnlinkList()) {
+    __remove_file(unlink_file);
+  }
+
+  for (auto& extra_env : __debugger_info->GetExtraEnvList()) {
+    __set_debug_env(extra_env, kb);
+  }
+
+  for (auto& extra_key : __debugger_info->GetExtraKeyList()) {
+    __add_debug_argv(extra_key, kb);
+  }
+
+  for (auto& last_extra_key : __debugger_info->GetLastExtraKeyList()) {
+    __add_extra_argv(last_extra_key, kb);
+  }
+}
+
+int _debug_init(void) {
+  if (__debug_initialized)
+    return 0;
+
+  launchpad::DebuggerInfoInflator inflator;
+  __debugger_info_list = inflator.Inflate(DEBUGGER_INFO_PATH);
+  if (__debugger_info_list.empty())
+    return -1;
+
+  __debug_initialized = 1;
+
+  return 0;
+}
+
+void _debug_fini(void) {
+  if (!__debug_initialized)
+    return;
+
+  __debugger_info_list.clear();
+}
diff --git a/src/launchpad-process-pool/src/launchpad_inotify.c b/src/launchpad-process-pool/src/launchpad_inotify.c
deleted file mode 100644 (file)
index 9130fa2..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/inotify.h>
-#include <glib.h>
-#include <gio/gio.h>
-
-#include "launchpad_inotify.h"
-#include "log_private.h"
-
-struct inotify_watch_info_s {
-       int fd;
-       int wd;
-       GIOChannel *io;
-       guint tag;
-       uint32_t mask;
-       inotify_watch_cb cb;
-       void *data;
-};
-
-static GList *__watch_list;
-
-static gboolean __inotify_cb(GIOChannel *source, GIOCondition condition,
-               gpointer data)
-{
-#define ALIGN_INOTIFY_EVENT \
-       __attribute__ ((aligned(__alignof__(struct inotify_event))))
-#define SIZE_INOTIFY_EVENT (sizeof(struct inotify_event))
-       int fd = g_io_channel_unix_get_fd(source);
-       char buf[4096] ALIGN_INOTIFY_EVENT;
-       const struct inotify_event *event;
-       struct inotify_watch_info_s *info = data;
-       ssize_t len;
-       char *ptr;
-       char *nptr;
-
-       while ((len = read(fd, buf, sizeof(buf))) > 0) {
-               for (ptr = buf; ptr < buf + len;
-                       ptr += sizeof(struct inotify_event) + event->len) {
-                       if ((ptr + SIZE_INOTIFY_EVENT) > (buf + len))
-                               break;
-
-                       event = (const struct inotify_event *)ptr;
-                       nptr = ptr + sizeof(struct inotify_event) + event->len;
-                       if (nptr > buf + len)
-                               break;
-
-                       if (event->mask & info->mask) {
-                               if (!info->cb(event->name, event->mask,
-                                                       info->data)) {
-                                       _inotify_rm_watch(info);
-                                       return G_SOURCE_CONTINUE;
-                               }
-                       }
-               }
-       }
-
-       return G_SOURCE_CONTINUE;
-}
-
-static void __destroy_inotify_watch_info(gpointer data)
-{
-       struct inotify_watch_info_s *info = (struct inotify_watch_info_s *)data;
-
-       if (info == NULL)
-               return;
-
-       if (info->tag > 0)
-               g_source_remove(info->tag);
-
-       if (info->io)
-               g_io_channel_unref(info->io);
-
-       if (info->wd > 0)
-               inotify_rm_watch(info->fd, info->wd);
-
-       if (info->fd > 0)
-               close(info->fd);
-
-       free(info);
-}
-
-static struct inotify_watch_info_s *__create_inotify_watch_info(
-               const char *path, uint32_t mask, inotify_watch_cb cb,
-               void *data)
-{
-       GIOCondition cond = G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP;
-       struct inotify_watch_info_s *info;
-
-       info = calloc(1, sizeof(struct inotify_watch_info_s));
-       if (info == NULL) {
-               _E("Out of memory");
-               return NULL;
-       }
-
-       info->fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
-       if (info->fd < 0) {
-               _E("inotify_init1() is failed. errno(%d)", errno);
-               __destroy_inotify_watch_info(info);
-               return NULL;
-       }
-
-       info->wd = inotify_add_watch(info->fd, path, mask);
-       if (info->wd < 0) {
-               _E("inotify_add_watch() is failed. path(%s), errno(%d)",
-                               path, errno);
-               __destroy_inotify_watch_info(info);
-               return NULL;
-       }
-
-       info->io = g_io_channel_unix_new(info->fd);
-       if (!info->io) {
-               _E("g_io_channel_unix_new() is failed");
-               __destroy_inotify_watch_info(info);
-               return NULL;
-       }
-
-       info->tag = g_io_add_watch(info->io, cond,
-                       __inotify_cb, info);
-       if (!info->tag) {
-               _E("g_io_add_watch() is failed");
-               __destroy_inotify_watch_info(info);
-               return NULL;
-       }
-
-       info->mask = mask;
-       info->cb = cb;
-       info->data = data;
-
-       return info;
-}
-
-int _inotify_add_watch(const char *path, uint32_t mask,
-               inotify_watch_cb callback, void *data)
-{
-       struct inotify_watch_info_s *info;
-
-       if (path == NULL || callback == NULL) {
-               _E("Invalid parameter");
-               return -1;
-       }
-
-       info = __create_inotify_watch_info(path, mask, callback, data);
-       if (info == NULL)
-               return -1;
-
-       __watch_list = g_list_append(__watch_list, info);
-
-       return 0;
-}
-
-void _inotify_rm_watch(inotify_watch_info_h handle)
-{
-       if (handle == NULL)
-               return;
-
-       __watch_list = g_list_remove(__watch_list, handle);
-       __destroy_inotify_watch_info(handle);
-}
-
-int _inotify_init(void)
-{
-       _D("inotify init");
-
-       return 0;
-}
-
-void _inotify_fini(void)
-{
-       _D("inotify fini");
-
-       if (__watch_list)
-               g_list_free_full(__watch_list, __destroy_inotify_watch_info);
-}
diff --git a/src/launchpad-process-pool/src/launchpad_inotify.cc b/src/launchpad-process-pool/src/launchpad_inotify.cc
new file mode 100644 (file)
index 0000000..2afc91a
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gio/gio.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/inotify.h>
+
+#include "launchpad_inotify.h"
+#include "log_private.h"
+
+struct inotify_watch_info_s {
+  int fd;
+  int wd;
+  GIOChannel* io;
+  guint tag;
+  uint32_t mask;
+  inotify_watch_cb cb;
+  void* data;
+};
+
+static GList* __watch_list;
+
+static gboolean __inotify_cb(GIOChannel* source,
+                             GIOCondition condition,
+                             gpointer data) {
+#define ALIGN_INOTIFY_EVENT \
+  __attribute__((aligned(__alignof__(struct inotify_event))))
+#define SIZE_INOTIFY_EVENT (sizeof(struct inotify_event))
+  int fd = g_io_channel_unix_get_fd(source);
+  char buf[4096] ALIGN_INOTIFY_EVENT;
+  const struct inotify_event* event;
+  auto* info = static_cast<inotify_watch_info_s*>(data);
+  ssize_t len;
+  char* ptr;
+  char* nptr;
+
+  while ((len = read(fd, buf, sizeof(buf))) > 0) {
+    for (ptr = buf; ptr < buf + len;
+         ptr += sizeof(struct inotify_event) + event->len) {
+      if ((ptr + SIZE_INOTIFY_EVENT) > (buf + len))
+        break;
+
+      event = (const struct inotify_event*)ptr;
+      nptr = ptr + sizeof(struct inotify_event) + event->len;
+      if (nptr > buf + len)
+        break;
+
+      if (event->mask & info->mask) {
+        if (!info->cb(event->name, event->mask, info->data)) {
+          _inotify_rm_watch(info);
+          return G_SOURCE_CONTINUE;
+        }
+      }
+    }
+  }
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void __destroy_inotify_watch_info(gpointer data) {
+  struct inotify_watch_info_s* info = (struct inotify_watch_info_s*)data;
+
+  if (info == nullptr)
+    return;
+
+  if (info->tag > 0)
+    g_source_remove(info->tag);
+
+  if (info->io)
+    g_io_channel_unref(info->io);
+
+  if (info->wd > 0)
+    inotify_rm_watch(info->fd, info->wd);
+
+  if (info->fd > 0)
+    close(info->fd);
+
+  free(info);
+}
+
+static struct inotify_watch_info_s* __create_inotify_watch_info(
+    const char* path,
+    uint32_t mask,
+    inotify_watch_cb cb,
+    void* data) {
+  auto cond = G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP;
+  struct inotify_watch_info_s* info;
+
+  info = static_cast<inotify_watch_info_s*>(
+      calloc(1, sizeof(inotify_watch_info_s)));
+  if (info == nullptr) {
+    _E("Out of memory");
+    return nullptr;
+  }
+
+  info->fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+  if (info->fd < 0) {
+    _E("inotify_init1() is failed. errno(%d)", errno);
+    __destroy_inotify_watch_info(info);
+    return nullptr;
+  }
+
+  info->wd = inotify_add_watch(info->fd, path, mask);
+  if (info->wd < 0) {
+    _E("inotify_add_watch() is failed. path(%s), errno(%d)", path, errno);
+    __destroy_inotify_watch_info(info);
+    return nullptr;
+  }
+
+  info->io = g_io_channel_unix_new(info->fd);
+  if (!info->io) {
+    _E("g_io_channel_unix_new() is failed");
+    __destroy_inotify_watch_info(info);
+    return nullptr;
+  }
+
+  info->tag = g_io_add_watch(info->io, static_cast<GIOCondition>(cond),
+                             __inotify_cb, info);
+  if (!info->tag) {
+    _E("g_io_add_watch() is failed");
+    __destroy_inotify_watch_info(info);
+    return nullptr;
+  }
+
+  info->mask = mask;
+  info->cb = cb;
+  info->data = data;
+
+  return info;
+}
+
+int _inotify_add_watch(const char* path,
+                       uint32_t mask,
+                       inotify_watch_cb callback,
+                       void* data) {
+  struct inotify_watch_info_s* info;
+
+  if (path == nullptr || callback == nullptr) {
+    _E("Invalid parameter");
+    return -1;
+  }
+
+  info = __create_inotify_watch_info(path, mask, callback, data);
+  if (info == nullptr)
+    return -1;
+
+  __watch_list = g_list_append(__watch_list, info);
+
+  return 0;
+}
+
+void _inotify_rm_watch(inotify_watch_info_h handle) {
+  if (handle == nullptr)
+    return;
+
+  __watch_list = g_list_remove(__watch_list, handle);
+  __destroy_inotify_watch_info(handle);
+}
+
+int _inotify_init(void) {
+  _D("inotify init");
+
+  return 0;
+}
+
+void _inotify_fini(void) {
+  _D("inotify fini");
+
+  if (__watch_list)
+    g_list_free_full(__watch_list, __destroy_inotify_watch_info);
+}
diff --git a/src/launchpad-process-pool/src/launchpad_io_channel.c b/src/launchpad-process-pool/src/launchpad_io_channel.c
deleted file mode 100644 (file)
index 31529a3..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <glib.h>
-#include <gio/gio.h>
-
-#include "launchpad_io_channel.h"
-#include "log_private.h"
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-
-struct io_channel_s {
-       GIOChannel *io;
-       guint tag;
-       bool do_close;
-       int fd;
-       io_channel_event_cb callback;
-       void *user_data;
-};
-
-struct io_condition_s {
-       io_condition_e io_cond;
-       GIOCondition g_io_cond;
-};
-
-static struct io_condition_s __cond_map[] = {
-       {
-               .io_cond = IO_IN,
-               .g_io_cond = G_IO_IN
-       },
-       {
-               .io_cond = IO_OUT,
-               .g_io_cond = G_IO_OUT
-       },
-       {
-               .io_cond = IO_PRI,
-               .g_io_cond = G_IO_PRI
-       },
-       {
-               .io_cond = IO_ERR,
-               .g_io_cond = G_IO_ERR
-       },
-       {
-               .io_cond = IO_HUP,
-               .g_io_cond = G_IO_HUP
-       },
-       {
-               .io_cond = IO_NVAL,
-               .g_io_cond = G_IO_NVAL,
-       }
-};
-
-static io_condition_e __convert_g_io_condition(GIOCondition cond)
-{
-       io_condition_e condition = 0;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(__cond_map); i++) {
-               if (__cond_map[i].g_io_cond & cond)
-                       condition |= __cond_map[i].io_cond;
-       }
-
-       return condition;
-}
-
-static GIOCondition __convert_io_condition(io_condition_e cond)
-{
-       GIOCondition condition = 0;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(__cond_map); i++) {
-               if (__cond_map[i].io_cond & cond)
-                       condition |= __cond_map[i].g_io_cond;
-       }
-
-       return condition;
-}
-
-static gboolean __io_event_cb(GIOChannel *source, GIOCondition condition,
-               gpointer data)
-{
-       io_channel_h channel = (io_channel_h)data;
-       io_condition_e cond = __convert_g_io_condition(condition);
-       int fd = g_io_channel_unix_get_fd(source);
-
-       if (!channel->callback(fd, cond, channel->user_data))
-               return G_SOURCE_REMOVE;
-
-       return G_SOURCE_CONTINUE;
-}
-
-io_channel_h _io_channel_create(int fd, io_condition_e cond,
-               io_channel_event_cb callback, void *user_data)
-{
-       struct io_channel_s *channel;
-
-       if (fd < 3 || !callback) {
-               _E("Invalid parameter");
-               return NULL;
-       }
-
-       channel = calloc(1, sizeof(struct io_channel_s));
-       if (!channel) {
-               _E("Out of memory");
-               return NULL;
-       }
-
-       channel->io = g_io_channel_unix_new(fd);
-       if (!channel->io) {
-               _E("Failed to create GIOChannel");
-               _io_channel_destroy(channel);
-               return NULL;
-       }
-
-       channel->tag = g_io_add_watch(channel->io, __convert_io_condition(cond),
-                       __io_event_cb, channel);
-       if (!channel->tag) {
-               _E("Failed to add GIO watch");
-               _io_channel_destroy(channel);
-               return NULL;
-       }
-
-       channel->do_close = true;
-       channel->fd = fd;
-       channel->callback = callback;
-       channel->user_data = user_data;
-
-       return channel;
-}
-
-void _io_channel_destroy(io_channel_h channel)
-{
-       if (!channel)
-               return;
-
-       if (channel->tag)
-               g_source_remove(channel->tag);
-
-       if (channel->io)
-               g_io_channel_unref(channel->io);
-
-       if (channel->do_close && channel->fd > 0)
-               close(channel->fd);
-
-       free(channel);
-}
-
-int _io_channel_set_close_on_destroy(io_channel_h channel, bool do_close)
-{
-       if (!channel) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       channel->do_close = do_close;
-
-       return 0;
-}
diff --git a/src/launchpad-process-pool/src/launchpad_io_channel.cc b/src/launchpad-process-pool/src/launchpad_io_channel.cc
new file mode 100644 (file)
index 0000000..5987793
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gio/gio.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "launchpad_io_channel.h"
+#include "log_private.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+struct io_channel_s {
+  GIOChannel* io;
+  guint tag;
+  bool do_close;
+  int fd;
+  io_channel_event_cb callback;
+  void* user_data;
+};
+
+struct io_condition_s {
+  io_condition_e io_cond;
+  GIOCondition g_io_cond;
+};
+
+static struct io_condition_s __cond_map[] = {
+    {.io_cond = IO_IN, .g_io_cond = G_IO_IN},
+    {.io_cond = IO_OUT, .g_io_cond = G_IO_OUT},
+    {.io_cond = IO_PRI, .g_io_cond = G_IO_PRI},
+    {.io_cond = IO_ERR, .g_io_cond = G_IO_ERR},
+    {.io_cond = IO_HUP, .g_io_cond = G_IO_HUP},
+    {
+        .io_cond = IO_NVAL,
+        .g_io_cond = G_IO_NVAL,
+    }};
+
+static io_condition_e __convert_g_io_condition(GIOCondition cond) {
+  int condition = 0;
+  int i;
+
+  for (i = 0; i < ARRAY_SIZE(__cond_map); i++) {
+    if (__cond_map[i].g_io_cond & cond)
+      condition |= __cond_map[i].io_cond;
+  }
+
+  return static_cast<io_condition_e>(condition);
+}
+
+static GIOCondition __convert_io_condition(io_condition_e cond) {
+  int condition = 0;
+  int i;
+
+  for (i = 0; i < ARRAY_SIZE(__cond_map); i++) {
+    if (__cond_map[i].io_cond & cond)
+      condition |= __cond_map[i].g_io_cond;
+  }
+
+  return static_cast<GIOCondition>(condition);
+}
+
+static gboolean __io_event_cb(GIOChannel* source,
+                              GIOCondition condition,
+                              gpointer data) {
+  io_channel_h channel = (io_channel_h)data;
+  io_condition_e cond = __convert_g_io_condition(condition);
+  int fd = g_io_channel_unix_get_fd(source);
+
+  if (!channel->callback(fd, cond, channel->user_data))
+    return G_SOURCE_REMOVE;
+
+  return G_SOURCE_CONTINUE;
+}
+
+io_channel_h _io_channel_create(int fd,
+                                io_condition_e cond,
+                                io_channel_event_cb callback,
+                                void* user_data) {
+  struct io_channel_s* channel;
+
+  if (fd < 3 || !callback) {
+    _E("Invalid parameter");
+    return nullptr;
+  }
+
+  channel = static_cast<io_channel_s*>(calloc(1, sizeof(io_channel_s)));
+  if (!channel) {
+    _E("Out of memory");
+    return nullptr;
+  }
+
+  channel->io = g_io_channel_unix_new(fd);
+  if (!channel->io) {
+    _E("Failed to create GIOChannel");
+    _io_channel_destroy(channel);
+    return nullptr;
+  }
+
+  channel->tag = g_io_add_watch(channel->io, __convert_io_condition(cond),
+                                __io_event_cb, channel);
+  if (!channel->tag) {
+    _E("Failed to add GIO watch");
+    _io_channel_destroy(channel);
+    return nullptr;
+  }
+
+  channel->do_close = true;
+  channel->fd = fd;
+  channel->callback = callback;
+  channel->user_data = user_data;
+
+  return channel;
+}
+
+void _io_channel_destroy(io_channel_h channel) {
+  if (!channel)
+    return;
+
+  if (channel->tag)
+    g_source_remove(channel->tag);
+
+  if (channel->io)
+    g_io_channel_unref(channel->io);
+
+  if (channel->do_close && channel->fd > 0)
+    close(channel->fd);
+
+  free(channel);
+}
+
+int _io_channel_set_close_on_destroy(io_channel_h channel, bool do_close) {
+  if (!channel) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  channel->do_close = do_close;
+
+  return 0;
+}
  * limitations under the License.
  */
 
-#define _GNU_SOURCE
+#include <linux/limits.h>
 #include <stdarg.h>
 #include <stdio.h>
-#include <linux/limits.h>
 
 #include "launchpad_config.h"
 #include "launchpad_log.h"
 
 static logger_h __logger;
 
-int _log_print(const char *tag, const char *format, ...)
-{
-       char formatted_buf[LAUNCHPAD_LOG_MAX_STRING_SIZE];
-       va_list ap;
-       int ret;
+int _log_print(const char* tag, const char* format, ...) {
+  char formatted_buf[LAUNCHPAD_LOG_MAX_STRING_SIZE];
+  va_list ap;
+  int ret;
 
-       if (!__logger)
-               return 0;
+  if (!__logger)
+    return 0;
 
-       va_start(ap, format);
-       ret = vsnprintf(formatted_buf, sizeof(formatted_buf), format, ap);
-       va_end(ap);
-       if (ret < 0 || ret >= sizeof(formatted_buf)) {
-               _E("vsnprintf() is failed. result(%d)", ret);
-               return -1;
-       }
+  va_start(ap, format);
+  ret = vsnprintf(formatted_buf, sizeof(formatted_buf), format, ap);
+  va_end(ap);
+  if (ret < 0 || ret >= sizeof(formatted_buf)) {
+    _E("vsnprintf() is failed. result(%d)", ret);
+    return -1;
+  }
 
-       return _logger_print(__logger, tag, formatted_buf);
+  return _logger_print(__logger, tag, formatted_buf);
 }
 
-int _log_init(void)
-{
-       char path[PATH_MAX];
-       int ret;
+int _log_init(void) {
+  char path[PATH_MAX];
+  int ret;
 
-       _W("LOG_INIT");
-       snprintf(path, sizeof(path), "%s/launchpad/launchpad.log",
-                       _config_get_string_value(CONFIG_TYPE_LOGGER_PATH));
-       ret = _logger_create(path, &__logger);
-       if (ret != 0) {
-               _E("Failed to create log file. error(%d)", ret);
-               return ret;
-       }
+  _W("LOG_INIT");
+  snprintf(path, sizeof(path), "%s/launchpad/launchpad.log",
+           _config_get_string_value(CONFIG_TYPE_LOGGER_PATH));
+  ret = _logger_create(path, &__logger);
+  if (ret != 0) {
+    _E("Failed to create log file. error(%d)", ret);
+    return ret;
+  }
 
-       return 0;
+  return 0;
 }
 
-void _log_fini(void)
-{
-       _W("LOG_FINI");
+void _log_fini(void) {
+  _W("LOG_FINI");
 
-       if (__logger)
-               _logger_destroy(__logger);
+  if (__logger)
+    _logger_destroy(__logger);
 }
diff --git a/src/launchpad-process-pool/src/launchpad_logger.c b/src/launchpad-process-pool/src/launchpad_logger.c
deleted file mode 100644 (file)
index d6b99d8..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <errno.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/smack.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <linux/limits.h>
-
-#include "launchpad_config.h"
-#include "launchpad_logger.h"
-#include "log_private.h"
-
-#define LAUNCHPAD_LOG_APPFW_PATH "/var/log/appfw"
-#define LAUNCHPAD_LOG_PATH "/var/log/appfw/launchpad"
-#define LAUNCHPAD_LOG_MAX_SIZE 2500
-#define LAUNCHPAD_LOG_MAX_BUFFER_SIZE 256
-
-struct logger_s {
-       int fd;
-       int index;
-};
-
-static int __set_smack_label(const char *path, const char *label)
-{
-       int ret;
-
-       ret = smack_setlabel(path, label, SMACK_LABEL_ACCESS);
-       if (ret != 0) {
-               ret = -errno;
-               _E("smack_setlabel() is failed. path(%s), label(%s), errno(%d)",
-                               path, label, errno);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int __create_directory(const char *path)
-{
-       mode_t mode;
-       int ret;
-
-       ret = access(path, F_OK);
-       if (ret == 0)
-               return 0;
-
-       mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
-       ret = mkdir(path, mode);
-       if (ret < 0) {
-               ret = -errno;
-               _E("Failed to create directory(%s). errno(%d)", path, errno);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int __create_launchpad_directories(void)
-{
-       const char *logger_path;
-       char path[PATH_MAX];
-       int ret;
-
-       logger_path = _config_get_string_value(CONFIG_TYPE_LOGGER_PATH);
-       ret = __create_directory(logger_path);
-       if (ret < 0)
-               return ret;
-
-       ret = __set_smack_label(logger_path, "User::Home");
-       if (ret < 0)
-               return ret;
-
-       snprintf(path, sizeof(path), "%s/launchpad", logger_path);
-       ret = __create_directory(path);
-       if (ret < 0)
-               return ret;
-
-       ret = __set_smack_label(path, "User");
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int _logger_create(const char *path, logger_h *handle)
-{
-       struct logger_s *logger;
-       off_t offset;
-       int ret;
-
-       if (!_config_get_int_value(CONFIG_TYPE_LOGGER_ENABLE))
-               return 0;
-
-       if (!path || !handle) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       ret = __create_launchpad_directories();
-       if (ret < 0)
-               return ret;
-
-       logger = calloc(1, sizeof(struct logger_s));
-       if (!logger) {
-               _E("Out of memory");
-               return -ENOMEM;
-       }
-
-       logger->fd = open(path, O_CREAT | O_WRONLY, 0640);
-       if (logger->fd < 0) {
-               ret = -errno;
-               _E("Failed to open path(%s), errno(%d)", path, errno);
-               _logger_destroy(logger);
-               return ret;
-       }
-
-       ret = __set_smack_label(path, "User");
-       if (ret < 0) {
-               _logger_destroy(logger);
-               return ret;
-       }
-
-       offset = lseek(logger->fd, 0, SEEK_END);
-       if (offset != 0) {
-               logger->index = (int)(offset / LAUNCHPAD_LOG_MAX_STRING_SIZE);
-               if (logger->index >= LAUNCHPAD_LOG_MAX_SIZE) {
-                       logger->index = 0;
-                       lseek(logger->fd, 0, SEEK_SET);
-               }
-       }
-
-       *handle = logger;
-
-       return 0;
-}
-
-int _logger_destroy(logger_h handle)
-{
-       if (!_config_get_int_value(CONFIG_TYPE_LOGGER_ENABLE))
-               return 0;
-
-       if (!handle) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       if (handle->fd > 0)
-               close(handle->fd);
-
-       free(handle);
-
-       return 0;
-}
-
-int _logger_print(logger_h handle, const char *tag, const char *format, ...)
-{
-       char buf[LAUNCHPAD_LOG_MAX_BUFFER_SIZE];
-       char format_buf[128];
-       struct tm tm = { 0, };
-       time_t t;
-       ssize_t ret;
-       va_list ap;
-       off_t offset;
-       int bytes;
-
-       if (!_config_get_int_value(CONFIG_TYPE_LOGGER_ENABLE))
-               return 0;
-
-       if (!handle || !tag || !format) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       t = time(NULL);
-       localtime_r(&t, &tm);
-
-       if (handle->index != 0)
-               offset = lseek(handle->fd, 0, SEEK_CUR);
-       else
-               offset = lseek(handle->fd, 0, SEEK_SET);
-
-       if (offset == -1)
-               _E("lseek() is failed. errno(%d)", errno);
-
-       va_start(ap, format);
-       bytes = vsnprintf(format_buf, sizeof(format_buf), format, ap);
-       va_end(ap);
-       if (bytes < 0 || bytes >= sizeof(format_buf)) {
-               _E("vsnprintf() is failed. result(%d)", bytes);
-               return -1;
-       }
-
-       snprintf(buf, sizeof(buf),
-                       "[%6d] %04d-%02d-%02d %02d:%02d:%02d %-16s %-100s\n",
-                       handle->index,
-                       tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
-                       tm.tm_hour, tm.tm_min, tm.tm_sec,
-                       tag, format_buf);
-       ret = write(handle->fd, buf, strlen(buf));
-       if (ret < 0) {
-               ret = -errno;
-               _E("Failed to write log message. errno(%d)", errno);
-               return ret;
-       }
-
-       if (++handle->index >= LAUNCHPAD_LOG_MAX_SIZE)
-               handle->index = 0;
-
-       return ret;
-}
-
-int _logger_get_fd(logger_h handle, int *fd)
-{
-       if (!_config_get_int_value(CONFIG_TYPE_LOGGER_ENABLE))
-               return 0;
-
-       if (!handle || !fd) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       *fd = handle->fd;
-
-       return 0;
-}
diff --git a/src/launchpad-process-pool/src/launchpad_logger.cc b/src/launchpad-process-pool/src/launchpad_logger.cc
new file mode 100644 (file)
index 0000000..592d73e
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <linux/limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/smack.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "launchpad_config.h"
+#include "launchpad_logger.h"
+#include "log_private.h"
+
+#define LAUNCHPAD_LOG_APPFW_PATH "/var/log/appfw"
+#define LAUNCHPAD_LOG_PATH "/var/log/appfw/launchpad"
+#define LAUNCHPAD_LOG_MAX_SIZE 2500
+#define LAUNCHPAD_LOG_MAX_BUFFER_SIZE 256
+
+struct logger_s {
+  int fd;
+  int index;
+};
+
+static int __set_smack_label(const char* path, const char* label) {
+  int ret;
+
+  ret = smack_setlabel(path, label, SMACK_LABEL_ACCESS);
+  if (ret != 0) {
+    ret = -errno;
+    _E("smack_setlabel() is failed. path(%s), label(%s), errno(%d)", path,
+       label, errno);
+    return ret;
+  }
+
+  return 0;
+}
+
+static int __create_directory(const char* path) {
+  mode_t mode;
+  int ret;
+
+  ret = access(path, F_OK);
+  if (ret == 0)
+    return 0;
+
+  mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
+  ret = mkdir(path, mode);
+  if (ret < 0) {
+    ret = -errno;
+    _E("Failed to create directory(%s). errno(%d)", path, errno);
+    return ret;
+  }
+
+  return 0;
+}
+
+static int __create_launchpad_directories(void) {
+  const char* logger_path;
+  char path[PATH_MAX];
+  int ret;
+
+  logger_path = _config_get_string_value(CONFIG_TYPE_LOGGER_PATH);
+  ret = __create_directory(logger_path);
+  if (ret < 0)
+    return ret;
+
+  ret = __set_smack_label(logger_path, "User::Home");
+  if (ret < 0)
+    return ret;
+
+  snprintf(path, sizeof(path), "%s/launchpad", logger_path);
+  ret = __create_directory(path);
+  if (ret < 0)
+    return ret;
+
+  ret = __set_smack_label(path, "User");
+  if (ret < 0)
+    return ret;
+
+  return 0;
+}
+
+int _logger_create(const char* path, logger_h* handle) {
+  struct logger_s* logger;
+  off_t offset;
+  int ret;
+
+  if (!_config_get_int_value(CONFIG_TYPE_LOGGER_ENABLE))
+    return 0;
+
+  if (!path || !handle) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  ret = __create_launchpad_directories();
+  if (ret < 0)
+    return ret;
+
+  logger = static_cast<logger_s*>(calloc(1, sizeof(struct logger_s)));
+  if (!logger) {
+    _E("Out of memory");
+    return -ENOMEM;
+  }
+
+  logger->fd = open(path, O_CREAT | O_WRONLY, 0640);
+  if (logger->fd < 0) {
+    ret = -errno;
+    _E("Failed to open path(%s), errno(%d)", path, errno);
+    _logger_destroy(logger);
+    return ret;
+  }
+
+  ret = __set_smack_label(path, "User");
+  if (ret < 0) {
+    _logger_destroy(logger);
+    return ret;
+  }
+
+  offset = lseek(logger->fd, 0, SEEK_END);
+  if (offset != 0) {
+    logger->index = (int)(offset / LAUNCHPAD_LOG_MAX_STRING_SIZE);
+    if (logger->index >= LAUNCHPAD_LOG_MAX_SIZE) {
+      logger->index = 0;
+      lseek(logger->fd, 0, SEEK_SET);
+    }
+  }
+
+  *handle = logger;
+
+  return 0;
+}
+
+int _logger_destroy(logger_h handle) {
+  if (!_config_get_int_value(CONFIG_TYPE_LOGGER_ENABLE))
+    return 0;
+
+  if (!handle) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  if (handle->fd > 0)
+    close(handle->fd);
+
+  free(handle);
+
+  return 0;
+}
+
+int _logger_print(logger_h handle, const char* tag, const char* format, ...) {
+  char buf[LAUNCHPAD_LOG_MAX_BUFFER_SIZE];
+  char format_buf[128];
+  struct tm tm = {
+      0,
+  };
+  time_t t;
+  ssize_t ret;
+  va_list ap;
+  off_t offset;
+  int bytes;
+
+  if (!_config_get_int_value(CONFIG_TYPE_LOGGER_ENABLE))
+    return 0;
+
+  if (!handle || !tag || !format) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  t = time(nullptr);
+  localtime_r(&t, &tm);
+
+  if (handle->index != 0)
+    offset = lseek(handle->fd, 0, SEEK_CUR);
+  else
+    offset = lseek(handle->fd, 0, SEEK_SET);
+
+  if (offset == -1)
+    _E("lseek() is failed. errno(%d)", errno);
+
+  va_start(ap, format);
+  bytes = vsnprintf(format_buf, sizeof(format_buf), format, ap);
+  va_end(ap);
+  if (bytes < 0 || bytes >= sizeof(format_buf)) {
+    _E("vsnprintf() is failed. result(%d)", bytes);
+    return -1;
+  }
+
+  snprintf(buf, sizeof(buf),
+           "[%6d] %04d-%02d-%02d %02d:%02d:%02d %-16s %-100s\n", handle->index,
+           tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
+           tm.tm_sec, tag, format_buf);
+  ret = write(handle->fd, buf, strlen(buf));
+  if (ret < 0) {
+    ret = -errno;
+    _E("Failed to write log message. errno(%d)", errno);
+    return ret;
+  }
+
+  if (++handle->index >= LAUNCHPAD_LOG_MAX_SIZE)
+    handle->index = 0;
+
+  return ret;
+}
+
+int _logger_get_fd(logger_h handle, int* fd) {
+  if (!_config_get_int_value(CONFIG_TYPE_LOGGER_ENABLE))
+    return 0;
+
+  if (!handle || !fd) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  *fd = handle->fd;
+
+  return 0;
+}
diff --git a/src/launchpad-process-pool/src/launchpad_memory_monitor.c b/src/launchpad-process-pool/src/launchpad_memory_monitor.c
deleted file mode 100644 (file)
index d4d4b2d..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#include "launchpad_config.h"
-#include "launchpad_memory_monitor.h"
-#include "launchpad_proc.h"
-#include "log_private.h"
-
-#define INTERVAL_BASE_RATE 0.15f
-
-struct memory_monitor_s {
-       unsigned int threshold;
-       unsigned int prev_used_ratio;
-       unsigned int base_interval;
-       unsigned int interval;
-       bool low_memory;
-       guint tag;
-       memory_monitor_cb callback;
-       void *user_data;
-};
-
-static struct memory_monitor_s __monitor;
-
-static void __memory_monitor_start(void);
-
-static gboolean __memory_check_cb(gpointer data)
-{
-       bool low_memory;
-
-       __monitor.tag = 0;
-       low_memory = _memory_monitor_is_low_memory();
-       if (__monitor.low_memory != low_memory && __monitor.callback)
-               __monitor.callback(low_memory, __monitor.user_data);
-
-       __monitor.low_memory = low_memory;
-       __memory_monitor_start();
-
-       return G_SOURCE_REMOVE;
-}
-
-static void __memory_monitor_stop(void)
-{
-       if (!__monitor.tag)
-               return;
-
-       g_source_remove(__monitor.tag);
-       __monitor.tag = 0;
-}
-
-static void __memory_monitor_start(void)
-{
-       if (__monitor.threshold == 100)
-               return;
-
-       if (__monitor.tag)
-               return;
-
-       __monitor.tag = g_timeout_add(__monitor.interval,
-                       __memory_check_cb, NULL);
-
-       __monitor.interval += __monitor.interval * INTERVAL_BASE_RATE;
-}
-
-int _memory_monitor_reset_timer(void)
-{
-       _W("Reset");
-       __monitor.interval = __monitor.base_interval;
-
-       __memory_monitor_stop();
-       __memory_monitor_start();
-
-       return 0;
-}
-
-bool _memory_monitor_is_low_memory(void)
-{
-       unsigned int mem_used_ratio = 0;
-
-       if (__monitor.threshold == 100)
-               return false;
-
-       _proc_get_mem_used_ratio(&mem_used_ratio);
-
-       _W("previous used ratio(%u), current used ratio(%u)",
-                       __monitor.prev_used_ratio, mem_used_ratio);
-
-       __monitor.prev_used_ratio = mem_used_ratio;
-
-       if (mem_used_ratio > __monitor.threshold)
-               return true;
-
-       return false;
-}
-
-int _memory_monitor_set_event_cb(memory_monitor_cb callback, void *user_data)
-{
-       __monitor.callback = callback;
-       __monitor.user_data = user_data;
-
-       return 0;
-}
-
-int _memory_monitor_init(void)
-{
-       int ret;
-
-       _W("MEMORY_MONITOR_INIT");
-
-       __monitor.threshold = _config_get_int_value(
-                       CONFIG_TYPE_MEMORY_MONITOR_THRESHOLD);
-       __monitor.base_interval = _config_get_int_value(
-                       CONFIG_TYPE_MEMORY_MONITOR_INTERVAL);
-       __monitor.interval = __monitor.base_interval;
-
-       ret = _proc_get_mem_used_ratio(&__monitor.prev_used_ratio);
-       if (ret != 0) {
-               _E("Failed to get mem used ratio. error(%d)", ret);
-               return ret;
-       }
-
-       __memory_monitor_start();
-
-       return 0;
-}
-
-void _memory_monitor_fini(void)
-{
-       _W("MEMORY_MONITOR_FINI");
-
-       __memory_monitor_stop();
-}
diff --git a/src/launchpad-process-pool/src/launchpad_memory_monitor.cc b/src/launchpad-process-pool/src/launchpad_memory_monitor.cc
new file mode 100644 (file)
index 0000000..d2b60ca
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "launchpad_config.h"
+#include "launchpad_memory_monitor.h"
+#include "launchpad_proc.h"
+#include "log_private.h"
+
+#define INTERVAL_BASE_RATE 0.15f
+
+struct memory_monitor_s {
+  unsigned int threshold;
+  unsigned int prev_used_ratio;
+  unsigned int base_interval;
+  unsigned int interval;
+  bool low_memory;
+  guint tag;
+  memory_monitor_cb callback;
+  void* user_data;
+};
+
+static struct memory_monitor_s __monitor;
+
+static void __memory_monitor_start(void);
+
+static gboolean __memory_check_cb(gpointer data) {
+  bool low_memory;
+
+  __monitor.tag = 0;
+  low_memory = _memory_monitor_is_low_memory();
+  if (__monitor.low_memory != low_memory && __monitor.callback)
+    __monitor.callback(low_memory, __monitor.user_data);
+
+  __monitor.low_memory = low_memory;
+  __memory_monitor_start();
+
+  return G_SOURCE_REMOVE;
+}
+
+static void __memory_monitor_stop(void) {
+  if (!__monitor.tag)
+    return;
+
+  g_source_remove(__monitor.tag);
+  __monitor.tag = 0;
+}
+
+static void __memory_monitor_start(void) {
+  if (__monitor.threshold == 100)
+    return;
+
+  if (__monitor.tag)
+    return;
+
+  __monitor.tag = g_timeout_add(__monitor.interval, __memory_check_cb, NULL);
+
+  __monitor.interval += __monitor.interval * INTERVAL_BASE_RATE;
+}
+
+int _memory_monitor_reset_timer(void) {
+  _W("Reset");
+  __monitor.interval = __monitor.base_interval;
+
+  __memory_monitor_stop();
+  __memory_monitor_start();
+
+  return 0;
+}
+
+bool _memory_monitor_is_low_memory(void) {
+  unsigned int mem_used_ratio = 0;
+
+  if (__monitor.threshold == 100)
+    return false;
+
+  _proc_get_mem_used_ratio(&mem_used_ratio);
+
+  _W("previous used ratio(%u), current used ratio(%u)",
+     __monitor.prev_used_ratio, mem_used_ratio);
+
+  __monitor.prev_used_ratio = mem_used_ratio;
+
+  if (mem_used_ratio > __monitor.threshold)
+    return true;
+
+  return false;
+}
+
+int _memory_monitor_set_event_cb(memory_monitor_cb callback, void* user_data) {
+  __monitor.callback = callback;
+  __monitor.user_data = user_data;
+
+  return 0;
+}
+
+int _memory_monitor_init(void) {
+  int ret;
+
+  _W("MEMORY_MONITOR_INIT");
+
+  __monitor.threshold =
+      _config_get_int_value(CONFIG_TYPE_MEMORY_MONITOR_THRESHOLD);
+  __monitor.base_interval =
+      _config_get_int_value(CONFIG_TYPE_MEMORY_MONITOR_INTERVAL);
+  __monitor.interval = __monitor.base_interval;
+
+  ret = _proc_get_mem_used_ratio(&__monitor.prev_used_ratio);
+  if (ret != 0) {
+    _E("Failed to get mem used ratio. error(%d)", ret);
+    return ret;
+  }
+
+  __memory_monitor_start();
+
+  return 0;
+}
+
+void _memory_monitor_fini(void) {
+  _W("MEMORY_MONITOR_FINI");
+
+  __memory_monitor_stop();
+}
diff --git a/src/launchpad-process-pool/src/launchpad_signal.c b/src/launchpad-process-pool/src/launchpad_signal.c
deleted file mode 100644 (file)
index 6212ca4..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (c) 2015 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <dirent.h>
-#include <gio/gio.h>
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/signalfd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "launchpad_common.h"
-#include "launchpad_dbus.h"
-#include "launchpad_io_channel.h"
-#include "launchpad_proc.h"
-#include "launchpad_signal.h"
-#include "launchpad_socket.h"
-#include "log_private.h"
-
-#define HYDRA_SIGCHLD_SOCK          ".hydra-sigchld-sock"
-
-static pid_t __pid;
-static sigset_t __mask;
-static sigset_t __old_mask;
-static socket_h __sigchld_socket;
-static io_channel_h __sigchld_channel;
-static socket_h __hydra_sigchld_socket;
-static io_channel_h __hydra_sigchld_channel;
-static signal_sigchld_cb __callback;
-static void *__user_data;
-
-static gboolean __hydra_sigchld_recovery_cb(gpointer data);
-static gboolean __sigchld_recovery_cb(gpointer data);
-
-static void __socket_garbage_collector(void)
-{
-       DIR *dp;
-       struct dirent *dentry = NULL;
-       char path[PATH_MAX];
-
-       snprintf(path, sizeof(path), "/run/aul/apps/%d", getuid());
-       dp = opendir(path);
-       if (!dp)
-               return;
-
-       while ((dentry = readdir(dp)) != NULL) {
-               if (!isdigit(dentry->d_name[0]))
-                       continue;
-
-               snprintf(path, sizeof(path), "/proc/%s", dentry->d_name);
-               if (access(path, F_OK) < 0)
-                       _delete_sock_path(atoi(dentry->d_name), getuid());
-       }
-       closedir(dp);
-}
-
-static void __sigchld_action(int pid)
-{
-       _dbus_send_app_dead_signal(pid);
-       _delete_sock_path(pid, getuid());
-       __socket_garbage_collector();
-}
-
-static int __check_permission(int pid)
-{
-       char buf[512] = { 0, };
-       int ret;
-
-       ret = _proc_get_attr(pid, buf, sizeof(buf));
-       if (ret < 0)
-               return -1;
-
-       if (!strcmp(buf, "User") ||
-                       !strcmp(buf, "System") ||
-                       !strcmp(buf, "System::Privileged"))
-               return 0;
-
-       _E("Permission denied. peer(%d:%s)", pid, buf);
-       return -1;
-}
-
-static bool __hydra_sigchld_handler(int fd, io_condition_e cond,
-               void *user_data)
-{
-       socket_h client_socket;
-       int caller_pid;
-       int pid = -1;
-       int ret;
-
-       if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
-               _E("fd(%d), io_condition(%d)", fd, cond);
-               g_idle_add(__hydra_sigchld_recovery_cb, NULL);
-               return false;
-       }
-
-       ret = _socket_accept(__hydra_sigchld_socket, &client_socket);
-       if (ret < 0)
-               return true;
-
-       _socket_get_pid(client_socket, &caller_pid);
-       ret = __check_permission(caller_pid);
-       if (ret < 0) {
-               _socket_destroy(client_socket);
-               return true;
-       }
-
-       ret = _socket_read(client_socket, &pid, sizeof(pid));
-       _socket_destroy(client_socket);
-       if (ret < 0) {
-               _E("Failed to read process id. ret(%d)", ret);
-               return true;
-       }
-
-       _W("[__SIGCHLD__] pid(%d)", pid);
-       __sigchld_action(pid);
-
-       if (__callback)
-               __callback(pid, user_data);
-
-       return true;
-}
-
-static int __hydra_sigchld_init(void)
-{
-       char path[LAUNCHPAD_SOCKET_PATH_SIZE];
-       io_channel_h channel;
-       io_condition_e cond;
-       socket_h socket;
-       int ret;
-       int fd;
-
-       snprintf(path, sizeof(path), "/run/aul/daemons/%u/%s",
-                       getuid(), HYDRA_SIGCHLD_SOCK);
-       ret = _socket_create(path, false, &socket);
-       if (ret < 0)
-               return ret;
-
-       _socket_get_fd(socket, &fd);
-
-       cond = IO_IN | IO_PRI | IO_ERR | IO_HUP | IO_NVAL;
-       channel = _io_channel_create(fd, cond,
-                       __hydra_sigchld_handler, NULL);
-       if (!channel) {
-               _socket_destroy(socket);
-               return -ENOMEM;
-       }
-
-       _io_channel_set_close_on_destroy(channel, false);
-
-       __hydra_sigchld_socket = socket;
-       __hydra_sigchld_channel = channel;
-
-       return 0;
-}
-
-static int __hydra_sigchld_fini(void)
-{
-       if (__hydra_sigchld_channel)
-               _io_channel_destroy(__hydra_sigchld_channel);
-
-       if (__hydra_sigchld_socket) {
-               if (__pid != getpid())
-                       _socket_set_fd(__hydra_sigchld_socket, -1);
-
-               _socket_destroy(__hydra_sigchld_socket);
-       }
-
-       return 0;
-}
-
-static bool __sigchld_handler(int fd, io_condition_e cond, void *user_data)
-{
-       struct signalfd_siginfo info;
-       pid_t child_pid;
-       pid_t child_pgid;
-       int status;
-       int ret;
-
-       if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
-               _E("fd(%d), io_condition(%d)", fd, cond);
-               g_idle_add(__sigchld_recovery_cb, NULL);
-               return false;
-       }
-
-       do {
-               ret = _socket_read(__sigchld_socket, &info, sizeof(info));
-               if (ret < 0)
-                       break;
-
-               child_pgid = getpgid(info.ssi_pid);
-               _W("[__SIGCHLD__] pid(%d), pgid(%d), status(%d)",
-                               info.ssi_pid, child_pgid, info.ssi_status);
-
-               while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
-                       if (child_pid == child_pgid)
-                               killpg(child_pgid, SIGKILL);
-
-                       __sigchld_action(child_pid);
-               }
-
-               if (__callback)
-                       __callback(info.ssi_pid, __user_data);
-       } while (ret == 0);
-
-       return true;
-}
-
-static int __signal_block_sigchld(void)
-{
-       int ret;
-
-       sigemptyset(&__mask);
-       sigaddset(&__mask, SIGCHLD);
-
-       ret = sigprocmask(SIG_BLOCK, &__mask, &__old_mask);
-       if (ret < 0) {
-               ret = -errno;
-               _E("sigprocmask(SIG_BLOCK) is failed. errno(%d)", errno);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int __signal_get_sigchld_fd(void)
-{
-       int sfd;
-
-       sfd = signalfd(-1, &__mask, SFD_NONBLOCK | SFD_CLOEXEC);
-       if (sfd < 0) {
-               sfd = -errno;
-               _E("signalfd() is failed. errno(%d)", errno);
-               return sfd;
-       }
-
-       return sfd;
-}
-
-int _signal_unblock_sigchld(void)
-{
-       int ret;
-
-       ret = sigprocmask(SIG_SETMASK, &__old_mask, NULL);
-       if (ret < 0) {
-               ret = -errno;
-               _E("sigprocmask(SIG_SETMASK) is failed. errno(%d)", errno);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int __sigchld_init(void)
-{
-       io_channel_h channel;
-       io_condition_e cond;
-       socket_h socket;
-       int sfd;
-       int ret;
-
-       sfd = __signal_get_sigchld_fd();
-       if (sfd < 0)
-               return sfd;
-
-       ret = _socket_create_with_fd(sfd, &socket);
-       if (ret < 0) {
-               close(sfd);
-               return ret;
-       }
-
-       cond = IO_IN | IO_PRI | IO_ERR | IO_HUP | IO_NVAL;
-       channel = _io_channel_create(sfd, cond,
-                       __sigchld_handler, NULL);
-       if (!channel) {
-               _socket_destroy(socket);
-               return -ENOMEM;
-       }
-       _io_channel_set_close_on_destroy(channel, false);
-
-       __sigchld_socket = socket;
-       __sigchld_channel = channel;
-
-       return 0;
-}
-
-static int __sigchld_fini(void)
-{
-       if (__sigchld_channel)
-               _io_channel_destroy(__sigchld_channel);
-
-       if (__sigchld_socket) {
-               if (__pid != getpid())
-                       _socket_set_fd(__sigchld_socket, -1);
-
-               _socket_destroy(__sigchld_socket);
-       }
-
-       return 0;
-}
-
-int _signal_set_sigchld_cb(signal_sigchld_cb callback, void *user_data)
-{
-       __callback = callback;
-       __user_data = user_data;
-
-       return 0;
-}
-
-static gboolean __hydra_sigchld_recovery_cb(gpointer data)
-{
-       int ret;
-
-       __hydra_sigchld_fini();
-
-       ret = __hydra_sigchld_init();
-       if (ret < 0) {
-               _E("Failed to recover hydra sigchld socket");
-               abort();
-       } else {
-               _W("[__RECOVERY__] Hydra SIGCHLD Socket");
-       }
-
-       return G_SOURCE_REMOVE;
-}
-
-static gboolean __sigchld_recovery_cb(gpointer data)
-{
-       int ret;
-
-       __sigchld_fini();
-
-       ret = __sigchld_init();
-       if (ret < 0) {
-               _E("Failed to recover sigchld fd");
-               abort();
-       } else {
-               _W("[__RECOVERY__] SIGCHLD fd");
-       }
-
-       return G_SOURCE_REMOVE;
-}
-
-int _signal_init(void)
-{
-       int ret;
-       int i;
-
-       _D("SIGNAL_INIT");
-       __pid = getpid();
-
-       ret = __signal_block_sigchld();
-       if (ret < 0)
-               return ret;
-
-       ret = __sigchld_init();
-       if (ret < 0)
-               return ret;
-
-       ret = __hydra_sigchld_init();
-       if (ret < 0)
-               return ret;
-
-       for (i = 0; i < _NSIG; ++i) {
-               switch (i) {
-               /* controlled by sys-assert package*/
-               case SIGQUIT:
-               case SIGILL:
-               case SIGABRT:
-               case SIGBUS:
-               case SIGFPE:
-               case SIGSEGV:
-               case SIGPIPE:
-                       break;
-               default:
-                       signal(i, SIG_DFL);
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-void _signal_fini(void)
-{
-#ifndef PRELOAD_ACTIVATE
-       int i;
-
-       for (i = 0; i < _NSIG; ++i)
-               signal(i, SIG_DFL);
-#endif
-
-       _D("SIGNAL_FINI");
-       _signal_set_sigchld_cb(NULL, NULL);
-       __hydra_sigchld_fini();
-       __sigchld_fini();
-       _signal_unblock_sigchld();
-}
diff --git a/src/launchpad-process-pool/src/launchpad_signal.cc b/src/launchpad-process-pool/src/launchpad_signal.cc
new file mode 100644 (file)
index 0000000..ca305b0
--- /dev/null
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2015 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+#include <gio/gio.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/signalfd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "launchpad_common.h"
+#include "launchpad_dbus.h"
+#include "launchpad_io_channel.h"
+#include "launchpad_proc.h"
+#include "launchpad_signal.h"
+#include "launchpad_socket.h"
+#include "log_private.h"
+
+#define HYDRA_SIGCHLD_SOCK ".hydra-sigchld-sock"
+
+static pid_t __pid;
+static sigset_t __mask;
+static sigset_t __old_mask;
+static socket_h __sigchld_socket;
+static io_channel_h __sigchld_channel;
+static socket_h __hydra_sigchld_socket;
+static io_channel_h __hydra_sigchld_channel;
+static signal_sigchld_cb __callback;
+static void* __user_data;
+
+static gboolean __hydra_sigchld_recovery_cb(gpointer data);
+static gboolean __sigchld_recovery_cb(gpointer data);
+
+static void __socket_garbage_collector(void) {
+  DIR* dp;
+  struct dirent* dentry = nullptr;
+  char path[PATH_MAX];
+
+  snprintf(path, sizeof(path), "/run/aul/apps/%d", getuid());
+  dp = opendir(path);
+  if (!dp)
+    return;
+
+  while ((dentry = readdir(dp)) != nullptr) {
+    if (!isdigit(dentry->d_name[0]))
+      continue;
+
+    snprintf(path, sizeof(path), "/proc/%s", dentry->d_name);
+    if (access(path, F_OK) < 0)
+      _delete_sock_path(atoi(dentry->d_name), getuid());
+  }
+  closedir(dp);
+}
+
+static void __sigchld_action(int pid) {
+  _dbus_send_app_dead_signal(pid);
+  _delete_sock_path(pid, getuid());
+  __socket_garbage_collector();
+}
+
+static int __check_permission(int pid) {
+  char buf[512] = {
+      0,
+  };
+  int ret;
+
+  ret = _proc_get_attr(pid, buf, sizeof(buf));
+  if (ret < 0)
+    return -1;
+
+  if (!strcmp(buf, "User") || !strcmp(buf, "System") ||
+      !strcmp(buf, "System::Privileged"))
+    return 0;
+
+  _E("Permission denied. peer(%d:%s)", pid, buf);
+  return -1;
+}
+
+static bool __hydra_sigchld_handler(int fd,
+                                    io_condition_e cond,
+                                    void* user_data) {
+  socket_h client_socket;
+  int caller_pid;
+  int pid = -1;
+  int ret;
+
+  if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
+    _E("fd(%d), io_condition(%d)", fd, cond);
+    g_idle_add(__hydra_sigchld_recovery_cb, nullptr);
+    return false;
+  }
+
+  ret = _socket_accept(__hydra_sigchld_socket, &client_socket);
+  if (ret < 0)
+    return true;
+
+  _socket_get_pid(client_socket, &caller_pid);
+  ret = __check_permission(caller_pid);
+  if (ret < 0) {
+    _socket_destroy(client_socket);
+    return true;
+  }
+
+  ret = _socket_read(client_socket, &pid, sizeof(pid));
+  _socket_destroy(client_socket);
+  if (ret < 0) {
+    _E("Failed to read process id. ret(%d)", ret);
+    return true;
+  }
+
+  _W("[__SIGCHLD__] pid(%d)", pid);
+  __sigchld_action(pid);
+
+  if (__callback)
+    __callback(pid, user_data);
+
+  return true;
+}
+
+static int __hydra_sigchld_init(void) {
+  char path[LAUNCHPAD_SOCKET_PATH_SIZE];
+  io_channel_h channel;
+  socket_h socket;
+  int ret;
+  int fd;
+
+  snprintf(path, sizeof(path), "/run/aul/daemons/%u/%s", getuid(),
+           HYDRA_SIGCHLD_SOCK);
+  ret = _socket_create(path, false, &socket);
+  if (ret < 0)
+    return ret;
+
+  _socket_get_fd(socket, &fd);
+
+  auto cond = IO_IN | IO_PRI | IO_ERR | IO_HUP | IO_NVAL;
+  channel = _io_channel_create(fd, static_cast<io_condition_e>(cond),
+                               __hydra_sigchld_handler, nullptr);
+  if (!channel) {
+    _socket_destroy(socket);
+    return -ENOMEM;
+  }
+
+  _io_channel_set_close_on_destroy(channel, false);
+
+  __hydra_sigchld_socket = socket;
+  __hydra_sigchld_channel = channel;
+
+  return 0;
+}
+
+static int __hydra_sigchld_fini(void) {
+  if (__hydra_sigchld_channel)
+    _io_channel_destroy(__hydra_sigchld_channel);
+
+  if (__hydra_sigchld_socket) {
+    if (__pid != getpid())
+      _socket_set_fd(__hydra_sigchld_socket, -1);
+
+    _socket_destroy(__hydra_sigchld_socket);
+  }
+
+  return 0;
+}
+
+static bool __sigchld_handler(int fd, io_condition_e cond, void* user_data) {
+  struct signalfd_siginfo info;
+  pid_t child_pid;
+  pid_t child_pgid;
+  int status;
+  int ret;
+
+  if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
+    _E("fd(%d), io_condition(%d)", fd, cond);
+    g_idle_add(__sigchld_recovery_cb, nullptr);
+    return false;
+  }
+
+  do {
+    ret = _socket_read(__sigchld_socket, &info, sizeof(info));
+    if (ret < 0)
+      break;
+
+    child_pgid = getpgid(info.ssi_pid);
+    _W("[__SIGCHLD__] pid(%d), pgid(%d), status(%d)", info.ssi_pid, child_pgid,
+       info.ssi_status);
+
+    while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
+      if (child_pid == child_pgid)
+        killpg(child_pgid, SIGKILL);
+
+      __sigchld_action(child_pid);
+    }
+
+    if (__callback)
+      __callback(info.ssi_pid, __user_data);
+  } while (ret == 0);
+
+  return true;
+}
+
+static int __signal_block_sigchld(void) {
+  int ret;
+
+  sigemptyset(&__mask);
+  sigaddset(&__mask, SIGCHLD);
+
+  ret = sigprocmask(SIG_BLOCK, &__mask, &__old_mask);
+  if (ret < 0) {
+    ret = -errno;
+    _E("sigprocmask(SIG_BLOCK) is failed. errno(%d)", errno);
+    return ret;
+  }
+
+  return 0;
+}
+
+static int __signal_get_sigchld_fd(void) {
+  int sfd;
+
+  sfd = signalfd(-1, &__mask, SFD_NONBLOCK | SFD_CLOEXEC);
+  if (sfd < 0) {
+    sfd = -errno;
+    _E("signalfd() is failed. errno(%d)", errno);
+    return sfd;
+  }
+
+  return sfd;
+}
+
+int _signal_unblock_sigchld(void) {
+  int ret;
+
+  ret = sigprocmask(SIG_SETMASK, &__old_mask, nullptr);
+  if (ret < 0) {
+    ret = -errno;
+    _E("sigprocmask(SIG_SETMASK) is failed. errno(%d)", errno);
+    return ret;
+  }
+
+  return 0;
+}
+
+static int __sigchld_init(void) {
+  io_channel_h channel;
+  socket_h socket;
+  int sfd;
+  int ret;
+
+  sfd = __signal_get_sigchld_fd();
+  if (sfd < 0)
+    return sfd;
+
+  ret = _socket_create_with_fd(sfd, &socket);
+  if (ret < 0) {
+    close(sfd);
+    return ret;
+  }
+
+  auto cond = IO_IN | IO_PRI | IO_ERR | IO_HUP | IO_NVAL;
+  channel = _io_channel_create(sfd, static_cast<io_condition_e>(cond),
+                               __sigchld_handler, nullptr);
+  if (!channel) {
+    _socket_destroy(socket);
+    return -ENOMEM;
+  }
+  _io_channel_set_close_on_destroy(channel, false);
+
+  __sigchld_socket = socket;
+  __sigchld_channel = channel;
+
+  return 0;
+}
+
+static int __sigchld_fini(void) {
+  if (__sigchld_channel)
+    _io_channel_destroy(__sigchld_channel);
+
+  if (__sigchld_socket) {
+    if (__pid != getpid())
+      _socket_set_fd(__sigchld_socket, -1);
+
+    _socket_destroy(__sigchld_socket);
+  }
+
+  return 0;
+}
+
+int _signal_set_sigchld_cb(signal_sigchld_cb callback, void* user_data) {
+  __callback = callback;
+  __user_data = user_data;
+
+  return 0;
+}
+
+static gboolean __hydra_sigchld_recovery_cb(gpointer data) {
+  int ret;
+
+  __hydra_sigchld_fini();
+
+  ret = __hydra_sigchld_init();
+  if (ret < 0) {
+    _E("Failed to recover hydra sigchld socket");
+    abort();
+  } else {
+    _W("[__RECOVERY__] Hydra SIGCHLD Socket");
+  }
+
+  return G_SOURCE_REMOVE;
+}
+
+static gboolean __sigchld_recovery_cb(gpointer data) {
+  int ret;
+
+  __sigchld_fini();
+
+  ret = __sigchld_init();
+  if (ret < 0) {
+    _E("Failed to recover sigchld fd");
+    abort();
+  } else {
+    _W("[__RECOVERY__] SIGCHLD fd");
+  }
+
+  return G_SOURCE_REMOVE;
+}
+
+int _signal_init(void) {
+  int ret;
+  int i;
+
+  _D("SIGNAL_INIT");
+  __pid = getpid();
+
+  ret = __signal_block_sigchld();
+  if (ret < 0)
+    return ret;
+
+  ret = __sigchld_init();
+  if (ret < 0)
+    return ret;
+
+  ret = __hydra_sigchld_init();
+  if (ret < 0)
+    return ret;
+
+  for (i = 0; i < _NSIG; ++i) {
+    switch (i) {
+      /* controlled by sys-assert package*/
+      case SIGQUIT:
+      case SIGILL:
+      case SIGABRT:
+      case SIGBUS:
+      case SIGFPE:
+      case SIGSEGV:
+      case SIGPIPE:
+        break;
+      default:
+        signal(i, SIG_DFL);
+        break;
+    }
+  }
+
+  return 0;
+}
+
+void _signal_fini(void) {
+#ifndef PRELOAD_ACTIVATE
+  int i;
+
+  for (i = 0; i < _NSIG; ++i)
+    signal(i, SIG_DFL);
+#endif
+
+  _D("SIGNAL_FINI");
+  _signal_set_sigchld_cb(nullptr, nullptr);
+  __hydra_sigchld_fini();
+  __sigchld_fini();
+  _signal_unblock_sigchld();
+}
diff --git a/src/launchpad-process-pool/src/launchpad_worker.c b/src/launchpad-process-pool/src/launchpad_worker.c
deleted file mode 100644 (file)
index 019e4a2..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <errno.h>
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "launchpad_worker.h"
-#include "log_private.h"
-
-struct job_s {
-       worker_job_cb callback;
-       void *user_data;
-};
-
-struct worker_s {
-       char *name;
-       GThread *thread;
-       GMutex mutex;
-       GCond cond;
-       GQueue *queue;
-};
-
-int _worker_add_job(worker_h worker, worker_job_cb callback, void *user_data)
-{
-       struct job_s *job;
-
-       if (!worker || !callback) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       job = malloc(sizeof(struct job_s));
-       if (!job) {
-               _E("Out of memory");
-               return -ENOMEM;
-       }
-
-       job->callback = callback;
-       job->user_data = user_data;
-
-       g_mutex_lock(&worker->mutex);
-       g_queue_push_tail(worker->queue, job);
-       g_cond_signal(&worker->cond);
-       g_mutex_unlock(&worker->mutex);
-
-       return 0;
-}
-
-static int __set_comm(const char *name)
-{
-       int fd;
-       ssize_t bytes_written;
-       char path[PATH_MAX];
-       pid_t tid = syscall(__NR_gettid);
-
-       _I("[%s] TID(%d)", name, tid);
-       snprintf(path, sizeof(path), "/proc/%d/comm", tid);
-       fd = open(path, O_WRONLY);
-       if (fd < 0) {
-               _E("Failed to open %s. error(%d)", path, errno);
-               return -1;
-       }
-
-       bytes_written = write(fd, name, strlen(name) + 1);
-       if (bytes_written < 0) {
-               _E("Failed to write name(%s)", name);
-               close(fd);
-               return -1;
-       }
-
-       close(fd);
-       return 0;
-}
-
-static gpointer __worker_thread_cb(gpointer data)
-{
-       struct worker_s *worker = (struct worker_s *)data;
-       struct job_s *job;
-       bool done = false;
-
-       __set_comm(worker->name);
-       do {
-               g_mutex_lock(&worker->mutex);
-               if (g_queue_is_empty(worker->queue))
-                       g_cond_wait(&worker->cond, &worker->mutex);
-
-               job = (struct job_s *)g_queue_pop_head(worker->queue);
-               g_mutex_unlock(&worker->mutex);
-               done = job->callback(job->user_data);
-               free(job);
-       } while (!done);
-
-       return NULL;
-}
-
-int _worker_create(const char *name, worker_h *worker)
-{
-       struct worker_s *handle;
-
-       if (name == NULL || worker == NULL) {
-               _E("Invalid parameter");
-               return -EINVAL;
-       }
-
-       handle = calloc(1, sizeof(struct worker_s));
-       if (handle == NULL) {
-               _E("calloc() is failed");
-               return -ENOMEM;
-       }
-
-       g_mutex_init(&handle->mutex);
-       g_cond_init(&handle->cond);
-
-       handle->name = strdup(name);
-       if (!handle->name) {
-               _E("strdup() is failed");
-               _worker_destroy(handle);
-               return -ENOMEM;
-       }
-
-       handle->queue = g_queue_new();
-       if (!handle->queue) {
-               _E("g_queue_new() is failed");
-               _worker_destroy(handle);
-               return -ENOMEM;
-       }
-
-       handle->thread = g_thread_new(name, __worker_thread_cb, handle);
-       if (!handle->thread) {
-               _E("g_thread_new() is failed");
-               _worker_destroy(handle);
-               return -ENOMEM;
-       }
-
-       *worker = handle;
-       return 0;
-}
-
-static bool __worker_done_cb(void *user_data)
-{
-       _W("Done");
-       return true;
-}
-
-void _worker_destroy(worker_h worker)
-{
-       if (worker == NULL)
-               return;
-
-       if (worker->thread) {
-               _worker_add_job(worker, __worker_done_cb, NULL);
-               g_thread_join(worker->thread);
-       }
-
-       if (worker->queue)
-               g_queue_free_full(worker->queue, (GDestroyNotify)free);
-
-       if (worker->name)
-               free(worker->name);
-
-       g_cond_clear(&worker->cond);
-       g_mutex_clear(&worker->mutex);
-       free(worker);
-}
diff --git a/src/launchpad-process-pool/src/launchpad_worker.cc b/src/launchpad-process-pool/src/launchpad_worker.cc
new file mode 100644 (file)
index 0000000..15b53a5
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "launchpad_worker.h"
+#include "log_private.h"
+
+struct job_s {
+  worker_job_cb callback;
+  void* user_data;
+};
+
+struct worker_s {
+  char* name;
+  GThread* thread;
+  GMutex mutex;
+  GCond cond;
+  GQueue* queue;
+};
+
+int _worker_add_job(worker_h worker, worker_job_cb callback, void* user_data) {
+  struct job_s* job;
+
+  if (!worker || !callback) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  job = static_cast<job_s*>(malloc(sizeof(job_s)));
+  if (!job) {
+    _E("Out of memory");
+    return -ENOMEM;
+  }
+
+  job->callback = callback;
+  job->user_data = user_data;
+
+  g_mutex_lock(&worker->mutex);
+  g_queue_push_tail(worker->queue, job);
+  g_cond_signal(&worker->cond);
+  g_mutex_unlock(&worker->mutex);
+
+  return 0;
+}
+
+static int __set_comm(const char* name) {
+  int fd;
+  ssize_t bytes_written;
+  char path[PATH_MAX];
+  pid_t tid = syscall(__NR_gettid);
+
+  _I("[%s] TID(%d)", name, tid);
+  snprintf(path, sizeof(path), "/proc/%d/comm", tid);
+  fd = open(path, O_WRONLY);
+  if (fd < 0) {
+    _E("Failed to open %s. error(%d)", path, errno);
+    return -1;
+  }
+
+  bytes_written = write(fd, name, strlen(name) + 1);
+  if (bytes_written < 0) {
+    _E("Failed to write name(%s)", name);
+    close(fd);
+    return -1;
+  }
+
+  close(fd);
+  return 0;
+}
+
+static gpointer __worker_thread_cb(gpointer data) {
+  struct worker_s* worker = (struct worker_s*)data;
+  struct job_s* job;
+  bool done = false;
+
+  __set_comm(worker->name);
+  do {
+    g_mutex_lock(&worker->mutex);
+    if (g_queue_is_empty(worker->queue))
+      g_cond_wait(&worker->cond, &worker->mutex);
+
+    job = (struct job_s*)g_queue_pop_head(worker->queue);
+    g_mutex_unlock(&worker->mutex);
+    done = job->callback(job->user_data);
+    free(job);
+  } while (!done);
+
+  return NULL;
+}
+
+int _worker_create(const char* name, worker_h* worker) {
+  struct worker_s* handle;
+
+  if (name == NULL || worker == NULL) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  handle = static_cast<worker_s*>(calloc(1, sizeof(worker_s)));
+  if (handle == NULL) {
+    _E("calloc() is failed");
+    return -ENOMEM;
+  }
+
+  g_mutex_init(&handle->mutex);
+  g_cond_init(&handle->cond);
+
+  handle->name = strdup(name);
+  if (!handle->name) {
+    _E("strdup() is failed");
+    _worker_destroy(handle);
+    return -ENOMEM;
+  }
+
+  handle->queue = g_queue_new();
+  if (!handle->queue) {
+    _E("g_queue_new() is failed");
+    _worker_destroy(handle);
+    return -ENOMEM;
+  }
+
+  handle->thread = g_thread_new(name, __worker_thread_cb, handle);
+  if (!handle->thread) {
+    _E("g_thread_new() is failed");
+    _worker_destroy(handle);
+    return -ENOMEM;
+  }
+
+  *worker = handle;
+  return 0;
+}
+
+static bool __worker_done_cb(void* user_data) {
+  _W("Done");
+  return true;
+}
+
+void _worker_destroy(worker_h worker) {
+  if (worker == NULL)
+    return;
+
+  if (worker->thread) {
+    _worker_add_job(worker, __worker_done_cb, NULL);
+    g_thread_join(worker->thread);
+  }
+
+  if (worker->queue)
+    g_queue_free_full(worker->queue, (GDestroyNotify)free);
+
+  if (worker->name)
+    free(worker->name);
+
+  g_cond_clear(&worker->cond);
+  g_mutex_clear(&worker->mutex);
+  free(worker);
+}
diff --git a/src/launchpad-process-pool/src/loader_info.c b/src/launchpad-process-pool/src/loader_info.c
deleted file mode 100644 (file)
index c43986f..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <string.h>
-
-#include "loader_info.h"
-#include "launchpad_common.h"
-
-#define TAG_LOADER                     "[LOADER]"
-#define TAG_NAME                       "NAME"
-#define TAG_EXE                                "EXE"
-#define TAG_APP_TYPE                   "APP_TYPE"
-#define TAG_DETECTION_METHOD           "DETECTION_METHOD"
-#define TAG_ACTIVATION_METHOD          "ACTIVATION_METHOD"
-#define TAG_DEACTIVATION_METHOD                "DEACTIVATION_METHOD"
-#define TAG_TTL                                "TTL"
-#define TAG_TIMEOUT                    "TIMEOUT"
-#define TAG_EXTRA                      "EXTRA"
-#define TAG_EXTRA_ARRAY                        "EXTRA_ARRAY"
-#define TAG_EXTRA_ARRAY_VAL            "EXTRA_ARRAY_VAL"
-#define TAG_ALTERNATIVE_LOADER         "ALTERNATIVE_LOADER"
-#define TAG_HW_ACC                     "HW_ACC"
-#define TAG_CPU_THRESHOLD_MAX          "CPU_THRESHOLD_MAX"
-#define TAG_CPU_THRESHOLD_MIN          "CPU_THRESHOLD_MIN"
-#define TAG_ON_BOOT                    "ON_BOOT"
-#define TAG_HYDRA                      "HYDRA"
-#define TAG_APP_CHECK                   "APP_CHECK"
-#define TAG_ON_BOOT_TIMEOUT             "ON_BOOT_TIMEOUT"
-#define TAG_SCHED_PRIORITY             "SCHED_PRIORITY"
-
-#define VAL_ON                         "ON"
-#define VAL_OFF                                "OFF"
-#define VAL_METHOD_TIMEOUT             "TIMEOUT"
-#define VAL_METHOD_DEMAND              "DEMAND"
-#define VAL_METHOD_VISIBILITY          "VISIBILITY"
-#define VAL_METHOD_REQUEST             "REQUEST"
-#define VAL_METHOD_AVAILABLE_MEMORY    "AVAILABLE_MEMORY"
-#define VAL_METHOD_TTL                 "TTL"
-#define VAL_METHOD_OUT_OF_MEMORY       "OUT_OF_MEMORY"
-
-static int __comp_name(gconstpointer a, gconstpointer b);
-static void __free_info(gpointer data);
-
-static loader_info_t *__create_loader_info()
-{
-       loader_info_t *info;
-
-       info = calloc(1, sizeof(loader_info_t));
-       if (info == NULL) {
-               _E("Out of memory");
-               return NULL;
-       }
-
-       info->type = 0;
-       info->name = NULL;
-       info->exe = NULL;
-       info->app_types = NULL;
-       info->hw_acc = NULL;
-       info->alternative_loaders = NULL;
-       info->detection_method = METHOD_TIMEOUT | METHOD_VISIBILITY |
-               METHOD_INSTALL;
-       info->timeout_val = 5000;
-       info->extra = bundle_create();
-       info->cpu_threshold_max = DEFAULT_CPU_THRESHOLD_MAX;
-       info->cpu_threshold_min = DEFAULT_CPU_THRESHOLD_MIN;
-       info->on_boot = true;
-       info->app_exists = false;
-       info->activation_method = 0;
-       info->deactivation_method = 0;
-       info->ttl = 600; /* 10 minutes */
-       info->is_hydra = false;
-       info->app_check = true;
-
-       return info;
-}
-
-static void __parse_detection_method(loader_info_t *info, char *line)
-{
-       char *token;
-       char *savedptr;
-
-       token = strtok_r(line, " |\t\r\n", &savedptr);
-       info->detection_method = 0;
-       while (token) {
-               if (!strcmp(token, VAL_METHOD_TIMEOUT))
-                       info->detection_method |= METHOD_TIMEOUT;
-               else if (!strcmp(token, VAL_METHOD_VISIBILITY))
-                       info->detection_method |= METHOD_VISIBILITY;
-               else if (!strcmp(token, VAL_METHOD_DEMAND))
-                       info->detection_method |= METHOD_DEMAND;
-
-               token = strtok_r(NULL, " |\t\r\n", &savedptr);
-       }
-
-       info->detection_method |= METHOD_INSTALL;
-       _D("detection_method:%d", info->detection_method);
-}
-
-static void __parse_activation_method(loader_info_t *info, char *line)
-{
-       char *token;
-       char *savedptr;
-
-       token = strtok_r(line, " |\t\r\n", &savedptr);
-       info->activation_method = 0;
-       while (token) {
-               if (!strcmp(token, VAL_METHOD_REQUEST))
-                       info->activation_method |= METHOD_REQUEST;
-               else if (!strcmp(token, VAL_METHOD_AVAILABLE_MEMORY))
-                       info->activation_method |= METHOD_AVAILABLE_MEMORY;
-
-               token = strtok_r(NULL, " |\t\r\n", &savedptr);
-       }
-
-       _D("activation_method:%d", info->activation_method);
-}
-
-static void __parse_deactivation_method(loader_info_t *info, char *line)
-{
-       char *token;
-       char *savedptr;
-
-       token = strtok_r(line, " |\t\r\n", &savedptr);
-       info->deactivation_method = 0;
-       while (token) {
-               if (!strcmp(token, VAL_METHOD_TTL))
-                       info->deactivation_method |= METHOD_TTL;
-               else if (!strcmp(token, VAL_METHOD_OUT_OF_MEMORY))
-                       info->deactivation_method |= METHOD_OUT_OF_MEMORY;
-
-               token = strtok_r(NULL, " |\t\r\n", &savedptr);
-       }
-
-       _D("deactivation_method:%d", info->deactivation_method);
-}
-
-static void __parse_app_types(loader_info_t *info, char *line)
-{
-       char *token;
-       char *savedptr;
-
-       token = strtok_r(line, " |\t\r\n", &savedptr);
-       while (token) {
-               info->app_types = g_list_append(info->app_types, strdup(token));
-               token = strtok_r(NULL, " |\t\r\n", &savedptr);
-       }
-}
-
-static void __parse_extra(loader_info_t *info, char *line)
-{
-       char *tok1 = NULL;
-       char *tok2 = NULL;
-       char *tok3 = NULL;
-
-       if (info->extra == NULL)
-               return;
-
-       sscanf(line, "%ms %ms %ms", &tok1, &tok2, &tok3);
-
-       if (!tok1 || !tok2 || !tok3)
-               goto end;
-
-       if (strlen(tok2) == 0 || strlen(tok3) == 0)
-               goto end;
-
-       bundle_add_str(info->extra, tok2, tok3);
-
-end:
-       if (tok1)
-               free(tok1);
-       if (tok2)
-               free(tok2);
-       if (tok3)
-               free(tok3);
-}
-
-static void __add_extra_array_from_list(bundle *b, const char *key, GList *list)
-{
-       const char **array;
-       int len;
-       int i;
-       GList *cur;
-
-       if (b == NULL || key == NULL || list == NULL)
-               return;
-
-       len = g_list_length(list);
-       array = malloc(sizeof(const char *) * len);
-       if (array == NULL)
-               return;
-
-       cur = list;
-       for (i = 0; i < len; i++) {
-               array[i] = cur->data;
-               cur = g_list_next(cur);
-       }
-
-       bundle_add_str_array(b, key, array, len);
-       free(array);
-}
-
-static void __flush_extra_array(bundle *b, char *key, GList *list)
-{
-       if (list) {
-               __add_extra_array_from_list(b, key, list);
-               g_list_free_full(list, free);
-       }
-
-       free(key);
-}
-
-static GList *__parse_file(GList *list, const char *path)
-{
-       FILE *fp;
-       char buf[LINE_MAX];
-       char *tok1 = NULL;
-       char *tok2 = NULL;
-       loader_info_t *cur_info = NULL;
-       char *key = NULL;
-       GList *extra_array = NULL;
-
-       fp = fopen(path, "rt");
-       if (fp == NULL)
-               return list;
-
-       while (fgets(buf, sizeof(buf), fp) != NULL) {
-               FREE_AND_NULL(tok1);
-               FREE_AND_NULL(tok2);
-               sscanf(buf, "%ms %ms", &tok1, &tok2);
-               if (tok1 && strcasecmp(TAG_LOADER, tok1) == 0) {
-                       if (cur_info != NULL) {
-                               __flush_extra_array(cur_info->extra, key,
-                                               extra_array);
-                               extra_array = NULL;
-                               key = NULL;
-                               list = g_list_append(list, cur_info);
-                       }
-                       cur_info = __create_loader_info();
-                       if (!cur_info)
-                               break;
-                       continue;
-               }
-
-               if (!tok1 || !tok2 || !cur_info)
-                       continue;
-               if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
-                       continue;
-
-               if (strcasecmp(TAG_NAME, tok1) == 0) {
-                       cur_info->name = strdup(tok2);
-               } else if (strcasecmp(TAG_EXE, tok1) == 0) {
-                       cur_info->exe = strdup(tok2);
-               } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
-                       __parse_app_types(cur_info, &buf[strlen(tok1)]);
-               } else if (strcasecmp(TAG_DETECTION_METHOD, tok1) == 0) {
-                       __parse_detection_method(cur_info, &buf[strlen(tok1)]);
-               } else if (strcasecmp(TAG_ACTIVATION_METHOD, tok1) == 0) {
-                       __parse_activation_method(cur_info,
-                                       &buf[strlen(tok1)]);
-               } else if (strcasecmp(TAG_DEACTIVATION_METHOD, tok1) == 0) {
-                       __parse_deactivation_method(cur_info,
-                                       &buf[strlen(tok1)]);
-               } else if (strcasecmp(TAG_TTL, tok1) == 0) {
-                       cur_info->ttl = strtoul(tok2, NULL, 10);
-               } else if (strcasecmp(TAG_TIMEOUT, tok1) == 0) {
-                       cur_info->timeout_val = atoi(tok2);
-               } else if (strcasecmp(TAG_EXTRA, tok1) == 0) {
-                       __parse_extra(cur_info, buf);
-               } else if (strcasecmp(TAG_EXTRA_ARRAY, tok1) == 0) {
-                       __flush_extra_array(cur_info->extra, key, extra_array);
-                       extra_array = NULL;
-                       key = strdup(tok2);
-               } else if (strcasecmp(TAG_EXTRA_ARRAY_VAL, tok1) == 0) {
-                       extra_array = g_list_append(extra_array, strdup(tok2));
-               } else if (strcasecmp(TAG_HW_ACC, tok1) == 0) {
-                       cur_info->hw_acc = strdup(tok2);
-               } else if (strcasecmp(TAG_ALTERNATIVE_LOADER, tok1) == 0) {
-                       cur_info->alternative_loaders =
-                               g_list_append(cur_info->alternative_loaders,
-                                               strdup(tok2));
-               } else if (strcasecmp(TAG_CPU_THRESHOLD_MAX, tok1) == 0) {
-                       cur_info->cpu_threshold_max = atoi(tok2);
-               } else if (strcasecmp(TAG_CPU_THRESHOLD_MIN, tok1) == 0) {
-                       cur_info->cpu_threshold_min = atoi(tok2);
-               } else if (strcasecmp(TAG_ON_BOOT, tok1) == 0) {
-                       if (tok2 && strcasecmp(VAL_OFF, tok2) == 0)
-                               cur_info->on_boot = false;
-               } else if (strcasecmp(TAG_HYDRA, tok1) == 0) {
-                       if (strcasecmp(VAL_ON, tok2) == 0)
-                               cur_info->is_hydra = 1;
-                       else
-                               cur_info->is_hydra = 0;
-               } else if (strcasecmp(TAG_APP_CHECK, tok1) == 0) {
-                       if (tok2 && strcasecmp(VAL_OFF, tok2) == 0)
-                               cur_info->app_check = false;
-               } else if (strcasecmp(TAG_ON_BOOT_TIMEOUT, tok1) == 0) {
-                       cur_info->on_boot_timeout = atoi(tok2);
-               } else if (strcasecmp(TAG_SCHED_PRIORITY, tok1) == 0) {
-                       cur_info->sched_priority = atoi(tok2);
-                       if (cur_info->sched_priority < -20)
-                               cur_info->sched_priority = -20;
-                       else if (cur_info->sched_priority > 19)
-                               cur_info->sched_priority = 19;
-               }
-       }
-
-       if (cur_info != NULL) {
-               __flush_extra_array(cur_info->extra, key, extra_array);
-               list = g_list_append(list, cur_info);
-       }
-
-       if (tok1)
-               free(tok1);
-       if (tok2)
-               free(tok2);
-
-       fclose(fp);
-
-       return list;
-}
-
-GList *_loader_info_load_dir(const char *path)
-{
-       DIR *dir_info;
-       struct dirent *entry = NULL;
-       GList *list = NULL;
-       char buf[PATH_MAX];
-       char *ext;
-
-       dir_info = opendir(path);
-       if (dir_info == NULL)
-               return  NULL;
-
-       while ((entry = readdir(dir_info)) != NULL) {
-               if (entry->d_name[0] == '.')
-                       continue;
-               ext = strrchr(entry->d_name, '.');
-               if (ext && !strcmp(ext, ".loader")) {
-                       snprintf(buf, sizeof(buf), "%s/%s", path, entry->d_name);
-                       list = __parse_file(list, buf);
-               }
-       }
-       closedir(dir_info);
-
-       return list;
-}
-
-GList *_loader_info_load_file(GList *list, const char *path)
-{
-       return __parse_file(list, path);
-}
-
-GList *_loader_info_unload(GList *list, const char *loader_name)
-{
-       GList *cur;
-       loader_info_t *info;
-
-       cur = g_list_find_custom(list, loader_name, __comp_name);
-       if (cur == NULL)
-               return list;
-
-       info = cur->data;
-
-       list = g_list_remove(list, info);
-       __free_info(info);
-
-       return list;
-}
-
-const char* _loader_info_find_loader_path_by_loader_name(GList *list, const char *loader_name)
-{
-       GList *cur;
-       loader_info_t *info;
-
-       cur = g_list_find_custom(list, loader_name, __comp_name);
-       if (cur == NULL)
-               return NULL;
-
-       info = cur->data;
-
-       return info->exe;
-}
-
-loader_info_t* _loader_info_find_loader_by_loader_name(GList *list, const char *loader_name)
-{
-       GList *cur;
-       loader_info_t *info;
-
-       cur = g_list_find_custom(list, loader_name, __comp_name);
-       if (cur == NULL)
-               return NULL;
-
-       info = cur->data;
-
-       return info;
-}
-
-static void __free_info(gpointer data)
-{
-       loader_info_t *info;
-
-       if (data == NULL)
-               return;
-
-       info = (loader_info_t *)data;
-
-       free(info->name);
-       free(info->exe);
-       if (info->app_types)
-               g_list_free_full(info->app_types, free);
-       free(info->hw_acc);
-       if (info->extra)
-               bundle_free(info->extra);
-       if (info->alternative_loaders)
-               g_list_free_full(info->alternative_loaders, free);
-
-       free(info);
-}
-
-void _loader_info_dispose(GList *info)
-{
-       g_list_free_full(info, __free_info);
-}
-
-static int __comp_str(gconstpointer a, gconstpointer b)
-{
-       if (!a || !b)
-               return -1;
-       return strcmp(a, b);
-}
-
-static int __comp_app_type_with_hw_acc(gconstpointer a, gconstpointer b)
-{
-       loader_info_t *info = (loader_info_t *)a;
-
-       if (info == NULL || info->app_types == NULL || b == NULL)
-               return -1;
-
-       if (g_list_find_custom(info->app_types, b, __comp_str) &&
-               (info->hw_acc == NULL || !strcasecmp(VAL_ON, info->hw_acc)))
-               return 0;
-
-       return -1;
-}
-
-static int __comp_app_type_with_sw_acc(gconstpointer a, gconstpointer b)
-{
-       loader_info_t *info = (loader_info_t *)a;
-
-       if (info == NULL || info->app_types == NULL || b == NULL)
-               return -1;
-
-       if (g_list_find_custom(info->app_types, b, __comp_str) &&
-               (info->hw_acc == NULL || !strcasecmp(VAL_OFF, info->hw_acc)))
-               return 0;
-
-       return -1;
-}
-
-static int __comp_name(gconstpointer a, gconstpointer b)
-{
-       loader_info_t *info = (loader_info_t *)a;
-
-       if (info == NULL || info->name == NULL || b == NULL)
-               return -1;
-
-       return strcmp(info->name, b);
-}
-
-int _loader_info_find_type(GList *info,  const char *app_type, bool hwacc)
-{
-       GList *cur;
-
-       if (hwacc) {
-               cur = g_list_find_custom(info, app_type,
-                               __comp_app_type_with_hw_acc);
-       } else {
-               cur = g_list_find_custom(info, app_type,
-                               __comp_app_type_with_sw_acc);
-       }
-
-       if (cur == NULL)
-               return -1;
-
-       loader_info_t *cur_info = (loader_info_t *)cur->data;
-
-       return cur_info->type;
-}
-
-int _loader_info_find_type_by_loader_name(GList *info,  const char *loader_name)
-{
-       GList *cur = NULL;
-
-       cur = g_list_find_custom(info, loader_name, __comp_name);
-       if (cur == NULL)
-               return -1;
-
-       loader_info_t *cur_info = (loader_info_t *)cur->data;
-
-       return cur_info->type;
-}
-
-static int *__make_type_array(GList *info, GList *loaders, int *len)
-{
-       int l;
-       int *t;
-       loader_info_t *i;
-       GList *c;
-       GList *cur;
-       int j = 0;
-
-       l = g_list_length(loaders);
-
-       if (l <= 0)
-               return NULL;
-
-       t = malloc(sizeof(int) * l);
-       if (!t)
-               return NULL;
-
-       *len = l;
-
-       cur = loaders;
-       while (cur) {
-               c = g_list_find_custom(info, cur->data, __comp_name);
-
-               if (c) {
-                       i = (loader_info_t *)c->data;
-                       t[j] = i->type;
-                       j++;
-               }
-
-               cur = g_list_next(cur);
-       }
-
-       return t;
-}
-
-int *_loader_get_alternative_types(GList *info, int type, int *len)
-{
-       GList *cur;
-       loader_info_t *i;
-
-       if (!info)
-               return NULL;
-
-       cur = info;
-       while (cur) {
-               i = (loader_info_t *)cur->data;
-               if (i->type == type) {
-                       if (!i->alternative_loaders)
-                               return NULL;
-
-                       return __make_type_array(info, i->alternative_loaders,
-                                       len);
-               }
-               cur = g_list_next(cur);
-       }
-
-       return NULL;
-}
-
-int _loader_info_foreach(GList *info, loader_info_foreach_cb callback,
-               void *data)
-{
-       GList *cur;
-       loader_info_t *i;
-
-       if (!info || !callback)
-               return -1;
-
-       cur = info;
-       while (cur) {
-               i = (loader_info_t *)cur->data;
-               callback(i, data);
-               cur = g_list_next(cur);
-       }
-
-       return 0;
-}
-
-bool _loader_info_exist_app_type(loader_info_t *info, const char *app_type)
-{
-       GList *list;
-
-       list = g_list_find_custom(info->app_types, app_type, __comp_str);
-       if (list)
-               return true;
-
-       return false;
-}
diff --git a/src/launchpad-process-pool/src/loader_info.cc b/src/launchpad-process-pool/src/loader_info.cc
new file mode 100644 (file)
index 0000000..548dfe1
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+#include <utility>
+
+#include "launchpad_common.h"
+#include "loader_info.hh"
+#include "util.hh"
+
+namespace launchpad {
+namespace {
+
+constexpr const char kTagLoader[] = "[LOADER]";
+constexpr const char kTagName[] = "NAME";
+constexpr const char kTagExe[] = "EXE";
+constexpr const char kTagAppType[] = "APP_TYPE";
+constexpr const char kTagDetectionMethod[] = "DETECTION_METHOD";
+constexpr const char kTagActivationMethod[] = "ACTIVATION_METHOD";
+constexpr const char kTagDeactivationMethod[] = "DEACTIVATION_METHOD";
+constexpr const char kTagTtl[] = "TTL";
+constexpr const char kTagTimeout[] = "TIMEOUT";
+constexpr const char kTagExtra[] = "EXTRA";
+constexpr const char kTagExtraArray[] = "EXTRA_ARRAY";
+constexpr const char kTagExtraArrayVal[] = "EXTRA_ARRAY_VAL";
+constexpr const char kTagAlternativeLoader[] = "ALTERNATIVE_LOADER";
+constexpr const char kTagHwAcc[] = "HW_ACC";
+constexpr const char kTagCpuThresholdMax[] = "CPU_THRESHOLD_MAX";
+constexpr const char kTagCpuThresholdMin[] = "CPU_THRESHOLD_MIN";
+constexpr const char kTagOnBoot[] = "ON_BOOT";
+constexpr const char kTagHydra[] = "HYDRA";
+constexpr const char kTagAppCheck[] = "APP_CHECK";
+constexpr const char kTagOnBootTimeout[] = "ON_BOOT_TIMEOUT";
+constexpr const char kTagSchedPriority[] = "SCHED_PRIORITY";
+
+constexpr const char kValOn[] = "ON";
+constexpr const char kValOff[] = "OFF";
+constexpr const char kValMethodTimeout[] = "TIMEOUT";
+constexpr const char kValMethodDemand[] = "DEMAND";
+constexpr const char kValMethodVisibility[] = "VISIBILITY";
+constexpr const char kValMethodRequest[] = "REQUEST";
+constexpr const char kValMethodAvailableMemory[] = "AVAILABLE_MEMORY";
+constexpr const char kValMethodTtl[] = "TTL";
+constexpr const char kValMethodOutOfMemory[] = "OUT_OF_MEMORY";
+
+}  // namespace
+
+namespace fs = std::filesystem;
+
+void LoaderInfoInflator::ParseDetectionMethod(const LoaderInfoPtr& info,
+                                              std::string& tok_start,
+                                              std::istringstream& ss) {
+  std::string line = tok_start;
+  do {
+    auto tokens = Split(line, " |\t\r\n");
+    for (auto& token : tokens) {
+      if (token == kValMethodTimeout)
+        info->detection_method_ =
+            info->detection_method_ | LoaderMethod::Timeout;
+      else if (token == kValMethodVisibility)
+        info->detection_method_ =
+            info->detection_method_ | LoaderMethod::Visibility;
+      else if (token == kValMethodDemand)
+        info->detection_method_ =
+            info->detection_method_ | LoaderMethod::Demand;
+    }
+  } while (std::getline(ss, line));
+
+  info->detection_method_ = info->detection_method_ | LoaderMethod::Install;
+  _D("detection_method:%d", static_cast<int>(info->detection_method_));
+}
+
+void LoaderInfoInflator::ParseActivationMethod(const LoaderInfoPtr& info,
+                                               std::string& tok_start,
+                                               std::istringstream& ss) {
+  info->activation_method_ = LoaderMethod::Empty;
+  std::string line = tok_start;
+  do {
+    auto tokens = Split(line, " |\t\r\n");
+    for (auto& token : tokens) {
+      if (token == kValMethodRequest)
+        info->activation_method_ =
+            info->activation_method_ | LoaderMethod::Request;
+      else if (token == kValMethodAvailableMemory)
+        info->activation_method_ =
+            info->activation_method_ | LoaderMethod::AvailableMemory;
+    }
+  } while (std::getline(ss, line));
+
+  _D("activation_method:%d", static_cast<int>(info->activation_method_));
+}
+
+void LoaderInfoInflator::ParseDeactivationMethod(const LoaderInfoPtr& info,
+                                                 std::string& tok_start,
+                                                 std::istringstream& ss) {
+  info->deactivation_method_ = LoaderMethod::Empty;
+  std::string line = tok_start;
+  do {
+    auto tokens = Split(line, " |\t\r\n");
+    for (auto& token : tokens) {
+      if (token == kValMethodTtl)
+        info->deactivation_method_ =
+            info->deactivation_method_ | LoaderMethod::Ttl;
+      else if (token == kValMethodOutOfMemory)
+        info->deactivation_method_ =
+            info->deactivation_method_ | LoaderMethod::OutOfMemory;
+    }
+  } while (std::getline(ss, line));
+
+  _D("deactivation_method:%d", static_cast<int>(info->deactivation_method_));
+}
+
+void LoaderInfoInflator::ParseAppTypes(const LoaderInfoPtr& info,
+                                       std::string& tok_start,
+                                       std::istringstream& ss) {
+  std::string line = tok_start;
+  do {
+    auto tokens = Split(line, " |\t\r\n");
+    for (auto& token : tokens) {
+      info->app_types_.push_back(std::move(token));
+    }
+  } while (std::getline(ss, line));
+}
+
+void LoaderInfoInflator::Parse(std::vector<LoaderInfoPtr>& loader_info_list,
+                               const fs::path& path) {
+  std::ifstream fp;
+  fp.open(path);
+  if (fp.fail())
+    return;
+
+  LoaderInfoPtr info;
+  std::string input;
+  std::string extra_array_key;
+  std::vector<std::string> extra_array;
+  while (std::getline(fp, input)) {
+    std::istringstream ss(input);
+    std::string tok1, tok2;
+    if (!(ss >> tok1))
+      continue;
+
+    if (strcasecmp(kTagLoader, tok1.c_str()) == 0) {
+      if (info != nullptr) {
+        if (!extra_array.empty()) {
+          info->extra_.Add(std::move(extra_array_key), std::move(extra_array));
+          extra_array.clear();
+        }
+
+        loader_info_list.push_back(std::move(info));
+      }
+
+      info = std::make_shared<LoaderInfo>();
+      continue;
+    }
+
+    if (!(ss >> tok2))
+      continue;
+    if (tok1.front() == '#' || info == nullptr)
+      continue;
+
+    std::string key;
+    std::transform(tok1.begin(), tok1.end(), std::back_inserter(key),
+                   [](char ch) { return toupper(ch); });
+    if (kTagName == key) {
+      info->name_ = std::move(tok2);
+    } else if (kTagExe == key) {
+      info->exe_ = std::move(tok2);
+    } else if (kTagAppType == key) {
+      ParseAppTypes(info, tok2, ss);
+    } else if (kTagDetectionMethod == key) {
+      ParseDetectionMethod(info, tok2, ss);
+    } else if (kTagActivationMethod == key) {
+      ParseActivationMethod(info, tok2, ss);
+    } else if (kTagDeactivationMethod == key) {
+      ParseDeactivationMethod(info, tok2, ss);
+    } else if (kTagTtl == key) {
+      info->ttl_ = std::stoul(tok2);
+    } else if (kTagTimeout == key) {
+      info->timeout_val_ = std::stoi(tok2);
+    } else if (kTagExtra == key) {
+      std::string val;
+      if (ss >> val)
+        info->extra_.Add(std::move(tok2), std::move(val));
+    } else if (kTagExtraArray == key) {
+      if (!extra_array.empty()) {
+        info->extra_.Add(std::move(extra_array_key), std::move(extra_array));
+        extra_array.clear();
+      }
+      extra_array_key = std::move(tok2);
+    } else if (kTagExtraArrayVal == key) {
+      extra_array.push_back(std::move(tok2));
+    } else if (kTagHwAcc == key) {
+      info->hw_acc_ = std::move(tok2);
+    } else if (kTagAlternativeLoader == key) {
+      info->alternative_loaders_.push_back(std::move(tok2));
+    } else if (kTagCpuThresholdMax == key) {
+      info->cpu_threshold_max_ = std::stoi(tok2);
+    } else if (kTagCpuThresholdMin == key) {
+      info->cpu_threshold_min_ = std::stoi(tok2);
+    } else if (kTagOnBoot == key) {
+      if (kValOff == tok2)
+        info->on_boot_ = false;
+    } else if (kTagHydra == key) {
+      if (kValOn == tok2)
+        info->is_hydra_ = true;
+      else
+        info->is_hydra_ = false;
+    } else if (kTagAppCheck == key) {
+      if (kValOff == tok2)
+        info->app_check_ = false;
+    } else if (kTagOnBootTimeout == key) {
+      info->on_boot_timeout_ = std::stoi(tok2);
+    } else if (kTagSchedPriority == key) {
+      info->sched_priority_ = std::min(std::max(std::stoi(tok2), -20), 19);
+    }
+  }
+
+  fp.close();
+  if (info != nullptr) {
+    if (!extra_array.empty())
+      info->extra_.Add(std::move(extra_array_key), std::move(extra_array));
+
+    loader_info_list.push_back(std::move(info));
+  }
+}
+
+LoaderType LoaderInfo::GetType() const {
+  return type_;
+}
+
+const std::string& LoaderInfo::GetName() const {
+  return name_;
+}
+
+const std::string& LoaderInfo::GetExe() const {
+  return exe_;
+}
+
+int LoaderInfo::GetCpuThresholdMax() const {
+  return cpu_threshold_max_;
+}
+
+int LoaderInfo::GetCpuThresholdMin() const {
+  return cpu_threshold_min_;
+}
+
+unsigned int LoaderInfo::GetTtl() const {
+  return ttl_;
+}
+
+const std::vector<std::string>& LoaderInfo::GetAppTypes() const {
+  return app_types_;
+}
+
+LoaderMethod LoaderInfo::GetDetectionMethod() const {
+  return detection_method_;
+}
+
+LoaderMethod LoaderInfo::GetActivationMethod() const {
+  return activation_method_;
+}
+
+LoaderMethod LoaderInfo::GetDeactivationMethod() const {
+  return deactivation_method_;
+}
+
+const std::string& LoaderInfo::GetHwAcc() const {
+  return hw_acc_;
+}
+
+int LoaderInfo::GetOnbootTimeout() const {
+  return on_boot_timeout_;
+}
+
+int LoaderInfo::GetTimeoutVal() const {
+  return timeout_val_;
+}
+
+int LoaderInfo::GetSchedPriority() const {
+  return sched_priority_;
+}
+
+bool LoaderInfo::IsAppExists() const {
+  return app_exists_;
+}
+
+bool LoaderInfo::IsOnBoot() const {
+  return on_boot_;
+}
+
+bool LoaderInfo::IsHydraEnabled() const {
+  return is_hydra_;
+}
+
+bool LoaderInfo::IsNeededAppCheck() const {
+  return app_check_;
+}
+
+tizen_base::Bundle& LoaderInfo::GetExtra() {
+  return extra_;
+}
+
+void LoaderInfo::SetType(LoaderType type) {
+  type_ = type;
+}
+
+void LoaderInfo::SetAppExists(bool exists) {
+  app_exists_ = exists;
+}
+
+std::vector<LoaderInfoPtr> LoaderInfoInflator::Inflate(
+    const std::string_view path) {
+  fs::path p(path);
+  if (fs::is_directory(p) == false)
+    return {};
+
+  std::vector<LoaderInfoPtr> result;
+  for (auto& entry : fs::directory_iterator(p)) {
+    fs::path file(entry.path());
+    if (file.extension() == ".loader")
+      Parse(result, file);
+  }
+
+  return result;
+}
+
+LoaderInfoManager::LoaderInfoManager(std::string path): path_(std::move(path)) {
+
+}
+
+void LoaderInfoManager::Load() {
+  if (!loader_list_.empty())
+    return;
+
+  LoaderInfoInflator inflator;
+  loader_list_ = inflator.Inflate(path_);
+}
+
+void LoaderInfoManager::LoadFile(const std::string_view file) {
+  LoaderInfoInflator inflator;
+  fs::path p(path_);
+  inflator.Parse(loader_list_, p / file);
+}
+
+void LoaderInfoManager::Unload(const std::string_view loader_name) {
+  loader_list_.erase(std::remove_if(loader_list_.begin(), loader_list_.end(),
+                                    [&](const LoaderInfoPtr& info) -> bool {
+                                      return info->GetName() == loader_name;
+                                    }), loader_list_.end());
+}
+
+void LoaderInfoManager::Dispose() {
+  loader_list_.clear();
+}
+
+std::string LoaderInfoManager::FindLoaderPath(
+    const std::string_view loader_name) {
+  for (auto& info : loader_list_) {
+    if (info->GetName() == loader_name)
+      return info->GetExe();
+  }
+
+  return "";
+}
+
+LoaderInfoPtr LoaderInfoManager::FindLoaderInfo(
+    const std::string_view loader_name) {
+  for (auto& info : loader_list_) {
+    if (info->GetName() == loader_name)
+      return info;
+  }
+
+  return nullptr;
+}
+
+LoaderType LoaderInfoManager::FindHwType(const std::string_view app_type) {
+  for (auto& info : loader_list_) {
+    if (info->GetHwAcc().empty() || info->GetHwAcc() == kValOn) {
+      auto it = std::find_if(
+          info->GetAppTypes().begin(), info->GetAppTypes().end(),
+          [&](const std::string& type) -> bool { return type == app_type; });
+
+      if (it != info->GetAppTypes().end())
+        return info->GetType();
+    }
+  }
+
+  return LoaderType::Unsupported;
+}
+
+LoaderType LoaderInfoManager::FindSwType(const std::string_view app_type) {
+  for (auto& info : loader_list_) {
+    if (info->GetHwAcc().empty() || info->GetHwAcc() == kValOff) {
+      auto it = std::find_if(
+          info->GetAppTypes().begin(), info->GetAppTypes().end(),
+          [&](const std::string& type) -> bool { return type == app_type; });
+
+      if (it != info->GetAppTypes().end())
+        return info->GetType();
+    }
+  }
+
+  return LoaderType::Unsupported;
+}
+
+std::vector<LoaderType> LoaderInfoManager::GetAlternativeTypes(
+    LoaderType type) {
+  std::vector<LoaderType> result;
+  for (auto& info : loader_list_) {
+    if (info->GetType() == type) {
+      for (auto& alt_loader : info->alternative_loaders_) {
+        auto it = std::find_if(loader_list_.begin(), loader_list_.end(),
+                               [&](const auto& li) -> bool {
+                                 return li->GetName() == alt_loader;
+                               });
+
+        if (it != loader_list_.end()) {
+          result.push_back((*it)->GetType());
+        }
+      }
+    }
+  }
+
+  return result;
+}
+
+const std::vector<LoaderInfoPtr>& LoaderInfoManager::GetLoaderInfoList() const {
+  return loader_list_;
+}
+
+}  // namespace launchpad
similarity index 52%
rename from src/launchpad-process-pool/inc/launcher_info.h
rename to src/launchpad-process-pool/src/util.cc
index c8a470b..172d1bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the License);
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
-#ifndef __LAUNCHER_INFO_H__
-#define __LAUNCHER_INFO_H__
+#include "util.hh"
 
-#include <glib.h>
+#include <regex>
 
-typedef struct launcher_info_s *launcher_info_h;
+namespace launchpad {
 
-GList *_launcher_info_load(const char *path);
-void _launcher_info_unload(GList *info);
-launcher_info_h _launcher_info_find(GList *info_list, const char *app_type);
-const char *_launcher_info_get_exe(launcher_info_h launcher_info);
-GList *_launcher_info_get_extra_args(launcher_info_h launcher_info);
+std::vector<std::string> Split(const std::string& str,
+                               const std::string& delim) {
+  const std::regex deli("[^" + delim + "]+");
+  std::vector<std::string> result;
+  for (auto i = std::sregex_iterator(str.begin(), str.end(), deli);
+       i != std::sregex_iterator(); ++i) {
+    result.push_back((*i).str());
+  }
 
-#endif /* __LAUNCHER_INFO_H__ */
+  return result;
+}
+
+}  // namespace launchpad
index f2cf987..d8b7123 100644 (file)
 
 #include <bundle.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 int _launchpad_plugin_prepare_app(const char *app_id, bundle *kb);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __LAUNCHPAD_PLUGIN_H__ */