PROJECT(context-service)
INCLUDE(GNUInstallDirs)
+INCLUDE_DIRECTORIES(
+ ${CMAKE_SOURCE_DIR}/src/shared
+)
+
ADD_DEFINITIONS(-O2 -Wall -fPIC -fPIE -fdata-sections -ffunction-sections -fvisibility=hidden)
+ADD_DEFINITIONS(-D_LIBDIR_="${LIBDIR}")
ADD_DEFINITIONS(-fdiagnostics-color)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -pie -Wl,--as-needed -Wl,--gc-sections -Wl,--print-gc-sections")
SET(CMAKE_VERBOSE_MAKEFILE OFF)
Source1: contextd.service
Source2: org.tizen.context.conf
Source3: contextd-agent.service
+Source4: contextd-agent.socket
BuildRequires: cmake
+BuildRequires: pkgconfig(libsystemd-daemon)
BuildRequires: pkgconfig(libsystemd-login)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(gio-2.0)
export CXXFLAGS+=" -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow"
export CXXFLAGS+=" -Wnon-virtual-dtor -std=c++0x"
-%cmake .
+%cmake . -DLIBDIR=%{_libdir}
make %{?_smp_mflags}
%install
mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d
install -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/dbus-1/system.d/
-mkdir -p %{buildroot}%{_unitdir_user}
+mkdir -p %{buildroot}%{_unitdir_user}/sockets.target.wants
install -m 0644 %{SOURCE3} %{buildroot}%{_unitdir_user}
+install -m 0644 %{SOURCE4} %{buildroot}%{_unitdir_user}
+ln -s ../contextd-agent.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/contextd-agent.socket
%files
%manifest packaging/%{name}.manifest
%manifest packaging/%{name}.manifest
%{_bindir}/contextd-agent
%{_unitdir_user}/contextd-agent.service
+%{_unitdir_user}/contextd-agent.socket
+%{_unitdir_user}/*/contextd-agent.socket
%license LICENSE
Description=Contextual Service Framework User-Level Agent Daemon
[Service]
-Type=simple
+Type=notify
ExecStart=/usr/bin/contextd-agent
+Sockets=contextd-agent.socket
+Restart=no
+
+[Install]
+WantedBy=sockets.target
--- /dev/null
+[Unit]
+Description=Context-Agent Socket
+
+[Socket]
+ListenStream=/run/user_ext/%U/.contextd-agent.socket
+Service=contextd-agent.service
+Accept=false
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdexcept>
+#include "AgentDBus.h"
+
+using namespace ctx;
+
+AgentDBus::AgentDBus() :
+ __connection(NULL)
+{
+ if (!__init())
+ throw std::runtime_error("DBus connection failed");
+
+ _I("Connection established (%s)", g_dbus_connection_get_unique_name(__connection));
+}
+
+AgentDBus::~AgentDBus()
+{
+ __release();
+}
+
+GDBusConnection* AgentDBus::getConnection()
+{
+ return __connection;
+}
+
+bool AgentDBus::__init()
+{
+ GError *gerr = NULL;
+ gchar *addr = NULL;
+
+ addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &gerr);
+ HANDLE_GERROR(gerr);
+ IF_FAIL_RETURN_TAG(addr, false, _E, "Getting address failed");
+
+ __connection = g_dbus_connection_new_for_address_sync(addr,
+ (GDBusConnectionFlags)(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
+ NULL, NULL, &gerr);
+ g_free(addr);
+ HANDLE_GERROR(gerr);
+ IF_FAIL_RETURN_TAG(__connection, false, _E, "Connection failed");
+
+ return true;
+}
+
+void AgentDBus::__release()
+{
+ if (__connection) {
+ g_dbus_connection_flush_sync(__connection, NULL, NULL);
+ g_dbus_connection_close_sync(__connection, NULL, NULL);
+ g_object_unref(__connection);
+ }
+
+ _I("Connection released");
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 __CONTEXT_AGENT_DBUS_H__
+#define __CONTEXT_AGENT_DBUS_H__
+
+#include <ContextTypes.h>
+
+namespace ctx {
+
+ class AgentDBus {
+ public:
+ AgentDBus();
+ ~AgentDBus();
+
+ GDBusConnection* getConnection();
+
+ private:
+ bool __init();
+ void __release();
+
+ GDBusConnection* __connection;
+ };
+
+}
+
+#endif
* limitations under the License.
*/
+#include <csignal>
#include <cstdlib>
+#include <systemd/sd-daemon.h>
-int main(int argc, char* argv[])
+#include <ServerBase.h>
+#include "AgentDBus.h"
+#include "AgentUtil.h"
+#include "PluginLoader.h"
+#include "AgentSocket.h"
+
+using namespace ctx;
+
+static MainLoop __mainLoop;
+
+static void __on_signal(int signum)
+{
+ _I(YELLOW("SIGNAL-%d: '%s'"), signum, strsignal(signum));
+ __mainLoop.stop();
+}
+
+int main(int argc, char **argv)
{
+ std::signal(SIGINT, __on_signal);
+ std::signal(SIGHUP, __on_signal);
+ std::signal(SIGTERM, __on_signal);
+ std::signal(SIGQUIT, __on_signal);
+
+ AgentDBus agentDBus;
+ AgentUtil agentUtil(agentDBus);
+ PluginLoader pluginLoader(agentUtil);
+ AgentSocket agentSocket(pluginLoader);
+
+ sd_notify(0, "READY=1");
+
+ __mainLoop.start();
+
+ sd_notify(0, "STOPPING=1");
+
return EXIT_SUCCESS;
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <systemd/sd-daemon.h>
+#include <stdexcept>
+#include <IAgentPlugin.h>
+#include "PluginLoader.h"
+#include "AgentSocket.h"
+
+#define PATH_LENGTH 48
+#define TERM_MSG_ID 0xFFFF
+
+using namespace ctx;
+
+struct CommandInfo {
+ PluginLoader* pluginLoader;
+ uint16_t id;
+ uint8_t length;
+ void* command;
+
+ CommandInfo(PluginLoader* loader, uint16_t i, uint8_t len, char* cmd) :
+ pluginLoader(loader), id(i), length(len), command(NULL)
+ {
+ command = malloc(length);
+
+ if (!command)
+ throw std::bad_alloc();
+
+ memcpy(command, cmd, length);
+ }
+
+ ~CommandInfo()
+ {
+ free(command);
+ }
+};
+
+static gboolean __send_command(gpointer data)
+{
+ CommandInfo* info = static_cast<CommandInfo*>(data);
+
+ info->pluginLoader->send(info->id, info->length, info->command);
+
+ delete info;
+
+ return G_SOURCE_REMOVE;
+}
+
+static bool __set_close_on_exec(int fd)
+{
+ if (::fcntl(fd, F_SETFL, FD_CLOEXEC) == -1)
+ return false;
+
+ return true;
+}
+
+static int __get_socket_fd(const char* path)
+{
+ int n = sd_listen_fds(0);
+ IF_FAIL_RETURN_TAG(n > 0, E_ACCESS, _E, "sd_listen_fds() failed");
+
+ for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) {
+ if (sd_is_socket_unix(fd, SOCK_STREAM, 1, path, 0) > 0) {
+ __set_close_on_exec(fd);
+ return fd;
+ }
+ }
+
+ return E_ACCESS;
+}
+
+AgentSocket::AgentSocket(PluginLoader& loader) :
+ __sockFd(-1),
+ __listening(false),
+ __listeningThread(NULL),
+ __pluginLoader(loader)
+{
+ if (!__init()) {
+ __release();
+ throw std::runtime_error("Socket connection failed");
+ }
+
+ _I("Listening...");
+}
+
+AgentSocket::~AgentSocket()
+{
+ __release();
+}
+
+bool AgentSocket::__init()
+{
+ char path[PATH_LENGTH];
+ g_snprintf(path, PATH_LENGTH, CTX_AGENT_SOCKET, static_cast<unsigned>(getuid()));
+
+ _D("Socket Path: %s", path);
+
+ __sockFd = __get_socket_fd(path);
+ IF_FAIL_RETURN_TAG(__sockFd > 0, false, _E, "Failed to get the socket fd");
+
+ __listening.store(true);
+ __listeningThread = g_thread_new(NULL, __listen, this);
+ IF_FAIL_RETURN_TAG(__listeningThread, false, _E, "Thread creation failed");
+
+ return true;
+}
+
+gpointer AgentSocket::__listen(gpointer data)
+{
+ static_cast<AgentSocket*>(data)->__listen();
+ return NULL;
+}
+
+void AgentSocket::__listen()
+{
+ int msgsock = 0;
+
+ while (__listening.load()) {
+ msgsock = accept(__sockFd, 0, 0);
+
+ if (msgsock < 0) {
+ _D("accept() failed");
+ continue;
+ }
+
+ if (!__readCommand(msgsock)) {
+ close(msgsock);
+ break;
+ }
+
+ close(msgsock);
+ }
+}
+
+bool AgentSocket::__readCommand(int msgsock)
+{
+ uint16_t id = 0;
+ uint8_t length = 0;
+ int rval = 0;
+ char buf[CTX_AGENT_COMMAND_LIMIT] = {0};
+
+ rval = read(msgsock, &id, sizeof(id));
+ IF_FAIL_RETURN_TAG(rval == sizeof(id), false, _E, "read() failed");
+
+ if (id == TERM_MSG_ID) {
+ _D("Stop listening...");
+ return false;
+ }
+
+ rval = read(msgsock, &length, sizeof(length));
+ IF_FAIL_RETURN_TAG(rval == sizeof(length), false, _E, "read() failed");
+
+ rval = read(msgsock, buf, length);
+ IF_FAIL_RETURN_TAG(rval == static_cast<int>(length), false, _E, "read() failed");
+
+
+ buf[length] = '\0';
+
+ CommandInfo* info = new CommandInfo(&__pluginLoader, id, length, buf);
+ g_idle_add(__send_command, info);
+
+ return true;
+}
+
+void AgentSocket::__release()
+{
+ if (!__listening.load())
+ return;
+
+ __listening.store(false);
+ __terminate();
+
+ if (__listeningThread)
+ g_thread_join(__listeningThread);
+
+ close(__sockFd);
+}
+
+bool AgentSocket::__terminate()
+{
+ int sock = -1;
+ sockaddr_un addr;
+ char path[PATH_LENGTH];
+ const uint16_t termMsg = TERM_MSG_ID;
+
+ g_snprintf(path, PATH_LENGTH, CTX_AGENT_SOCKET, static_cast<unsigned>(getuid()));
+ IF_FAIL_RETURN_TAG(strlen(path) < sizeof(addr.sun_path), false, _E, "Invalid path");
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ IF_FAIL_RETURN_TAG(sock > 0, false, _E, "socket creation failed");
+
+ bzero(&addr, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, path, sizeof(addr.sun_path));
+ addr.sun_path[sizeof(path)] = '\0';
+
+ if (connect(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
+ close(sock);
+ _E("Connection failed");
+ return false;
+ }
+
+ if (write(sock, &termMsg, sizeof(termMsg)) < 0) {
+ close(sock);
+ _E("Sending failed");
+ return false;
+ }
+
+ close(sock);
+ return true;
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 __CONTEXT_AGENT_SOCKET_H__
+#define __CONTEXT_AGENT_SOCKET_H__
+
+#include <atomic>
+#include <ContextTypes.h>
+
+namespace ctx {
+
+ class PluginLoader;
+
+ class AgentSocket {
+ public:
+ AgentSocket(PluginLoader& loader);
+ ~AgentSocket();
+
+ private:
+ bool __init();
+ void __release();
+
+ void __listen();
+ bool __readCommand(int msgsock);
+ bool __terminate();
+
+ static gpointer __listen(gpointer data);
+
+ int __sockFd;
+ std::atomic_bool __listening;
+ GThread* __listeningThread;
+ PluginLoader& __pluginLoader;
+ };
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 "AgentDBus.h"
+#include "AgentUtil.h"
+
+using namespace ctx;
+
+AgentUtil::AgentUtil(AgentDBus& agentDBus) :
+ __agentDBus(agentDBus)
+{
+}
+
+AgentUtil::~AgentUtil()
+{
+}
+
+GDBusConnection* AgentUtil::getDBusConnection()
+{
+ return __agentDBus.getConnection();
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 __CONTEXT_AGENT_UTIL_H__
+#define __CONTEXT_AGENT_UTIL_H__
+
+#include <ContextTypes.h>
+#include <IAgentPlugin.h>
+
+namespace ctx {
+
+ class AgentDBus;
+
+ class AgentUtil : public IAgentUtil {
+ public:
+ AgentUtil(AgentDBus& agentDBus);
+ ~AgentUtil();
+
+ GDBusConnection* getDBusConnection();
+
+ private:
+ AgentDBus& __agentDBus;
+ };
+
+}
+
+#endif
SET(target "contextd-agent")
-SET(DEPS glib-2.0 gio-2.0 gmodule-2.0 dlog capi-base-common)
+SET(DEPS glib-2.0 gio-2.0 gmodule-2.0 libsystemd-daemon dlog capi-base-common)
-FILE(GLOB_RECURSE SRCS *.cpp)
+SET(INCDIR "${CMAKE_INSTALL_INCLUDEDIR}/context-service")
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_INSTALL_PREFIX}/${INCDIR}/private
+)
+
+FILE(GLOB SRCS *.cpp ../shared/*.cpp)
MESSAGE("Sources: ${SRCS}")
INCLUDE(FindPkgConfig)
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdexcept>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <gmodule.h>
+#include "AgentUtil.h"
+#include "PluginLoader.h"
+
+#define PLUGIN_DIR _LIBDIR_ "/" CTX_AGENT_PLUGIN_DIR
+
+using namespace ctx;
+
+PluginLoader::PluginLoader(AgentUtil& agentUtil) :
+ __agentUtil(agentUtil)
+{
+ if (!__load()) {
+ __unload();
+ throw std::runtime_error("Plugin loading failed");
+ }
+
+ _I("%u plugins loaded", __plugins.size());
+}
+
+PluginLoader::~PluginLoader()
+{
+ __unload();
+}
+
+void PluginLoader::send(uint16_t id, uint8_t length, const void* command)
+{
+ for (auto& agent : __plugins) {
+ if (agent->getId() == id) {
+ agent->doAction(length, command);
+ return;
+ }
+ }
+
+ _W("Agent not found");
+}
+
+bool PluginLoader::__load()
+{
+ DIR* dir = NULL;
+ struct dirent* entry = NULL;
+ struct stat fileStat;
+
+ _D("Scanning %s", PLUGIN_DIR);
+
+ dir = opendir(PLUGIN_DIR);
+ IF_FAIL_RETURN_TAG(dir, false, _E, "Failed to open: %s", PLUGIN_DIR);
+
+ while ((entry = readdir(dir))) {
+ std::string filePath(PLUGIN_DIR "/");
+ filePath.append(entry->d_name);
+
+ if (lstat(filePath.c_str(), &fileStat) != 0)
+ continue;
+
+ if (!S_ISREG(fileStat.st_mode))
+ continue;
+
+ if (!__load(filePath)) {
+ closedir(dir);
+ _E("Failed to load %s", filePath.c_str());
+ return false;
+ }
+ }
+
+ closedir(dir);
+ return true;
+}
+
+bool PluginLoader::__load(const std::string& filePath)
+{
+ _D("Loading plugins from %s", filePath.c_str());
+
+ GModule *soHandle = g_module_open(filePath.c_str(), G_MODULE_BIND_LAZY);
+ IF_FAIL_RETURN_TAG(soHandle, false, _E, "%s", g_module_error());
+
+ create_plugins_t createPlugins;
+ if (!g_module_symbol(soHandle, CTX_AGENT_CREATE_FUNC_SYM, (gpointer*)&createPlugins) || !createPlugins) {
+ _E("%s", g_module_error());
+ g_module_close(soHandle);
+ return false;
+ }
+
+ IAgentPlugin** plugins = createPlugins(&__agentUtil);
+ for (int i = 0; plugins[i] != NULL; ++i) {
+ __plugins.push_back(plugins[i]);
+ }
+
+ return true;
+}
+
+void PluginLoader::__unload()
+{
+ for (auto& plugin : __plugins) {
+ delete plugin;
+ }
+
+ __plugins.clear();
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 __CONTEXT_AGENT_PLUGIN_LOADER_H__
+#define __CONTEXT_AGENT_PLUGIN_LOADER_H__
+
+#include <string>
+#include <vector>
+#include <ContextTypes.h>
+#include <IAgentPlugin.h>
+
+namespace ctx {
+
+ class AgentUtil;
+
+ class PluginLoader {
+ public:
+ PluginLoader(AgentUtil& agentUtil);
+ ~PluginLoader();
+
+ void send(uint16_t id, uint8_t length, const void* command);
+
+ private:
+ bool __load();
+ bool __load(const std::string& filePath);
+ void __unload();
+
+ AgentUtil& __agentUtil;
+ std::vector<IAgentPlugin*> __plugins;
+ };
+
+}
+
+#endif
${CMAKE_INSTALL_PREFIX}/${INCDIR}/private
)
-FILE(GLOB_RECURSE SRCS *.cpp)
+FILE(GLOB SRCS *.cpp ../shared/*.cpp)
MESSAGE("Sources: ${SRCS}")
INCLUDE(FindPkgConfig)
#include <csignal>
#include <cstdlib>
#include <cstring>
-#include <new>
-#include <exception>
-#include <stdexcept>
#include <ContextTypes.h>
#include <ServerUtil.h>
+#include <ServerBase.h>
#include "DBusConnector.h"
#include "ServiceLoader.h"
#include "ActiveUserMonitor.h"
#include "AlarmInitializer.h"
-#define NEW_FAIL_LIMIT 3
-
using namespace ctx;
-namespace {
- class MainLoop {
- public:
- static bool start();
- static void stop();
- private:
- MainLoop() {}
- static GMainLoop* __mainLoop;
- };
-}
-
-GMainLoop* MainLoop::__mainLoop = NULL;
-
-bool MainLoop::start()
-{
- __mainLoop = g_main_loop_new(NULL, FALSE);
- IF_FAIL_RETURN_TAG(__mainLoop, false, _E, E_STR_ALLOC);
-
- _I(CYAN("Starting..."));
- g_main_loop_run(__mainLoop);
-
- g_main_loop_unref(__mainLoop);
-
- return true;
-}
-
-void MainLoop::stop()
-{
- _I(PURPLE("Terminating..."));
- g_main_loop_quit(__mainLoop);
-}
-
+static MainLoop __mainLoop;
static ServiceLoader __serviceLoader;
static ActiveUserMonitor __activeUserMonitor(&__serviceLoader);
static AlarmInitializer __alarmInit;
_I("Unloading services");
__serviceLoader.stopAll();
- MainLoop::stop();
+ __mainLoop.stop();
return G_SOURCE_REMOVE;
}
}
}
-static void __on_terminate()
-{
- try {
- auto unknown = std::current_exception();
- if (unknown) {
- std::rethrow_exception(unknown);
- }
- } catch (const std::exception& e) {
- _E(RED("Unexpected exception: %s"), e.what());
- } catch (...) {
- _E(RED("Unknown exception"));
- }
-}
-
-static void __on_new_failed()
-{
- static unsigned failCount = 0;
- _E_ALLOC;
- failCount += 1;
- if (failCount >= NEW_FAIL_LIMIT)
- throw std::bad_alloc();
-}
-
int main(int argc, char* argv[])
{
std::signal(SIGINT, __on_signal);
std::signal(SIGHUP, __on_signal);
std::signal(SIGTERM, __on_signal);
std::signal(SIGQUIT, __on_signal);
- std::signal(SIGABRT, __on_signal);
-
- std::set_terminate(__on_terminate);
- std::set_new_handler(__on_new_failed);
DBusConnector dbusConnector(__bus_acquired, __bus_lost);
- MainLoop::start();
+ __mainLoop.start();
return EXIT_SUCCESS;
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 <new>
+#include <exception>
+#include <stdexcept>
+#include "ServerBase.h"
+
+#define NEW_FAIL_LIMIT 3
+
+using namespace ctx;
+
+static void __on_terminate()
+{
+ try {
+ auto unknown = std::current_exception();
+ if (unknown) {
+ std::rethrow_exception(unknown);
+ }
+ } catch (const std::exception& e) {
+ _E(RED("Unexpected exception: %s"), e.what());
+ } catch (...) {
+ _E(RED("Unknown exception"));
+ }
+}
+
+static void __on_new_failed()
+{
+ static unsigned failCount = 0;
+ _E_ALLOC;
+ failCount += 1;
+ if (failCount >= NEW_FAIL_LIMIT)
+ throw std::bad_alloc();
+}
+
+MainLoop::MainLoop() :
+ __mainLoop(NULL)
+{
+ std::set_terminate(__on_terminate);
+ std::set_new_handler(__on_new_failed);
+}
+
+bool MainLoop::start()
+{
+ __mainLoop = g_main_loop_new(NULL, FALSE);
+ IF_FAIL_RETURN_TAG(__mainLoop, false, _E, E_STR_ALLOC);
+
+ _I(CYAN("Starting..."));
+ g_main_loop_run(__mainLoop);
+
+ g_main_loop_unref(__mainLoop);
+ __mainLoop = NULL;
+
+ return true;
+}
+
+void MainLoop::stop()
+{
+ if (__mainLoop && g_main_loop_is_running(__mainLoop)) {
+ _I(PURPLE("Terminating..."));
+ g_main_loop_quit(__mainLoop);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 __CONEXT_SERVER_BASE_H__
+#define __CONEXT_SERVER_BASE_H__
+
+#include <ContextTypes.h>
+
+namespace ctx {
+ class MainLoop {
+ public:
+ MainLoop();
+ bool start();
+ void stop();
+ private:
+ GMainLoop* __mainLoop;
+ };
+}
+
+#endif