block: Added logic to wait for thread processing on exit 28/202828/4
authorYunmi Ha <yunmi.ha@samsung.com>
Fri, 5 Apr 2019 00:44:46 +0000 (09:44 +0900)
committerYunmi Ha <yunmi.ha@samsung.com>
Wed, 10 Apr 2019 07:43:41 +0000 (16:43 +0900)
If the thread has remain job when it exit,
it need to wait for finishing it.

Change-Id: Ibe331760e67a3ade57dc11d08555c60ae9106c3e
Signed-off-by: Yunmi Ha <yunmi.ha@samsung.com>
src/block/block.c
src/core/modules.c

index 5318897fab392390b46d3f13b1c96d9c52c1c1cc..2d788f9a28b0337d5b9bd15afb1b62ad9dcf2c35 100644 (file)
@@ -2039,15 +2039,15 @@ static int add_operation(struct block_device *bdev,
        DD_LIST_APPEND(bdev->op_queue, op);
        th_manager[thread_id].op_len++;
 
-       if (th_manager[thread_id].op_len == 1 && !start_th)
+       if (th_manager[thread_id].op_len == 1 && start_th)
                pthread_cond_signal(&(th_manager[thread_id].cond));
 
        pthread_mutex_unlock(&(th_manager[thread_id].mutex));
        /* UNLOCK */
 
-       if (start_th) {
+       if (!start_th) {
                _D("Start New thread for block device");
-               th_manager[thread_id].start_th = false;
+               th_manager[thread_id].start_th = true;
                ret = pthread_create(&(th_manager[thread_id].th), NULL, block_th_start, &th_manager[thread_id]);
                if (ret != 0) {
                        _E("fail to create thread for %s", bdev->data->devnode);
@@ -3740,7 +3740,7 @@ static void block_init(void *data)
        for (i = 0; i < THREAD_MAX; i++) {
                th_manager[i].num_dev = 0;
                th_manager[i].op_len = 0;
-               th_manager[i].start_th = true;
+               th_manager[i].start_th = false;
                th_manager[i].thread_id = i;
                pthread_mutex_init(&(th_manager[i].mutex), NULL);
                pthread_cond_init(&(th_manager[i].cond), NULL);
@@ -3804,11 +3804,34 @@ static void block_init(void *data)
                        block_poweroff, NULL, NULL);
 }
 
-static void block_exit(void *data)
+static void terminate_threads(void)
 {
        dd_list *elem, *elem_next;
        char *temp;
-       int ret, i;
+       int i, count;
+       const int WAIT_TIME = 10;
+
+       for (i = 0; i < THREAD_MAX; i++) {
+               if (th_manager[i].start_th) {
+                       count = 0;
+                       while ((th_manager[i].op_len != 0) && (count < WAIT_TIME)) {
+                               _I("Thread(%d) job is not finished. Wait a second.", th_manager[i].thread_id);
+                               usleep(200*1000);
+                               count++;
+                       }
+                       pthread_cancel(th_manager[i].th);
+                       pthread_join(th_manager[i].th, NULL);
+               }
+               DD_LIST_FOREACH_SAFE(th_manager[i].th_node_list, elem, elem_next, temp) {
+                       DD_LIST_REMOVE(th_manager[i].th_node_list, temp);
+                       free(temp);
+               }
+       }
+}
+
+static void block_exit(void *data)
+{
+       int ret;
 
        udev_exit(NULL);
 
@@ -3830,14 +3853,7 @@ static void block_exit(void *data)
        /* remove remaining blocks */
        remove_whole_block_device();
 
-       for (i = 0; i < THREAD_MAX; i++) {
-               if (!th_manager[i].start_th)
-                       pthread_cancel(th_manager[i].th);
-               DD_LIST_FOREACH_SAFE(th_manager[i].th_node_list, elem, elem_next, temp) {
-                       DD_LIST_REMOVE(th_manager[i].th_node_list, temp);
-                       free(temp);
-               }
-       }
+       terminate_threads();
 
        /* exit pipe */
        pipe_exit();
index ca303ea1a8ee35f192ba4f9322a97f35faea302e..3dde9876bbcbd9c1aba5afbd4905d232f63308b0 100644 (file)
@@ -169,6 +169,7 @@ void modules_deinit(void *data)
                if (module->plugin && module->plugin->exit)
                        module->plugin->exit(NULL);
                storaged_close_module(module->plugin);
+               _I("%s closed", module->so_name);
                free(module->name);
                free(module->so_name);
                free(module);