Imported Upstream version 2.64.5
[platform/upstream/glib.git] / glib / tests / thread-pool.c
1 /* Unit tests for GThreadPool
2  * Copyright (C) 2020 Sebastian Dröge <sebastian@centricular.com>
3  *
4  * This work is provided "as is"; redistribution and modification
5  * in whole or in part, in any medium, physical or electronic is
6  * permitted without restriction.
7  *
8  * This work is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * In no event shall the authors or contributors be liable for any
13  * direct, indirect, incidental, special, exemplary, or consequential
14  * damages (including, but not limited to, procurement of substitute
15  * goods or services; loss of use, data, or profits; or business
16  * interruption) however caused and on any theory of liability, whether
17  * in contract, strict liability, or tort (including negligence or
18  * otherwise) arising in any way out of the use of this software, even
19  * if advised of the possibility of such damage.
20  */
21
22 #include <config.h>
23
24 #include <glib.h>
25
26 typedef struct {
27   GMutex mutex;
28   GCond cond;
29   gboolean signalled;
30 } MutexCond;
31
32 static void
33 pool_func (gpointer data, gpointer user_data)
34 {
35   MutexCond *m = user_data;
36
37   g_mutex_lock (&m->mutex);
38   g_assert_false (m->signalled);
39   g_assert_true (data == GUINT_TO_POINTER (123));
40   m->signalled = TRUE;
41   g_cond_signal (&m->cond);
42   g_mutex_unlock (&m->mutex);
43 }
44
45 static void
46 test_simple (gconstpointer shared)
47 {
48   GThreadPool *pool;
49   GError *err = NULL;
50   MutexCond m;
51   gboolean success;
52
53   g_mutex_init (&m.mutex);
54   g_cond_init (&m.cond);
55
56   if (GPOINTER_TO_INT (shared))
57     {
58       g_test_summary ("Tests that a shared, non-exclusive thread pool "
59                       "generally works.");
60       pool = g_thread_pool_new (pool_func, &m, -1, FALSE, &err);
61     }
62   else
63     {
64       g_test_summary ("Tests that an exclusive thread pool generally works.");
65       pool = g_thread_pool_new (pool_func, &m, 2, TRUE, &err);
66     }
67   g_assert_no_error (err);
68   g_assert_nonnull (pool);
69
70   g_mutex_lock (&m.mutex);
71   m.signalled = FALSE;
72
73   success = g_thread_pool_push (pool, GUINT_TO_POINTER (123), &err);
74   g_assert_no_error (err);
75   g_assert_true (success);
76
77   while (!m.signalled)
78     g_cond_wait (&m.cond, &m.mutex);
79   g_mutex_unlock (&m.mutex);
80
81   g_thread_pool_free (pool, TRUE, TRUE);
82 }
83
84 static void
85 dummy_pool_func (gpointer data, gpointer user_data)
86 {
87   g_assert_true (data == GUINT_TO_POINTER (123));
88 }
89
90 static void
91 test_create_first_pool (gconstpointer shared_first)
92 {
93   GThreadPool *pool;
94   GError *err = NULL;
95   gboolean success;
96
97   g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/2012");
98   if (GPOINTER_TO_INT (shared_first))
99     {
100       g_test_summary ("Tests that creating an exclusive pool after a "
101                       "shared one works.");
102     }
103   else
104     {
105       g_test_summary ("Tests that creating a shared pool after an "
106                       "exclusive one works.");
107     }
108
109   if (!g_test_subprocess ())
110     {
111       g_test_trap_subprocess (NULL, 0, 0);
112       g_test_trap_assert_passed ();
113       return;
114     }
115
116   g_thread_pool_set_max_unused_threads (0);
117
118   if (GPOINTER_TO_INT (shared_first))
119     pool = g_thread_pool_new (dummy_pool_func, NULL, -1, FALSE, &err);
120   else
121     pool = g_thread_pool_new (dummy_pool_func, NULL, 2, TRUE, &err);
122   g_assert_no_error (err);
123   g_assert_nonnull (pool);
124
125   success = g_thread_pool_push (pool, GUINT_TO_POINTER (123), &err);
126   g_assert_no_error (err);
127   g_assert_true (success);
128
129   g_thread_pool_free (pool, TRUE, TRUE);
130
131   if (GPOINTER_TO_INT (shared_first))
132     pool = g_thread_pool_new (dummy_pool_func, NULL, 2, TRUE, &err);
133   else
134     pool = g_thread_pool_new (dummy_pool_func, NULL, -1, FALSE, &err);
135   g_assert_no_error (err);
136   g_assert_nonnull (pool);
137
138   success = g_thread_pool_push (pool, GUINT_TO_POINTER (123), &err);
139   g_assert_no_error (err);
140   g_assert_true (success);
141
142   g_thread_pool_free (pool, TRUE, TRUE);
143 }
144
145 int
146 main (int argc, char *argv[])
147 {
148   g_test_init (&argc, &argv, NULL);
149
150   g_test_add_data_func ("/thread_pool/shared", GINT_TO_POINTER (TRUE), test_simple);
151   g_test_add_data_func ("/thread_pool/exclusive", GINT_TO_POINTER (FALSE), test_simple);
152   g_test_add_data_func ("/thread_pool/create_shared_after_exclusive", GINT_TO_POINTER (FALSE), test_create_first_pool);
153   g_test_add_data_func ("/thread_pool/create_exclusive_after_shared", GINT_TO_POINTER (TRUE), test_create_first_pool);
154
155   return g_test_run ();
156 }