Fix manager aborting 39/167439/5
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 17 Jan 2018 15:24:19 +0000 (18:24 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 18 Jan 2018 17:46:39 +0000 (20:46 +0300)
Solution: join host control thread.

Change-Id: Ie2b91accf58c91cd3a9ce76d1c2017d1ee3ca521
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
daemon/da_protocol.c
daemon/daemon.c
daemon/daemon.h
daemon/main.c

index b8c8d82fbfb3591b476b531a6bcbdbf3b3e46e6e..f866368f8315196395967fc1eae34abe6fba7ecb 100644 (file)
@@ -572,7 +572,7 @@ static size_t str_array_getsize(const char **strings, size_t len)
 static int send_reply(struct msg_t *msg)
 {
        printBuf((char *)msg, msg->len + sizeof (*msg));
-       if (send(manager.host.control_socket,
+       if (send(manager.host.control.socket,
                 msg, MSG_CMD_HDR_LEN + msg->len, MSG_NOSIGNAL) == -1) {
                GETSTRERROR(errno, buf);
                LOGE("Cannot send reply : %s\n", buf);
@@ -612,6 +612,7 @@ static enum HostMessageT get_ack_msg_id(const enum HostMessageT id)
 int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
                        char *payload, int payload_size)
 {
+       assert(manager.host.control.status == HCS_RUNNING);
        int ret = 1; /* error by default */
        struct msg_t *msg = NULL;
        uint32_t err = err_code;
@@ -620,11 +621,6 @@ int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
                                 payload_size;
        char *p;
 
-       if (manager.host.control_socket == -1) {
-               LOGE("no connection\n");
-               goto exit;
-       }
-
        msg = malloc(loglen);
        if (msg == NULL) {
                LOGE("Cannot allocates memory for msg\n");
@@ -649,7 +645,7 @@ int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
        printBuf((char *)msg, loglen);
 
        /* TODO FIXME What the hell is going around? This shouldn't be this way */
-       if (send(manager.host.control_socket, msg,
+       if (send(manager.host.control.socket, msg,
                 loglen, MSG_NOSIGNAL) == -1) {
                GETSTRERROR(errno, buf);
 //             LOGE("Cannot send reply: %s\n", buf);
index 394a03cae6635d88c62c89df8ca47c88088a205b..fda9f53b95365415696f40fc3311f65e81022879 100644 (file)
@@ -878,7 +878,7 @@ static void *host_control_sock_thread(void *args)
                        manager.connect_timeout_timerfd = -1;
                }
                /* Receive header */
-               recv_len = recv(manager.host.control_socket,
+               recv_len = recv(manager.host.control.socket,
                                &msg_head, MSG_CMD_HDR_LEN, 0);
 
                /* error or close request from host */
@@ -895,7 +895,7 @@ static void *host_control_sock_thread(void *args)
                if (msg_head.len > HOST_CTL_MSG_MAX_LEN) {
                        LOGE("Too long message. MSG_ID = 0x%08X; size = %u\n",
                             msg_head.id, msg_head.len);
-                       recv_msg_tail(manager.host.control_socket, msg_head.len);
+                       recv_msg_tail(manager.host.control.socket, msg_head.len);
                        sendACKToHost(msg_head.id, ERR_TO_LONG_MESSAGE, 0, 0);
                        continue;
                }
@@ -905,7 +905,7 @@ static void *host_control_sock_thread(void *args)
                if (!msg) {
                        LOGE("Cannot alloc msg. MSG_ID = 0x%08X; size = %u\n",
                             msg_head.id, msg_head.len);
-                       recv_msg_tail(manager.host.control_socket, msg_head.len);
+                       recv_msg_tail(manager.host.control.socket, msg_head.len);
                        sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
                        continue;
                }
@@ -914,7 +914,7 @@ static void *host_control_sock_thread(void *args)
                msg->len = msg_head.len;
                if (msg->len > 0) {
                        /* Receive payload (if exists) */
-                       recv_len = recv(manager.host.control_socket,
+                       recv_len = recv(manager.host.control.socket,
                                        msg->payload, msg->len, MSG_WAITALL);
                        if (recv_len == -1 || recv_len == 0) {
                                LOGW("error or close request from host. "
@@ -930,15 +930,11 @@ static void *host_control_sock_thread(void *args)
                free(msg);
        }
 
-       /*  connection closed */
-       LOGI("Connection closed. Termination. (%d)\n",
-            manager.host.control_socket);
        /* splice will fail without next cmd */
        manager.host.data_socket = -1;
        stop_all();
        evloop_stop(g_loop);
 
-       manager.host.control_socket = -1;
        LOGI("Control socket thread finished\n");
        return NULL;
 }
@@ -960,6 +956,62 @@ static void host_data_cb(const struct evloop_handler *handler, void *data)
        LOGI("host message from data socket %d\n", recvLen);
 }
 
+static int host_control_thread_create(struct host_control *control, int socket)
+{
+       int ret = 0;
+
+       pthread_mutex_lock(&control->mutex);
+       if (control->status != HCS_READY) {
+               LOGE("Host control thread does not ready starting, status=%d\n",
+                    control->status);
+               ret = -1;
+               goto unlock;
+       }
+
+       if (pthread_create(&control->thread,
+                          NULL,
+                          host_control_sock_thread,
+                          NULL) < 0) {
+               LOGE("Failed to create host control thread\n");
+               ret = -1;
+               goto unlock;
+       }
+       control->socket = socket;
+       control->status = HCS_RUNNING;
+
+unlock:
+       pthread_mutex_unlock(&control->mutex);
+       return ret;
+}
+
+static void host_control_thread_destroy(struct host_control *control)
+{
+       int ret = 0;
+       void *retval;
+
+       pthread_mutex_lock(&control->mutex);
+       if (control->status == HCS_READY) {
+               /* do nothing */
+               goto unlock;
+       } else if (control->status == HCS_FINISH) {
+               LOGE("Host control already finished\n");
+               ret = -1;
+               goto unlock;
+       }
+
+       ret = pthread_join(control->thread, &retval);
+       if (ret == 0) {
+               control->status = HCS_FINISH;
+               close(control->socket);
+       } else {
+               LOGE("Cannot join host control thread, err=%d\n", ret);
+               abort();
+       }
+
+unlock:
+       pthread_mutex_unlock(&control->mutex);
+}
+
 // return 0 if normal case
 // return plus value if non critical error occur
 // return minus value if critical error occur
@@ -977,24 +1029,15 @@ static int hostServerHandler(void)
                // accept succeed
 
                if (hostserverorder == 0) {
-                       manager.host.control_socket = csocket;
                        portfile_reset();
                        LOGI("host control socket connected = %d\n", csocket);
 
-                       if (manager.host_control_sock_thread != -1) {
-                               LOGI("replay already started\n");
-                               return -1;
-                       }
-
-                       if (pthread_create(&(manager.host_control_sock_thread),
-                                          NULL,
-                                          host_control_sock_thread,
-                                          NULL) < 0)
-                       {
-                               LOGE("Failed to create replay thread\n");
+                       if (host_control_thread_create(&manager.host.control,
+                                                      csocket)) {
+                               close(csocket);
+                               LOGE("Cannot create host control thread\n");
                                return -1;
                        }
-
                } else {
                        manager.host.data_socket = csocket;
                        LOGI("host data socket connected = %d\n", csocket);
@@ -1102,6 +1145,7 @@ int daemon_init(void)
 
 void daemon_uninit(void)
 {
+       host_control_thread_destroy(&manager.host.control);
        evloop_destroy(g_loop);
        g_loop = NULL;
 }
index 872c749cc7e17ad97b7ed97d0a0d440a32ff2f13..9c6c715427743d2a7a75a6634118bb9aa6632acd 100644 (file)
@@ -98,9 +98,22 @@ enum DAState
 #define STR_VALUE_E(x) #x
 #define STR_VALUE(x) STR_VALUE_E(x)
 
+enum host_control_status {
+       HCS_READY,
+       HCS_RUNNING,
+       HCS_FINISH,
+};
+
+struct host_control {
+       enum host_control_status status;
+       pthread_mutex_t mutex;
+       pthread_t thread;
+       int socket;
+};
+
 typedef struct
 {
-       int                                     control_socket;
+       struct host_control control;
        int                                     data_socket;
        pthread_mutex_t         data_socket_mutex;
 } __da_host_info;
@@ -134,7 +147,6 @@ typedef struct
        pthread_t sampling_thread;
        pthread_t replay_thread;
        pthread_t transfer_thread;
-       pthread_t host_control_sock_thread;
        int buf_fd;
        int user_ev_fd;
        int lockfd;
index cae9aeac6ee6a7b3e49a3e168579f75b3a9f6f16..d1f5882814186212ec74c00a6a5285fae06ec4a3 100644 (file)
@@ -78,13 +78,15 @@ __da_manager manager =
        .sampling_thread = -1,
        .replay_thread = -1,
        .transfer_thread = -1,
-       .host_control_sock_thread = -1,
        .buf_fd = -1,
        .user_ev_fd = -1,
        .lockfd = -1,
 
        .host = {
-               .control_socket = -1,
+               .control = {
+                       .status = HCS_READY,
+                       .mutex = PTHREAD_MUTEX_INITIALIZER,
+               },
                .data_socket = -1,
                .data_socket_mutex = PTHREAD_MUTEX_INITIALIZER
        },
@@ -493,10 +495,6 @@ static int finalizeManager()
        finalize_system_info();
 
        // close host client socket
-       if(manager.host.control_socket != -1){
-               LOGI("close host control socket (%d)\n", manager.host.control_socket);
-               close(manager.host.control_socket);
-       }
        if(manager.host.data_socket != -1){
                LOGI("close host data socket (%d)\n", manager.host.data_socket);
                close(manager.host.data_socket);