Add conditional variables to wait for the USB event thread to be ready 78/318278/1 tizen
authorJihoon Jung <jh8801.jung@samsung.com>
Wed, 15 Jan 2025 05:47:49 +0000 (14:47 +0900)
committerJihoon Jung <jh8801.jung@samsung.com>
Wed, 15 Jan 2025 05:47:49 +0000 (14:47 +0900)
Change-Id: Id07c5dfbec3bdb6377b10cd5383a14a52920baf8
Signed-off-by: Jihoon Jung <jh8801.jung@samsung.com>
packaging/mtp-initiator.spec
src/daemon/include/mtp_daemon.h
src/daemon/mtp_daemon.c
src/daemon/mtp_daemon_event.c

index 61f32180680b99fcc3169194557974bee3d509cd..613a03dfd2b298df7dbc85fcaee03c25ab71905f 100644 (file)
@@ -1,6 +1,6 @@
 Name:       mtp-initiator
 Summary:    mtp(media transfer protocol) initiator
-Version:    1.4.38
+Version:    1.4.39
 Release:    0
 Group:      Network & Connectivity/Other
 License:    Apache-2.0
index ac14b852e4e60abb9317962aea93f760d4d31198..eaa77693b5971074ba89fb003a451bf9d326a064 100644 (file)
@@ -165,6 +165,9 @@ struct _mtp_context {
 
        gint quit_timer;
        bool is_device_preparing;
+
+       pthread_mutex_t usb_thread_mutex;
+       pthread_cond_t usb_thread_cond;
 };
 
 struct _mtp_queue_data {
index 4c620444646f6ef494e1b90033ce8a331d8b255a..008ccaaa6e3b9723648dfddaaff28d74cb37f398 100644 (file)
@@ -113,6 +113,9 @@ static mtp_error_e __daemon_deinitalize(mtp_context *mtp_ctx)
                libusb_exit(mtp_ctx->usb_ctx);
        }
 
+       pthread_mutex_destroy(&mtp_ctx->usb_thread_mutex);
+       pthread_cond_destroy(&mtp_ctx->usb_thread_cond);
+
        g_main_loop_unref(mtp_ctx->main_loop);
        g_free(mtp_ctx);
 
index 2d086f3abc7a6d901eda6771fa8557fe1559ecd4..e31fe02224954ebd12a85968577b6b60125e55f5 100644 (file)
@@ -109,6 +109,8 @@ int __usb_host_status_changed_cb(struct libusb_context *ctx,
 
        MTP_LOGI("bus_no : %03d, dev_no : %03d", bus_no, dev_no);
 
+       pthread_mutex_lock(&mtp_ctx->usb_thread_mutex);
+
        if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
                MTP_LOGI("USB device added");
 
@@ -224,6 +226,8 @@ int __usb_host_status_changed_cb(struct libusb_context *ctx,
                }
        }
 
+       pthread_mutex_unlock(&mtp_ctx->usb_thread_mutex);
+
        return 0;
 }
 /* LCOV_EXCL_STOP */
@@ -303,6 +307,8 @@ mtp_error_e __device_list_init(mtp_context *mtp_ctx)
 
        RETV_IF(mtp_ctx == NULL, MTP_ERROR_INVALID_PARAMETER);
 
+       pthread_mutex_lock(&mtp_ctx->usb_thread_mutex);
+
        LIBMTP_Set_Debug(LIBMTP_DEBUG_ALL);
        LIBMTP_Init();
        LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices);
@@ -373,6 +379,8 @@ mtp_error_e __device_list_init(mtp_context *mtp_ctx)
        }
        g_free(rawdevices);
 
+       pthread_mutex_unlock(&mtp_ctx->usb_thread_mutex);
+
        return ret;
 }
 
@@ -389,7 +397,12 @@ static gpointer __dispatch_event(gpointer user_data)
                /* LCOV_EXCL_STOP */
        }
 
-       MTP_LOGE("dispatch thread created");
+       MTP_LOGE("dispatch thread created. Signal the main thread that work is done");
+       pthread_mutex_lock(&mtp_ctx->usb_thread_mutex);
+       pthread_cond_signal(&mtp_ctx->usb_thread_cond);
+       pthread_mutex_unlock(&mtp_ctx->usb_thread_mutex);
+
+       MTP_LOGE("USB event thread prepared");
        while (mtp_ctx->is_running) {
                libusb_handle_events_completed(mtp_ctx->usb_ctx, NULL);
        }
@@ -411,9 +424,16 @@ mtp_error_e mtp_daemon_event_init(mtp_context *mtp_ctx)
        for (slot = 1; slot < MTP_MAX_SLOT; slot++)
                mtp_ctx->device_list->device_info_list[slot] = NULL;
 
-       /* mtp device list init */
-       if (__device_list_init(mtp_ctx) != MTP_ERROR_NONE)
-               return MTP_ERROR_NO_DEVICE;
+       if (pthread_mutex_init(&mtp_ctx->usb_thread_mutex, NULL) != 0) {
+               MTP_LOGE("Failed to initialize mutex");
+               return MTP_ERROR_PLUGIN_FAIL;
+       }
+
+       if (pthread_cond_init(&mtp_ctx->usb_thread_cond, NULL) != 0) {
+               MTP_LOGE("Failed to initialize condition variable");
+               pthread_mutex_destroy(&mtp_ctx->usb_thread_mutex);
+               return MTP_ERROR_PLUGIN_FAIL;
+       }
 
        /* usb event setting */
        ret = libusb_init(&(mtp_ctx->usb_ctx));
@@ -438,6 +458,16 @@ mtp_error_e mtp_daemon_event_init(mtp_context *mtp_ctx)
                /* LCOV_EXCL_STOP */
        }
 
+       MTP_LOGE("Waits up to 5 sec for the USB event thread to become ready");
+       pthread_mutex_lock(&mtp_ctx->usb_thread_mutex);
+       pthread_cond_timedwait(&mtp_ctx->usb_thread_cond, &mtp_ctx->usb_thread_mutex, &(struct timespec){time(NULL) + 5});
+       pthread_mutex_unlock(&mtp_ctx->usb_thread_mutex);
+       MTP_LOGE("USB event thread prepared");
+
+       /* mtp device list init */
+       if (__device_list_init(mtp_ctx) != MTP_ERROR_NONE)
+               return MTP_ERROR_NO_DEVICE;
+
        /* create thread pool */
        mtp_ctx->device_list->threads
                = g_thread_pool_new((GFunc) __event_thread, mtp_ctx, MTP_MAX_SLOT-1, TRUE, NULL);