Delete g_cond_wait from tpl_gsource_destroy. 01/282301/1
authorJoonbum Ko <joonbum.ko@samsung.com>
Wed, 28 Sep 2022 11:26:57 +0000 (20:26 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Wed, 28 Sep 2022 11:27:21 +0000 (20:27 +0900)
 - g_cond_wait does not guarantee perfectly.
  Therefore, it is recommended that the caller of tpl_gsource_destroy
  should call the g_cond_wait to confirm if the destroy is
  actually complete.

 - https://docs.gtk.org/glib/method.Cond.wait.html
  Atomically releases mutex and waits until cond is signalled.
 When this function returns, mutex is locked again
 and owned by the calling thread.

  When using condition variables, it is possible that a spurious
 wakeup may occur (ie: g_cond_wait() returns even though g_cond_signal()
 was not called). It’s also possible that a stolen wakeup may occur.
 This is when g_cond_signal() is called, but another thread acquires
 mutex before this thread and modifies the state of the program in such
 a way that when g_cond_wait() is able to return,
 the expected condition is no longer met.

 For this reason, g_cond_wait() must always be used in a loop.
 See the documentation for GCond for a complete example.

Change-Id: If3b98b4d79b205d9125558edb75f4b85ef6a3a99
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/tpl_utils_gthread.c
src/tpl_utils_gthread.h

index 3352a0d..20b6838 100644 (file)
@@ -329,8 +329,6 @@ tpl_gsource_destroy(tpl_gsource *source, tpl_bool_t destroy_in_thread)
                if (destroy_in_thread) {
                        finalizer->intended_destroy = TPL_TRUE;
                        tpl_gsource_send_message(finalizer, 1);
-
-                       g_cond_wait(&thread->thread_cond, &thread->thread_mutex);
                } else {
                        __gsource_remove_and_destroy(finalizer);
                        source->finalizer = NULL;
index a1d4ce1..0237f40 100644 (file)
@@ -65,6 +65,11 @@ tpl_gthread_destroy(tpl_gthread *thread);
  *
  * This creates a new tpl_gsource to be attached the thread loop.
  *
+ * IMPORTANT
+ *  - If destroy_in_thread is TPL_TRUE, since this function does not use
+ *    g_cond_wait(), caller should call tpl_gcond_wait() or tpl_gcond_timed_wait()
+ *    to confirm gsource destroy completely.
+ *
  * @param thread Pointer to tpl_gthread to attach new tpl_gsource.
  * @param data Pointer to some handle used by its user.
  * @param fd fd to poll. If the value is more than 0, the passed value will be polled.