[FIX] wsi crash, deadlock 04/48704/7
authorVitaliy Cherepanov <v.cherepanov@samsung.com>
Fri, 25 Sep 2015 07:06:06 +0000 (10:06 +0300)
committerVitaliy Cherepanov <v.cherepanov@samsung.com>
Mon, 28 Sep 2015 12:53:41 +0000 (15:53 +0300)
Change-Id: I18174cc7071b6d3283db33996dbc02cff87d6d36
Signed-off-by: Vitaliy Cherepanov <v.cherepanov@samsung.com>
daemon/swap_debug.h
daemon/wsi.c

index ff6608d..d49d6c2 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef _DAEMON_DEBUG_H_
 #define _DAEMON_DEBUG_H_
 
+#include <sys/syscall.h>
 #include <stdint.h>            // for uint64_t, int64_t
 #include <pthread.h>   // for pthread_mutex_t
 #include <stdarg.h>
@@ -96,7 +97,10 @@ static inline void do_log(const char *prefix, const char *funcname, int line, ..
 {
        va_list ap;
        const char *fmt;
-       fprintf(stderr, "[%s][%f] (%s:%d):", prefix, get_uptime(), funcname, line);
+       fprintf(stderr, "[%s][%f] PID %u:%u (%s:%d):", prefix, get_uptime(),
+               (unsigned int)getpid(),
+               (unsigned int)syscall(SYS_gettid),
+               funcname, line);
 
        va_start(ap, line);
        fmt = va_arg(ap, const char *);
index f925c99..fab3896 100644 (file)
 #define CLRSTAT(S, F)                          ((S) &= ~(F))
 #define CHKSTAT(S, F)                          (((S) & (F)) ? 1: 0)
 
+
+#define LOG_STATUS LOGW(">>>>> state : %s %s %s %s %s %s\n",\
+       CHKSTAT(pstate, PSTATE_DEFAULT)?"PSTATE_DEFAULT":"",\
+       CHKSTAT(pstate, PSTATE_CONNECTED)?"PSTATE_CONNECTED":"",\
+       CHKSTAT(pstate, PSTATE_PROFILING)?"PSTATE_PROFILING":"",\
+       CHKSTAT(pstate, PSTATE_WAIT_ACK)?"PSTATE_WAIT_ACK":"",\
+       CHKSTAT(pstate, PSTATE_TIMEOUT)?"PSTATE_TIMEOUT":"",\
+       CHKSTAT(pstate, PSTATE_START)?"PSTATE_START":"",\
+       CHKSTAT(pstate, PSTATE_DISCONNECT)?"PSTATE_DISCONNECT":"")
+
+
 enum protocol_names {
        PROTOCOL_PROFILING
 };
@@ -72,6 +83,7 @@ int pstate = PSTATE_DEFAULT;
 int request_id = 1;
 
 pthread_t wsi_start_thread = -1;
+pthread_t wsi_handle_thread = -1;
 
 static void wsi_destroy(void);
 
@@ -151,15 +163,13 @@ int wsi_set_smack_rules(const struct app_info_t *app_info)
        char *package_id;
        size_t id_maxlen = 128;
 
-       app_id = malloc(sizeof(char) * (strnlen(app_info->app_id, id_maxlen) + 1));
-
+       app_id = strndup(app_info->app_id, id_maxlen);
        if (app_id == NULL) {
-               LOGE("app id alloc error\n");
-               ret = 1;
+               LOGE("cannot allocate memory\n");
+               ret = -ENOMEM;
                goto exit;
        }
 
-       strcpy(app_id, app_info->app_id);
        package_id = strtok(app_id, delim);
 
        if (package_id != NULL) {
@@ -206,6 +216,7 @@ static void send_request(const char *method)
        char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_REQUEST_LENGTH +
                 LWS_SEND_BUFFER_POST_PADDING];
        const char *payload;
+       size_t payload_len = 0;
 
        jobj = json_object_new_object();
        if (jobj == NULL) {
@@ -223,16 +234,22 @@ static void send_request(const char *method)
                LOGE("cannot parse json object (method: %s)\n", method);
                return;
        }
-       strncpy(buf, payload, MAX_REQUEST_LENGTH);
 
-       if (libwebsocket_write(wsi, (unsigned char *)buf, strlen(payload),
+       payload_len = strnlen(payload, MAX_REQUEST_LENGTH);
+       if (payload_len != MAX_REQUEST_LENGTH)
+               LOGI("json generated len: %d; msg: %s\n", payload_len, payload);
+       else
+               LOGE("bad payload!!!\n");
+
+       strncpy(buf, payload, MAX_REQUEST_LENGTH - 1);
+
+       if (libwebsocket_write(wsi, (unsigned char *)buf, payload_len,
                               LWS_WRITE_TEXT) < 0) {
                LOGE("cannot write to web socket (method: %s)\n", method);
                return;
        }
 
        SETSTAT(pstate, PSTATE_WAIT_ACK);
-       LOGI("json message send; len: %d; msg: %s\n", strlen(payload), payload);
 }
 
 static int profiling_callback(struct libwebsocket_context *context,
@@ -252,10 +269,12 @@ static int profiling_callback(struct libwebsocket_context *context,
                send_request("Profiler.start");
                break;
 
+       case LWS_CALLBACK_DEL_POLL_FD:
+               LOGE("LWS_CALLBACK_DEL_POLL_FD\n");
        case LWS_CALLBACK_CLOSED:
                LOGI("Connection closed\n");
                CLRSTAT(pstate, PSTATE_CONNECTED);
-               CLRSTAT(pstate, PSTATE_DISCONNECT);
+               SETSTAT(pstate, PSTATE_DISCONNECT);
                break;
 
        case LWS_CALLBACK_CLIENT_RECEIVE:
@@ -314,7 +333,7 @@ static int profiling_callback(struct libwebsocket_context *context,
                break;
 
        case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
-               LOGE("Web socket connection error\n");
+               LOGE("Web socket connection error. Falling down\n");
                /*
                 * TODO: need report to host about error. May be should stop
                 * web profiling and/or launching web application
@@ -343,7 +362,7 @@ static int init_wsi_conn(struct libwebsocket_context **context,
                         struct libwebsocket **wsi,
                         const char *address, int port)
 {
-       struct lws_context_creation_info info;
+       static struct lws_context_creation_info info;
        char host[32];
        char origin[32];
        const char *page = "/devtools/page/1";
@@ -351,6 +370,7 @@ static int init_wsi_conn(struct libwebsocket_context **context,
 
        sprintf(host, "%s:%d", address, port);
        sprintf(origin, "http://%s:%d", address, port);
+       LOGI(" host =<%s> origin = <%s>\n", host, origin);
 
        memset(&info, 0, sizeof(info));
 
@@ -388,9 +408,11 @@ static int init_wsi_conn(struct libwebsocket_context **context,
 static void *handle_ws_responses(void *arg)
 {
        while (CHKSTAT(pstate, PSTATE_START | PSTATE_PROFILING |
-                      PSTATE_WAIT_ACK))
-               libwebsocket_service(context, 50);
+                      PSTATE_WAIT_ACK) && !CHKSTAT(pstate, PSTATE_DISCONNECT)) {
+               libwebsocket_service(context, 1000);
+       }
 
+       LOGI("handle response thread finished\n");
        return NULL;
 }
 
@@ -424,10 +446,12 @@ static int wsi_init(const char *address, int port)
 static void wsi_destroy(void)
 {
        if (CHKSTAT(pstate, PSTATE_CONNECTED)) {
-               if (CHKSTAT(pstate, PSTATE_WAIT_ACK))
+               if (CHKSTAT(pstate, PSTATE_WAIT_ACK)) {
                        SETSTAT(pstate, PSTATE_DISCONNECT);
-               else
+               } else {
+                       LOGI("destroy context\n");
                        destroy_wsi_conn(context);
+               }
        } else {
                LOGW("Try disconnect when web socket not connected\n");
        }
@@ -435,11 +459,9 @@ static void wsi_destroy(void)
 
 static int wsi_start_profiling(void)
 {
-       pthread_t tid;
-
        SETSTAT(pstate, PSTATE_START);
 
-       if (pthread_create(&tid, NULL, &handle_ws_responses, NULL)) {
+       if (pthread_create(&wsi_handle_thread, NULL, &handle_ws_responses, NULL)) {
                LOGE("Can't create handle_ws_ threads\n");
                destroy_wsi_conn(context);
                return 1;
@@ -498,9 +520,20 @@ void wsi_stop(void)
                        LOGE("Cannot disable web application profiling\n");
        }
 
+       SETSTAT(pstate, PSTATE_DISCONNECT);
+
        if (wsi_start_thread != -1)
                pthread_join(wsi_start_thread, &thread_ret);
-
        wsi_start_thread = -1;
-       wsi_destroy();
+
+
+       if (wsi_handle_thread != -1) {
+               LOGI("wait handle thread");
+               pthread_join(wsi_handle_thread, &thread_ret);
+       }
+       wsi_handle_thread = -1;
+
+       destroy_wsi_conn(context);
+
+       CLRSTAT(pstate, PSTATE_DISCONNECT);
 }