diff options
Diffstat (limited to 'daemon/target.c')
-rw-r--r-- | daemon/target.c | 262 |
1 files changed, 262 insertions, 0 deletions
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; +} |