summaryrefslogtreecommitdiff
path: root/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'daemon')
-rw-r--r--daemon/Makefile3
-rw-r--r--daemon/da_inst.c6
-rw-r--r--daemon/da_inst.h3
-rw-r--r--daemon/da_protocol.c77
-rw-r--r--daemon/da_protocol.h8
-rw-r--r--daemon/daemon.c208
-rw-r--r--daemon/daemon.h16
-rw-r--r--daemon/main.c23
-rw-r--r--daemon/sys_stat.c18
-rw-r--r--daemon/target.c262
-rw-r--r--daemon/target.h90
-rw-r--r--daemon/threads.c79
-rw-r--r--daemon/threads.h5
13 files changed, 515 insertions, 283 deletions
diff --git a/daemon/Makefile b/daemon/Makefile
index 5698036..9e84161 100644
--- a/daemon/Makefile
+++ b/daemon/Makefile
@@ -46,7 +46,8 @@ DAEMON_SRCS = \
device_system_info.c \
device_camera.c \
smack.c \
- malloc_debug.c
+ malloc_debug.c \
+ target.c
DAEMON_OBJS = $(patsubst %.c,%.o, $(DAEMON_SRCS))
diff --git a/daemon/da_inst.c b/daemon/da_inst.c
index 47a597a..78446cd 100644
--- a/daemon/da_inst.c
+++ b/daemon/da_inst.c
@@ -631,17 +631,17 @@ static void generate_maps_inst_msg(struct user_space_inst_t *us_inst)
unlock_lib_maps_message();
}
-void send_maps_inst_msg_to(int sock)
+void send_maps_inst_msg_to(struct target *t)
{
lock_lib_maps_message();
- send_msg_to_target(sock, (struct msg_target_t *)lib_maps_message);
+ target_send_msg(t, (struct msg_target_t *)lib_maps_message);
unlock_lib_maps_message();
}
static void send_maps_inst_msg_to_all_targets()
{
lock_lib_maps_message();
- send_msg_to_all_targets(lib_maps_message);
+ target_send_msg_to_all(lib_maps_message);
unlock_lib_maps_message();
}
diff --git a/daemon/da_inst.h b/daemon/da_inst.h
index 9368f64..bf26b54 100644
--- a/daemon/da_inst.h
+++ b/daemon/da_inst.h
@@ -90,6 +90,7 @@ void free_data_list(struct data_list_t **data);
struct app_info_t *app_info_get_first(struct app_list_t **app_list);
struct app_info_t *app_info_get_next(struct app_list_t **app_list);
-void send_maps_inst_msg_to(int sock);
+struct target; // move
+void send_maps_inst_msg_to(struct target *t);
#endif /* __DA_INST_H__*/
diff --git a/daemon/da_protocol.c b/daemon/da_protocol.c
index 786ce19..86ffa3f 100644
--- a/daemon/da_protocol.c
+++ b/daemon/da_protocol.c
@@ -957,31 +957,57 @@ send_ack:
return -(err_code != ERR_NO);
}
-int send_msg_to_target(int sock, struct msg_target_t *msg)
+int send_msg_to_sock(int sock, struct msg_target_t *msg)
{
- if (sock != -1) {
- if (send(sock, msg, sizeof(struct _msg_target_t) + msg->length, MSG_NOSIGNAL) == -1)
- LOGE("fail to send data to target socket(%d)\n", sock);
- else
- return 1;
+ ssize_t ret;
+ size_t n;
+ int err = 0;
+
+ n = sizeof(struct _msg_target_t) + msg->length;
+ ret = send(sock, msg, n, MSG_NOSIGNAL);
+ if (ret != n) {
+ LOGE("fail to send data to socket(%d) n=%u, ret=%d\n",
+ sock, n, ret);
+ err = 1;
}
- return 0;
+
+ return err;
}
-int send_msg_to_all_targets(struct msg_target_t *msg)
+int recv_msg_from_sock(int sock, struct msg_target_t *msg)
{
- int target_index;
- int sock;
- for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++) {
- sock = manager.target[target_index].socket;
- if (sock != -1) {
- if (send(sock, msg, sizeof(struct _msg_target_t) + msg->length, MSG_NOSIGNAL) == -1)
- LOGE("fail to send data to target index(%d)\n",
- target_index);
- else
- return 1;
- }
+ ssize_t ret;
+
+ ret = recv(sock, msg, MSG_HEADER_LEN, MSG_WAITALL);
+ if (ret != MSG_HEADER_LEN)
+ return 1;
+
+ if (IS_PROBE_MSG(msg->type)) {
+ struct msg_data_t *msg_data = (struct msg_data_t *)msg;
+ size_t n = MSG_DATA_HDR_LEN - MSG_HEADER_LEN;
+
+ ret = recv(sock, (char *)msg_data + MSG_HEADER_LEN,
+ n, MSG_WAITALL);
+ if (ret != n)
+ return 1;
+
+ /* TODO: check msg_data->len */
+ ret = recv(sock, msg_data->payload,
+ msg_data->len, MSG_WAITALL);
+
+ if (ret != msg_data->len)
+ return 1;
+
+ return 0;
}
+
+ if (msg->length > 0) {
+ /* TODO: check msg->length */
+ ret = recv(sock, msg->data, msg->length, MSG_WAITALL);
+ if (ret != msg->length)
+ return 1;
+ }
+
return 0;
}
@@ -996,7 +1022,7 @@ static int process_msg_get_screenshot(struct msg_buf_t *msg_control)
sendlog.length = 0;
log_len = sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length;
- if (send_msg_to_all_targets(&sendlog) == 1)
+ if (target_send_msg_to_all(&sendlog) == 1)
err_code = ERR_NO;
return -(err_code != ERR_NO);
@@ -1168,16 +1194,7 @@ int host_message_handler(struct msg_t *msg)
sendlog.type = MSG_OPTION;
sendlog.length = sprintf(sendlog.data, "%llu",
(unsigned long long) prof_session.conf.use_features0);
- for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++)
- {
- if(manager.target[target_index].socket != -1)
- {
- if (0 > send(manager.target[target_index].socket, &sendlog,
- sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length,
- MSG_NOSIGNAL))
- LOGE("fail to send data to target index(%d)\n", target_index);
- }
- }
+ target_send_msg_to_all(&sendlog);
break;
case NMSG_BINARY_INFO:
return process_msg_binary_info(&msg_control);
diff --git a/daemon/da_protocol.h b/daemon/da_protocol.h
index b326e94..d4201f4 100644
--- a/daemon/da_protocol.h
+++ b/daemon/da_protocol.h
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <stddef.h>
#include <linux/input.h>
enum HostMessageT {
@@ -182,6 +183,9 @@ struct msg_target_t {
char data[DA_MSG_MAX];
};
+enum { MSG_HEADER_LEN = offsetof(struct msg_target_t, data) };
+
+
#define MAX_FILENAME 128
#define MSG_DATA_HDR_LEN 20
@@ -439,8 +443,8 @@ int check_running_status(const struct prof_session_t *prof_session);
extern struct prof_session_t prof_session;
-extern int send_msg_to_target(int sock, struct msg_target_t *msg);
-extern int send_msg_to_all_targets(struct msg_target_t *msg);
+int send_msg_to_sock(int sock, struct msg_target_t *msg);
+int recv_msg_from_sock(int sock, struct msg_target_t *msg);
//debugs
void print_replay_event(struct replay_event_t *ev, uint32_t num, char *tab);
diff --git a/daemon/daemon.c b/daemon/daemon.c
index d232a68..38acb2e 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
@@ -70,46 +70,6 @@
#define MAX_CONNECT_TIMEOUT_TIME 5*60
-uint64_t get_total_alloc_size_by_pid(pid_t pid)
-{
- int i;
-
- for (i = 0; i < MAX_TARGET_COUNT; i++) {
- if (manager.target[i].socket != -1 &&
- manager.target[i].pid == pid &&
- manager.target[i].allocmem > 0)
- return manager.target[i].allocmem;
- }
- return 0;
-}
-
-static int getEmptyTargetSlot()
-{
- int i;
- for (i = 0; i < MAX_TARGET_COUNT; i++) {
- if (manager.target[i].socket == -1)
- break;
- }
-
- return i;
-}
-
-static void setEmptyTargetSlot(int index)
-{
- if (index >= 0 && index < MAX_TARGET_COUNT) {
- manager.target[index].pid = -1;
- manager.target[index].recv_thread = -1;
- manager.target[index].allocmem = 0;
- manager.target[index].initial_log = 0;
- if (manager.target[index].event_fd != -1)
- close(manager.target[index].event_fd);
- manager.target[index].event_fd = -1;
- if (manager.target[index].socket != -1)
- close(manager.target[index].socket);
- manager.target[index].socket = -1;
- }
-}
-
// =============================================================================
// start and terminate control functions
// =============================================================================
@@ -276,41 +236,21 @@ static int exec_app(const struct app_info_t *app_info)
// just send stop message to all target process
static void terminate_all_target()
{
- int i;
- ssize_t sendlen;
- struct msg_target_t sendlog;
-
- sendlog.type = MSG_STOP;
- sendlog.length = 0;
-
- for (i = 0; i < MAX_TARGET_COUNT; i++) {
- if (manager.target[i].socket != -1) {
- sendlen = send(manager.target[i].socket, &sendlog,
- sizeof(sendlog.type) +
- sizeof(sendlog.length), MSG_NOSIGNAL);
- if (sendlen != -1) {
- LOGI("TERMINATE send exit msg (socket %d) "
- "by terminate_all_target()\n",
- manager.target[i].socket);
- }
- }
- }
+ struct msg_target_t msg = {
+ .type = MSG_STOP,
+ .length = 0
+ };
+
+ target_send_msg_to_all(&msg);
}
// terminate all target and wait for threads
void terminate_all()
{
- int i;
terminate_all_target();
// wait for all other thread exit
- for (i = 0; i < MAX_TARGET_COUNT; i++) {
- if (manager.target[i].recv_thread != -1) {
- LOGI("join recv thread [%d] is started\n", i);
- pthread_join(manager.target[i].recv_thread, NULL);
- LOGI("join recv thread %d. done\n", i);
- }
- }
+ target_wait_all();
}
// terminate all profiling by critical error
@@ -505,8 +445,6 @@ int reconfigure(struct conf_t conf)
return 0;
}
-static Ecore_Fd_Handler *target_handlers[MAX_TARGET_COUNT];
-
static int file2str(const char *filename, char *buf, int len)
{
@@ -528,13 +466,13 @@ static int file2str(const char *filename, char *buf, int len)
return num_read;
}
-static int get_lpad_pid(int pid)
+static pid_t get_lpad_pid(pid_t pid)
{
- static pid_t lpad_pid = -1;
+ static pid_t lpad_pid = UNKNOWN_PID;
static const char lpad_path[] = DEBUG_LAUNCH_PRELOAD_PATH;
enum { lpad_path_len = sizeof(lpad_path) };
- if (lpad_pid == -1) {
+ if (lpad_pid == UNKNOWN_PID) {
char fname[64];
char buf[lpad_path_len];
@@ -553,32 +491,34 @@ static int get_lpad_pid(int pid)
static pid_t get_current_pid(void)
{
- static pid_t pid = -1;
+ static pid_t pid = UNKNOWN_PID;
- if (pid == -1)
- pid = getpid();
+ if (pid == UNKNOWN_PID)
+ pid = getpid();
- return pid;
+ return pid;
}
-static void taget_set_type(__da_target_info *taget)
+static void target_set_type(struct target *t)
{
- if (get_current_pid() == taget->ppid) {
- taget->app_type = APP_TYPE_COMMON;
- } else if (get_lpad_pid(taget->ppid) == taget->ppid) {
- taget->app_type = APP_TYPE_TIZEN;
+ pid_t ppid = target_get_ppid(t);
+
+ if (get_current_pid() == ppid) {
+ t->app_type = APP_TYPE_COMMON;
+ } else if (get_lpad_pid(ppid) == ppid) {
+ t->app_type = APP_TYPE_TIZEN;
}
}
-static int target_event_pid_handler(int index, uint64_t msg)
+static int target_event_pid_handler(struct target *target)
{
struct app_list_t *app = NULL;
struct app_info_t *app_info = NULL;
- taget_set_type(&manager.target[index]);
+ target_set_type(target);
- if (index == 0) { // main application
+ if (0) { // main application (index == 0)
app_info = app_info_get_first(&app);
if (app_info == NULL) {
LOGE("No app info found\n");
@@ -587,14 +527,14 @@ static int target_event_pid_handler(int index, uint64_t msg)
while (app_info != NULL) {
if (is_same_app_process(app_info->exe_path,
- manager.target[index].pid))
+ target_get_pid(target)))
break;
app_info = app_info_get_next(&app);
}
if (app_info == NULL) {
LOGE("pid %d not found in app list\n",
- manager.target[index].pid);
+ target_get_pid(target));
return -1;
}
@@ -603,29 +543,30 @@ static int target_event_pid_handler(int index, uint64_t msg)
return -1;
}
}
- manager.target[index].initial_log = 1;
+
+ target->initial_log = 1;
+
return 0;
}
-static int target_event_stop_handler(int index, uint64_t msg)
+static int target_event_stop_handler(struct target *target)
{
int cnt;
+ enum app_type_t app_type = target->app_type;
- LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
- manager.target[index].socket, manager.target[index].pid,
- manager.target_count - 1);
+ LOGI("target[%p] close, pid(%d) : (remaining %d target)\n",
+ target, target_get_pid(target), target_cnt_get() - 1);
-
- if (index == 0) // main application
+ if (0) // main application (index == 0)
stop_replay();
- ecore_main_fd_handler_del(target_handlers[index]);
+ ecore_main_fd_handler_del(target->handler);
- setEmptyTargetSlot(index);
+ target_dtor(target);
// all target client are closed
- cnt = __sync_sub_and_fetch(&manager.target_count, 1);
+ cnt = target_cnt_sub_and_fetch();
if (0 == cnt) {
- switch (manager.target[index].app_type) {
+ switch (app_type) {
case APP_TYPE_TIZEN:
case APP_TYPE_COMMON:
LOGI("all targets are stopped\n");
@@ -642,16 +583,16 @@ static int target_event_stop_handler(int index, uint64_t msg)
// return plus value if non critical error occur
// return minus value if critical error occur
// return -11 if all target process closed
-static int target_event_handler(int index, uint64_t msg)
+static int target_event_handler(struct target *t, uint64_t msg)
{
int err = 0;
if (msg & EVENT_PID)
- err = target_event_pid_handler(index, msg);
+ err = target_event_pid_handler(t);
if (err)
return err;
if (msg & EVENT_STOP || msg & EVENT_ERROR)
- err = target_event_stop_handler(index, msg);
+ err = target_event_stop_handler(t);
return err;
}
@@ -660,14 +601,14 @@ static Eina_Bool target_event_cb(void *data, Ecore_Fd_Handler *fd_handler)
{
uint64_t u;
ssize_t recvLen;
- int index = (int)data;
+ struct target *target = (struct target *)data;
- recvLen = read(manager.target[index].event_fd, &u, sizeof(uint64_t));
+ recvLen = read(target->event_fd, &u, sizeof(uint64_t));
if (recvLen != sizeof(uint64_t)) {
// maybe closed, but ignoring is more safe then
// removing fd from event loop
} else {
- if (-11 == target_event_handler(index, u)) {
+ if (-11 == target_event_handler(target, u)) {
LOGI("all target process is closed\n");
}
}
@@ -682,60 +623,53 @@ static Eina_Bool target_event_cb(void *data, Ecore_Fd_Handler *fd_handler)
*/
static int targetServerHandler(void)
{
+ int err;
struct msg_target_t log;
+ struct target *target;
- int index = getEmptyTargetSlot();
- if (index == MAX_TARGET_COUNT) {
- LOGW("Max target number(8) reached, no more target can connected\n");
+ target = target_ctor();
+ if (target == NULL) {
+ LOGW("(target == NULL) no more target can connected\n");
return 1;
}
- manager.target[index].socket =
- accept4(manager.target_server_socket, NULL, NULL, SOCK_CLOEXEC);
-
- if (manager.target[index].socket >= 0) {
- /* accept succeed */
- fd_setup_attributes(manager.target[index].socket);
-
+ err = target_accept(target, manager.target_server_socket);
+ if (err == 0) {
/* send config message to target process */
log.type = MSG_OPTION;
log.length = sprintf(log.data, "%llu\0",
prof_session.conf.use_features0) + 1;
- if (0 > send(manager.target[index].socket, &log,
- sizeof(log.type) + sizeof(log.length) + log.length,
- MSG_NOSIGNAL))
- LOGE("fail to send data to target index(%d)\n", index);
+ if (target_send_msg(target, &log) != 0)
+ LOGE("fail to send data to target %p\n", target);
/* send current instrument maps */
- send_maps_inst_msg_to(manager.target[index].socket);
+ send_maps_inst_msg_to(target);
// make event fd
- manager.target[index].event_fd = eventfd(EFD_CLOEXEC, EFD_NONBLOCK);
- if (manager.target[index].event_fd == -1) {
+ target->event_fd = eventfd(EFD_CLOEXEC, EFD_NONBLOCK);
+ if (target->event_fd == -1) {
// fail to make event fd
- LOGE("fail to make event fd for socket (%d)\n",
- manager.target[index].socket);
+ LOGE("fail to make event fd for target[%p]\n", target);
goto TARGET_CONNECT_FAIL;
}
- target_handlers[index] =
- ecore_main_fd_handler_add(manager.target[index].event_fd,
+ target->handler =
+ ecore_main_fd_handler_add(target->event_fd,
ECORE_FD_READ,
target_event_cb,
- (void *)index,
+ (void *)target,
NULL, NULL);
- if (!target_handlers[index]) {
- LOGE("fail to add event fd for socket (%d)\n",
- manager.target[index].socket);
+ if (!target->handler) {
+ LOGE("fail to add event fd for target[%p]\n", target);
goto TARGET_CONNECT_FAIL;
}
// make recv thread for target
- if (makeRecvThread(index) != 0) {
+ if (makeRecvThread(target) != 0) {
// fail to make recv thread
- LOGE("fail to make recv thread for socket (%d)\n",
- manager.target[index].socket);
- ecore_main_fd_handler_del(target_handlers[index]);
+ LOGE("fail to make recv thread for target[%p]\n",
+ target);
+ ecore_main_fd_handler_del(target->handler);
goto TARGET_CONNECT_FAIL;
}
@@ -746,10 +680,10 @@ static int targetServerHandler(void)
LOGE("cannot stop app launch timer\n");
}
- LOGI("target connected = %d(running %d target)\n",
- manager.target[index].socket, manager.target_count + 1);
+ LOGI("target connected target[%p](running %d target)\n",
+ target, target_cnt_get() + 1);
- manager.target_count++;
+ target_cnt_set(target_cnt_get() + 1);
return 0;
} else {
// accept error
@@ -757,12 +691,12 @@ static int targetServerHandler(void)
}
TARGET_CONNECT_FAIL:
- if (manager.target_count == 0) {
+ if (target_cnt_get() == 0) {
// if this connection is main connection
return -1;
} else {
// if this connection is not main connection then ignore process by error
- setEmptyTargetSlot(index);
+ target_dtor(target);
return 1;
}
}
diff --git a/daemon/daemon.h b/daemon/daemon.h
index f3749a4..8c10637 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -36,6 +36,7 @@
#include <stdint.h> // for uint64_t, int64_t
#include <pthread.h> // for pthread_mutex_t
#include "da_protocol.h"
+#include "target.h"
#ifdef __cplusplus
extern "C" {
@@ -142,18 +143,6 @@ typedef struct
typedef struct
{
- int64_t allocmem; // written only by recv thread
- pid_t pid; // written only by recv thread
- pid_t ppid; // written only by recv thread
- int socket; // written only by main thread
- pthread_t recv_thread; // written only by main thread
- int event_fd; // for thread communication (from recv thread to main thread)
- int initial_log; // written only by main thread
- enum app_type_t app_type;
-} __da_target_info;
-
-typedef struct
-{
int brightness;
int voltage;
int procmeminfo;
@@ -168,7 +157,6 @@ typedef struct
{
int host_server_socket;
int target_server_socket;
- int target_count;
int apps_to_run;
unsigned int config_flag;
int app_launch_timerfd;
@@ -180,7 +168,6 @@ typedef struct
int user_ev_fd;
int efd;
__da_host_info host;
- __da_target_info target[MAX_TARGET_COUNT];
__file_descriptors fd;
char appPath[128]; // application executable path
} __da_manager;
@@ -193,7 +180,6 @@ void initialize_log(void);
int daemonLoop(void);
void unlink_portfile(void);
-int makeRecvThread(int index);
int samplingStart(void);
int samplingStop(void);
diff --git a/daemon/main.c b/daemon/main.c
index 42d6aec..cb182f4 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -64,7 +64,6 @@ __da_manager manager =
{
.host_server_socket = -1,
.target_server_socket = -1,
- .target_count = 0,
.apps_to_run = 0,
.config_flag = 0,
.app_launch_timerfd = -1,
@@ -82,9 +81,6 @@ __da_manager manager =
.data_socket_mutex = PTHREAD_MUTEX_INITIALIZER
},
- .target = {
- {0L, },
- },
.fd = {
.brightness = -1,
.voltage = -1,
@@ -265,22 +261,9 @@ static bool ensure_singleton(const char *lockfile)
return locked;
}
-static void inititialize_manager_targets(__da_manager * mng)
+static void inititialize_manager_targets(void)
{
- int index;
- __da_target_info target_init_value = {
- .pid = -1,
- .socket = -1,
- .event_fd = -1,
- .recv_thread = -1,
- .initial_log = 0,
- .allocmem = 0
- };
-
- for (index = 0; index < MAX_TARGET_COUNT; index++)
- mng->target[index] = target_init_value;
-
- manager.target_count = 0;
+ target_cnt_set(0);
}
static bool initialize_pthread_sigmask()
@@ -325,7 +308,7 @@ static int initializeManager(FILE *portfile)
LOGI("SUCCESS to write port\n");
- inititialize_manager_targets(&manager);
+ inititialize_manager_targets();
// initialize sendMutex
pthread_mutex_init(&(manager.host.data_socket_mutex), NULL);
diff --git a/daemon/sys_stat.c b/daemon/sys_stat.c
index 2bfa04f..abd1fb5 100644
--- a/daemon/sys_stat.c
+++ b/daemon/sys_stat.c
@@ -1803,22 +1803,6 @@ static int get_other_pid_array(pid_t inst_pid[], const int inst_n, pid_t arr[],
return count;
}
-static pid_t get_first_target_process(void)
-{
- pid_t pid = -1;
- int i;
-
- for (i = 0; i < MAX_TARGET_COUNT; i++) {
- if (manager.target[i].socket != -1 &&
- manager.target[i].pid != -1) {
- pid = manager.target[i].pid;
- break;
- }
- }
-
- return pid;
-}
-
// return log length (>0) for normal case
// return negative value for error
int get_system_info(struct system_info_t *sys_info)
@@ -2241,7 +2225,7 @@ struct msg_data_t *pack_system_info(struct system_info_t *sys_info)
pack_int64(p, (uint64_t)proc->proc_data.pss);
/* TODO total alloc for not ld preloaded processes */
- pack_int64(p, (uint64_t)get_total_alloc_size_by_pid(proc->proc_data.pid));
+ pack_int64(p, target_get_total_alloc(proc->proc_data.pid));
//pack threads
if (IS_OPT_SET(FL_SYSTEM_THREAD_LOAD)) {
diff --git a/daemon/target.c b/daemon/target.c
new file mode 100644
index 0000000..471d4e6
--- /dev/null
+++ b/daemon/target.c
@@ -0,0 +1,262 @@
+/*
+ * DA manager
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ * 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.
+ *
+ * Contributors:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+
+#define _GNU_SOURCE /* for accept4() */
+#include <sys/socket.h>
+
+#include "target.h"
+
+#include "daemon.h" // for manager (it is need delete)
+#include "smack.h"
+#include "debug.h"
+
+
+static struct target *target_malloc(void);
+static void target_free(struct target *t);
+
+struct target *target_ctor(void)
+{
+ struct target *t;
+
+ t = target_malloc();
+ if (t) {
+ t->pid = UNKNOWN_PID;
+ t->socket = UNKNOWN_FD;
+ t->event_fd = UNKNOWN_FD;
+ t->recv_thread = 0;
+ t->initial_log = 0;
+ t->allocmem = 0;
+ }
+
+ return t;
+}
+
+void target_dtor(struct target *t)
+{
+ t->recv_thread = -1;
+ t->allocmem = 0;
+ t->initial_log = 0;
+
+ if (t->event_fd != -1)
+ close(t->event_fd);
+ t->event_fd = -1;
+
+ if (t->socket != UNKNOWN_FD)
+ close(t->socket);
+ t->socket = -1;
+
+ target_free(t);
+}
+
+
+int target_accept(struct target *t, int sockfd)
+{
+ int sock;
+
+ sock = accept4(sockfd, NULL, NULL, SOCK_CLOEXEC);
+ if (sock == UNKNOWN_FD)
+ return 1;
+
+ /* accept succeed */
+ fd_setup_attributes(sock);
+
+ t->socket = sock;
+
+ return 0;
+}
+
+int target_send_msg(struct target *t, struct msg_target_t *msg)
+{
+ return send_msg_to_sock(t->socket, msg);
+}
+
+int target_recv_msg(struct target *t, struct msg_target_t *msg)
+{
+ return recv_msg_from_sock(t->socket, msg);
+}
+
+
+int target_start(struct target *t, void *(*start_routine) (void *))
+{
+ return pthread_create(&t->recv_thread, NULL, start_routine, (void *)t);
+}
+
+int target_wait(struct target *t)
+{
+ return pthread_join(t->recv_thread, NULL);
+}
+
+
+pid_t target_get_pid(struct target *t)
+{
+ return t->pid;
+}
+
+void target_set_pid(struct target *t, pid_t pid)
+{
+ t->pid = pid;
+}
+
+pid_t target_get_ppid(struct target *t)
+{
+ return t->ppid;
+}
+
+void target_set_ppid(struct target *t, pid_t ppid)
+{
+ t->ppid = ppid;
+}
+
+static int target_cnt = 0;
+static pthread_mutex_t ts_mutex = PTHREAD_MUTEX_INITIALIZER;
+static int target_use[MAX_TARGET_COUNT] = {0};
+static struct target target_array[MAX_TARGET_COUNT];
+
+static void target_array_lock(void)
+{
+ pthread_mutex_lock(&ts_mutex);
+}
+
+static void target_array_unlock(void)
+{
+ pthread_mutex_unlock(&ts_mutex);
+}
+
+static struct target *target_malloc(void)
+{
+ int i;
+ struct target *t = NULL;
+
+ target_array_lock();
+ for (i = 0; i < MAX_TARGET_COUNT; i++) {
+ if (target_use[i] == 0) {
+ target_use[i] = 1;
+ t = &target_array[i];
+ break;
+ }
+ }
+ target_array_unlock();
+
+ return t;
+}
+
+static void target_free(struct target *t)
+{
+ target_array_lock();
+ target_use[t - target_array] = 0;
+ target_array_unlock();
+}
+
+
+void target_cnt_set(int cnt)
+{
+ target_cnt = cnt;
+}
+
+int target_cnt_get(void)
+{
+ return target_cnt;
+}
+
+int target_cnt_sub_and_fetch(void)
+{
+ return __sync_sub_and_fetch(&target_cnt, 1);
+}
+
+
+struct target *target_get(int i)
+{
+ return &target_array[i];
+}
+
+
+
+
+
+/*
+ * for all targets
+ */
+int target_send_msg_to_all(struct msg_target_t *msg)
+{
+ int i, ret = 0;
+ struct target *t;
+
+ target_array_lock();
+ for (i = 0; i < MAX_TARGET_COUNT; ++i) {
+ if (target_use[i] == 0)
+ continue;
+
+ t = target_get(i);
+ if (target_send_msg(t, msg))
+ ret = 1;
+ }
+ target_array_unlock();
+
+ return ret;
+}
+
+void target_wait_all(void)
+{
+ int i;
+ struct target *t;
+
+ target_array_lock();
+ for (i = 0; i < MAX_TARGET_COUNT; ++i) {
+ if (target_use[i] == 0)
+ continue;
+
+ t = target_get(i);
+
+ LOGI("join recv thread [%d] is started\n", i);
+ target_wait(t);
+ LOGI("join recv thread %d. done\n", i);
+ }
+ target_array_unlock();
+}
+
+uint64_t target_get_total_alloc(pid_t pid)
+{
+ int i;
+ uint64_t ret = 0;
+ struct target *t;
+
+ target_array_lock();
+ for (i = 0; i < MAX_TARGET_COUNT; i++) {
+ if (target_use[i] == 0)
+ continue;
+
+ t = target_get(i);
+ if (target_get_pid(t) == pid) {
+ ret = t->allocmem;
+ goto unlock;
+ }
+ }
+unlock:
+ target_array_lock();
+
+ return ret;
+}
diff --git a/daemon/target.h b/daemon/target.h
new file mode 100644
index 0000000..e30ea25
--- /dev/null
+++ b/daemon/target.h
@@ -0,0 +1,90 @@
+/*
+ * DA manager
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ * 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.
+ *
+ * Contributors:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+
+#ifndef _TARGER_H_
+#define _TARGER_H_
+
+
+#include <inttypes.h>
+#include <pthread.h>
+
+#include <Ecore.h>
+
+#include "da_protocol.h"
+
+
+#define UNKNOWN_PID ((pid_t)(-1))
+#define UNKNOWN_FD (-1)
+
+
+struct target {
+ enum app_type_t app_type; /* calculated when connecting */
+ int64_t allocmem; /* written only by recv thread */
+ pid_t pid; /* written only by recv thread */
+ pid_t ppid; /* written only by recv thread */
+ int socket; /* written only by main thread */
+ pthread_t recv_thread; /* written only by main thread */
+ int event_fd; /* for thread communication
+ * (from recv thread to main thread) */
+ int initial_log; /* written only by main thread */
+ Ecore_Fd_Handler *handler; /* calculated when connecting */
+};
+
+
+struct target *target_ctor(void);
+void target_dtor(struct target *t);
+
+int target_accept(struct target *t, int sockfd);
+
+int target_send_msg(struct target *t, struct msg_target_t *msg);
+int target_recv_msg(struct target *t, struct msg_target_t *msg);
+
+
+int target_start(struct target *t, void *(*start_routine) (void *));
+int target_wait(struct target *t);
+
+
+pid_t target_get_pid(struct target *t);
+void target_set_pid(struct target *t, pid_t pid);
+
+pid_t target_get_ppid(struct target *t);
+void target_set_ppid(struct target *t, pid_t ppid);
+
+
+void target_cnt_set(int cnt);
+int target_cnt_get(void);
+int target_cnt_sub_and_fetch(void);
+
+struct target *target_get(int i);
+
+/* for all targets */
+int target_send_msg_to_all(struct msg_target_t *msg);
+void target_wait_all(void);
+uint64_t target_get_total_alloc(pid_t pid);
+
+
+#endif /* _TARGER_H_ */
diff --git a/daemon/threads.c b/daemon/threads.c
index 7797ba3..3cbd85a 100644
--- a/daemon/threads.c
+++ b/daemon/threads.c
@@ -46,67 +46,38 @@
#include "da_protocol.h"
#include "da_data.h"
+#include "da_inst.h"
#include "debug.h"
#include "buffer.h"
#include "input_events.h"
static void* recvThread(void* data)
{
- __da_target_info *target = data;
+ struct target *target = data;
int pass = 0;
uint64_t event;
- ssize_t recvLen;
struct msg_target_t log;
+ int err;
// initialize target variable
- target->pid = -1;
target->allocmem = 0;
- while(1)
- {
- // read from target process
- recvLen = recv(target->socket, &log,
- sizeof(log.type) + sizeof(log.length),
- MSG_WAITALL);
-
- if(unlikely(recvLen < sizeof(log.type) + sizeof(log.length)))
- { // disconnect
+ for (;;) {
+ err = target_recv_msg(target, &log);
+ if (err != 0) {
+ /* disconnect */
event = EVENT_STOP;
- write(target->event_fd, &event, sizeof(uint64_t));
+ write(target->event_fd, &event, sizeof(event));
break;
}
+
if (IS_PROBE_MSG(log.type)) {
- struct msg_data_t tmp_msg;
- int offs = sizeof(log.type) + sizeof(log.length);
-
- recvLen = recv(target->socket,
- (char *)&log + offs,
- MSG_DATA_HDR_LEN - offs,
- MSG_WAITALL);
- memcpy(&tmp_msg, &log, MSG_DATA_HDR_LEN);
- struct msg_data_t *msg = malloc(MSG_DATA_HDR_LEN +
- tmp_msg.len);
- memcpy(msg, &tmp_msg, MSG_DATA_HDR_LEN);
- recvLen = recv(target->socket,
- (char *)msg + MSG_DATA_HDR_LEN,
- msg->len, MSG_WAITALL);
- if (write_to_buf(msg) != 0)
+ struct msg_data_t *msg_data = (struct msg_data_t *)&log;
+
+ if (write_to_buf(msg_data) != 0)
LOGE("write to buf fail\n");
- free(msg);
- continue;
- }
- // send to host
- if (likely(log.length > 0))
- {
- recvLen = recv(target->socket, log.data, log.length,
- MSG_WAITALL);
- if(unlikely((recvLen == -1) || (recvLen != log.length))) // consume as disconnect
- {
- event = EVENT_STOP;
- write(target->event_fd, &event, sizeof(uint64_t));
- break;
- }
+ continue;
}
log.data[log.length] = '\0';
@@ -120,8 +91,7 @@ static void* recvThread(void* data)
LOGI("MSG_PID arrived (pid ppid): %s\n", log.data);
// only when first MSG_PID is arrived
- if(target->pid == -1)
- {
+ if (target_get_pid(target) == UNKNOWN_PID) {
int n;
pid_t pid, ppid;
@@ -140,19 +110,20 @@ static void* recvThread(void* data)
}
/* set pid and ppid */
- target->pid = pid;
- target->ppid = ppid;
+ target_set_pid(target, pid);
+ target_set_ppid(target, ppid);
/* send event */
event = EVENT_PID;
write(target->event_fd, &event, sizeof(uint64_t));
}
- send_maps_inst_msg_to(target->socket);
+ send_maps_inst_msg_to(target);
continue; // don't send to host
}
else if(log.type == MSG_TERMINATE)
{
- LOGI("MSG_TERMINATE arrived: pid[%d]\n", target->pid);
+ LOGI("MSG_TERMINATE arrived: pid[%d]\n",
+ target_get_pid(target));
// send stop message to main thread
event = EVENT_STOP;
@@ -214,16 +185,10 @@ static void* recvThread(void* data)
return NULL;
}
-int makeRecvThread(int index)
+int makeRecvThread(struct target *target)
{
- if (manager.target[index].socket == -1)
- return -1;
-
- if (pthread_create(&(manager.target[index].recv_thread),
- NULL, recvThread, &manager.target[index]) < 0)
- {
- LOGE("Failed to create recv thread for socket (%d)\n",
- manager.target[index].socket);
+ if (target_start(target, recvThread) < 0) {
+ LOGE("Failed to create recv thread\n");
return -1;
}
diff --git a/daemon/threads.h b/daemon/threads.h
index 6569e3a..ea4a670 100644
--- a/daemon/threads.h
+++ b/daemon/threads.h
@@ -38,6 +38,11 @@ extern "C" {
#endif
+struct target;
+
+
+int makeRecvThread(struct target *target);
+
#ifdef __cplusplus
}