Add some more cases to the app-id unit tests
[glib.git] / gio / tests / cancellable.c
blob1cbd765cc3799a676c53d4e51c543305decbdc83
1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2011 Collabora Ltd.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 * Author: Stef Walter <stefw@collabora.co.uk>
21 #include <locale.h>
23 #include <gio/gio.h>
25 /* How long to wait in ms for each iteration */
26 #define WAIT_ITERATION (10)
28 static gint num_async_operations = 0;
30 typedef struct
32 guint iterations_requested;
33 guint iterations_done;
34 } MockOperationData;
36 static void
37 mock_operation_free (gpointer user_data)
39 MockOperationData *data = user_data;
40 g_free (data);
43 static void
44 mock_operation_thread (GTask *task,
45 gpointer source_object,
46 gpointer task_data,
47 GCancellable *cancellable)
49 MockOperationData *data = task_data;
50 guint i;
52 for (i = 0; i < data->iterations_requested; i++)
54 if (g_cancellable_is_cancelled (cancellable))
55 break;
56 if (g_test_verbose ())
57 g_printerr ("THRD: %u iteration %u\n", data->iterations_requested, i);
58 g_usleep (WAIT_ITERATION * 1000);
61 if (g_test_verbose ())
62 g_printerr ("THRD: %u stopped at %u\n", data->iterations_requested, i);
63 data->iterations_done = i;
65 g_task_return_boolean (task, TRUE);
68 static gboolean
69 mock_operation_timeout (gpointer user_data)
71 GTask *task;
72 MockOperationData *data;
73 gboolean done = FALSE;
75 task = G_TASK (user_data);
76 data = g_task_get_task_data (task);
78 if (data->iterations_done >= data->iterations_requested)
79 done = TRUE;
81 if (g_cancellable_is_cancelled (g_task_get_cancellable (task)))
82 done = TRUE;
84 if (done)
86 if (g_test_verbose ())
87 g_printerr ("LOOP: %u stopped at %u\n", data->iterations_requested,\
88 data->iterations_done);
89 g_task_return_boolean (task, TRUE);
90 return FALSE; /* don't call timeout again */
92 else
94 data->iterations_done++;
95 if (g_test_verbose ())
96 g_printerr ("LOOP: %u iteration %u\n", data->iterations_requested,
97 data->iterations_done);
98 return TRUE; /* call timeout */
102 static void
103 mock_operation_async (guint wait_iterations,
104 gboolean run_in_thread,
105 GCancellable *cancellable,
106 GAsyncReadyCallback callback,
107 gpointer user_data)
109 GTask *task;
110 MockOperationData *data;
112 task = g_task_new (NULL, cancellable, callback, user_data);
113 data = g_new0 (MockOperationData, 1);
114 data->iterations_requested = wait_iterations;
115 g_task_set_task_data (task, data, mock_operation_free);
117 if (run_in_thread)
119 g_task_run_in_thread (task, mock_operation_thread);
120 if (g_test_verbose ())
121 g_printerr ("THRD: %d started\n", wait_iterations);
123 else
125 g_timeout_add_full (G_PRIORITY_DEFAULT, WAIT_ITERATION, mock_operation_timeout,
126 g_object_ref (task), g_object_unref);
127 if (g_test_verbose ())
128 g_printerr ("LOOP: %d started\n", wait_iterations);
131 g_object_unref (task);
134 static guint
135 mock_operation_finish (GAsyncResult *result,
136 GError **error)
138 MockOperationData *data;
139 GTask *task;
141 g_assert (g_task_is_valid (result, NULL));
143 /* This test expects the return value to be iterations_done even
144 * when an error is set.
146 task = G_TASK (result);
147 data = g_task_get_task_data (task);
149 g_task_propagate_boolean (task, error);
150 return data->iterations_done;
153 GMainLoop *loop;
155 static void
156 on_mock_operation_ready (GObject *source,
157 GAsyncResult *result,
158 gpointer user_data)
160 guint iterations_requested;
161 guint iterations_done;
162 GError *error = NULL;
164 iterations_requested = GPOINTER_TO_UINT (user_data);
165 iterations_done = mock_operation_finish (result, &error);
167 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
168 g_error_free (error);
170 g_assert_cmpint (iterations_requested, >, iterations_done);
171 num_async_operations--;
173 if (!num_async_operations)
174 g_main_loop_quit (loop);
177 static gboolean
178 on_main_loop_timeout_quit (gpointer user_data)
180 GMainLoop *loop = user_data;
181 g_main_loop_quit (loop);
182 return FALSE;
185 static void
186 test_cancel_multiple_concurrent (void)
188 GCancellable *cancellable;
189 guint i, iterations;
191 cancellable = g_cancellable_new ();
192 loop = g_main_loop_new (NULL, FALSE);
194 for (i = 0; i < 45; i++)
196 iterations = i + 10;
197 mock_operation_async (iterations, g_random_boolean (), cancellable,
198 on_mock_operation_ready, GUINT_TO_POINTER (iterations));
199 num_async_operations++;
202 /* Wait for two iterations, to give threads a chance to start up */
203 g_timeout_add (WAIT_ITERATION * 2, on_main_loop_timeout_quit, loop);
204 g_main_loop_run (loop);
205 g_assert_cmpint (num_async_operations, ==, 45);
206 if (g_test_verbose ())
207 g_printerr ("CANCEL: %d operations\n", num_async_operations);
208 g_cancellable_cancel (cancellable);
209 g_assert (g_cancellable_is_cancelled (cancellable));
211 /* Wait for all operations to be cancelled */
212 g_main_loop_run (loop);
213 g_assert_cmpint (num_async_operations, ==, 0);
215 g_object_unref (cancellable);
216 g_main_loop_unref (loop);
220 main (int argc, char *argv[])
222 g_test_init (&argc, &argv, NULL);
224 g_test_add_func ("/cancellable/multiple-concurrent", test_cancel_multiple_concurrent);
226 return g_test_run ();