[glib: 1/2] GThreadPool: Add g_thread_pool_new_full()




commit 75db4883fc4bbe47766b6bd5f939b8154ef5e98e
Author: nitinosiris <nitinwartkar58 gmail com>
Date:   Sat Jun 26 16:08:42 2021 +0530

    GThreadPool: Add g_thread_pool_new_full()
    
    g_thread_pool_new_full() is similar to g_thread_pool_new()
    but with GDestroyNotify argument.
    
    Closes #121

 docs/reference/glib/glib-sections.txt |  1 +
 glib/gthreadpool.c                    | 34 ++++++++++++++++++++-
 glib/gthreadpool.h                    |  7 +++++
 glib/tests/thread-pool.c              | 56 +++++++++++++++++++++++++++++++++++
 4 files changed, 97 insertions(+), 1 deletion(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 863dc5a1b..406041253 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -1171,6 +1171,7 @@ g_once_init_enter_impl
 <FILE>thread_pools</FILE>
 GThreadPool
 g_thread_pool_new
+g_thread_pool_new_full
 g_thread_pool_push
 g_thread_pool_set_max_threads
 g_thread_pool_get_max_threads
diff --git a/glib/gthreadpool.c b/glib/gthreadpool.c
index 305152ae7..15d5d4e52 100644
--- a/glib/gthreadpool.c
+++ b/glib/gthreadpool.c
@@ -558,6 +558,38 @@ g_thread_pool_new (GFunc      func,
                    gint       max_threads,
                    gboolean   exclusive,
                    GError   **error)
+{
+  return g_thread_pool_new_full (func, user_data, NULL, max_threads, exclusive, error);
+}
+
+/**
+ * g_thread_pool_new_full:
+ * @func: a function to execute in the threads of the new thread pool
+ * @user_data: user data that is handed over to @func every time it
+ *     is called
+ * @item_free_func: (nullable): used to pass as a free function to
+ *     g_async_queue_new_full()
+ * @max_threads: the maximal number of threads to execute concurrently
+ *     in the new thread pool, `-1` means no limit
+ * @exclusive: should this thread pool be exclusive?
+ * @error: return location for error, or %NULL
+ *
+ * This function creates a new thread pool similar to g_thread_pool_new()
+ * but allowing @item_free_func to be specified to free the data passed
+ * to g_thread_pool_push() in the case that the #GThreadPool is stopped
+ * and freed before all tasks have been executed.
+ *
+ * Returns: (transfer full): the new #GThreadPool
+ *
+ * Since: 2.70
+ */
+GThreadPool *
+g_thread_pool_new_full (GFunc           func,
+                        gpointer        user_data,
+                        GDestroyNotify  item_free_func,
+                        gint            max_threads,
+                        gboolean        exclusive,
+                        GError        **error)
 {
   GRealThreadPool *retval;
   G_LOCK_DEFINE_STATIC (init);
@@ -571,7 +603,7 @@ g_thread_pool_new (GFunc      func,
   retval->pool.func = func;
   retval->pool.user_data = user_data;
   retval->pool.exclusive = exclusive;
-  retval->queue = g_async_queue_new ();
+  retval->queue = g_async_queue_new_full (item_free_func);
   g_cond_init (&retval->cond);
   retval->max_threads = max_threads;
   retval->num_threads = 0;
diff --git a/glib/gthreadpool.h b/glib/gthreadpool.h
index 11c3d1d16..f2501b88b 100644
--- a/glib/gthreadpool.h
+++ b/glib/gthreadpool.h
@@ -51,6 +51,13 @@ GThreadPool *   g_thread_pool_new               (GFunc            func,
                                                  gint             max_threads,
                                                  gboolean         exclusive,
                                                  GError         **error);
+GLIB_AVAILABLE_IN_2_70
+GThreadPool *   g_thread_pool_new_full          (GFunc            func,
+                                                 gpointer         user_data,
+                                                 GDestroyNotify   item_free_func,
+                                                 gint             max_threads,
+                                                 gboolean         exclusive,
+                                                 GError         **error);
 GLIB_AVAILABLE_IN_ALL
 void            g_thread_pool_free              (GThreadPool     *pool,
                                                  gboolean         immediate,
diff --git a/glib/tests/thread-pool.c b/glib/tests/thread-pool.c
index 703da5d7a..50a72a632 100644
--- a/glib/tests/thread-pool.c
+++ b/glib/tests/thread-pool.c
@@ -87,6 +87,12 @@ dummy_pool_func (gpointer data, gpointer user_data)
   g_assert_true (data == GUINT_TO_POINTER (123));
 }
 
+static void
+dummy_pool_func_full (gpointer data, gpointer user_data)
+{
+  g_assert_true (data == user_data);
+}
+
 static void
 test_create_first_pool (gconstpointer shared_first)
 {
@@ -142,6 +148,55 @@ test_create_first_pool (gconstpointer shared_first)
   g_thread_pool_free (pool, TRUE, TRUE);
 }
 
+static void
+free_func (gpointer user_data)
+{
+  gboolean *free_func_called = user_data;
+  *free_func_called = TRUE;
+}
+
+static void
+test_thread_pool_full (gconstpointer shared_first)
+{
+  GThreadPool *pool;
+  gboolean free_func_called = FALSE;
+  GError *err = NULL;
+  gboolean success;
+
+  g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/121";);
+
+  g_thread_pool_set_max_unused_threads (0);
+
+  if (GPOINTER_TO_INT (shared_first))
+    pool = g_thread_pool_new_full (dummy_pool_func_full, &free_func_called, free_func, -1, FALSE, &err);
+  else
+    pool = g_thread_pool_new_full (dummy_pool_func_full, &free_func_called, free_func, 2, TRUE, &err);
+  g_assert_no_error (err);
+  g_assert_nonnull (pool);
+
+  success = g_thread_pool_push (pool, &free_func_called, &err);
+  g_assert_no_error (err);
+  g_assert_true (success);
+
+  g_thread_pool_free (pool, TRUE, TRUE);
+  g_assert_true (free_func_called);
+
+  free_func_called = FALSE;
+  if (GPOINTER_TO_INT (shared_first))
+    pool = g_thread_pool_new_full (dummy_pool_func_full, &free_func_called, free_func, 2, TRUE, &err);
+  else
+    pool = g_thread_pool_new_full (dummy_pool_func_full, &free_func_called, free_func, -1, FALSE, &err);
+  g_assert_no_error (err);
+  g_assert_nonnull (pool);
+
+  success = g_thread_pool_push (pool, &free_func_called, &err);
+  g_assert_no_error (err);
+  g_assert_true (success);
+
+  g_thread_pool_free (pool, TRUE, TRUE);
+  g_assert_true (free_func_called);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -150,6 +205,7 @@ main (int argc, char *argv[])
   g_test_add_data_func ("/thread_pool/shared", GINT_TO_POINTER (TRUE), test_simple);
   g_test_add_data_func ("/thread_pool/exclusive", GINT_TO_POINTER (FALSE), test_simple);
   g_test_add_data_func ("/thread_pool/create_shared_after_exclusive", GINT_TO_POINTER (FALSE), 
test_create_first_pool);
+  g_test_add_data_func ("/thread_pool/create_full", GINT_TO_POINTER (FALSE), test_thread_pool_full);
   g_test_add_data_func ("/thread_pool/create_exclusive_after_shared", GINT_TO_POINTER (TRUE), 
test_create_first_pool);
 
   return g_test_run ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]