• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
pool_func(gpointer data,gpointer user_data)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
test_simple(gconstpointer shared)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
dummy_pool_func(gpointer data,gpointer user_data)85 dummy_pool_func (gpointer data, gpointer user_data)
86 {
87   g_assert_true (data == GUINT_TO_POINTER (123));
88 }
89 
90 static void
test_create_first_pool(gconstpointer shared_first)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
main(int argc,char * argv[])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 }
157