Andrew Geissler | 95ac1b8 | 2021-03-31 14:34:31 -0500 | [diff] [blame] | 1 | From 7f905ff1faf0acbe0d2ce69937e031fcacce9294 Mon Sep 17 00:00:00 2001 |
| 2 | From: Philip Withnall <pwithnall@endlessos.org> |
| 3 | Date: Wed, 11 Nov 2020 18:21:00 +0000 |
| 4 | Subject: [PATCH 05/29] tests: Fix non-atomic access to some shared variables |
| 5 | MIME-Version: 1.0 |
| 6 | Content-Type: text/plain; charset=UTF-8 |
| 7 | Content-Transfer-Encoding: 8bit |
| 8 | |
| 9 | And drop the `volatile` qualifier from the variables, as that doesn’t |
| 10 | help with thread safety. |
| 11 | |
| 12 | Signed-off-by: Philip Withnall <pwithnall@endlessos.org> |
| 13 | |
| 14 | Helps: #600 |
| 15 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1719] |
| 16 | --- |
| 17 | gio/tests/gdbus-connection-flush.c | 6 +- |
| 18 | gio/tests/gdbus-connection.c | 40 ++++---- |
| 19 | gio/tests/gdbus-overflow.c | 20 ++-- |
| 20 | gio/tests/socket-service.c | 6 +- |
| 21 | gio/tests/task.c | 150 ++++++++++++++--------------- |
| 22 | 5 files changed, 111 insertions(+), 111 deletions(-) |
| 23 | |
| 24 | --- a/gio/tests/gdbus-connection-flush.c |
| 25 | +++ b/gio/tests/gdbus-connection-flush.c |
| 26 | @@ -43,9 +43,9 @@ G_LOCK_DEFINE_STATIC (write); |
| 27 | typedef struct { |
| 28 | GFilterOutputStream parent; |
| 29 | |
| 30 | - volatile gint started; |
| 31 | - volatile gint finished; |
| 32 | - volatile gint flushed; |
| 33 | + gint started; /* (atomic) */ |
| 34 | + gint finished; /* (atomic) */ |
| 35 | + gint flushed; /* (atomic) */ |
| 36 | |
| 37 | GOutputStream *real_output; |
| 38 | } MyOutputStream; |
| 39 | --- a/gio/tests/gdbus-connection.c |
| 40 | +++ b/gio/tests/gdbus-connection.c |
| 41 | @@ -61,9 +61,9 @@ _log (const gchar *format, ...) |
| 42 | static gboolean |
| 43 | test_connection_quit_mainloop (gpointer user_data) |
| 44 | { |
| 45 | - volatile gboolean *quit_mainloop_fired = user_data; |
| 46 | + gboolean *quit_mainloop_fired = user_data; /* (atomic) */ |
| 47 | _log ("quit_mainloop_fired"); |
| 48 | - *quit_mainloop_fired = TRUE; |
| 49 | + g_atomic_int_set (quit_mainloop_fired, TRUE); |
| 50 | g_main_loop_quit (loop); |
| 51 | return TRUE; |
| 52 | } |
| 53 | @@ -113,8 +113,8 @@ on_name_owner_changed (GDBusConnection * |
| 54 | static void |
| 55 | a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop (gpointer user_data) |
| 56 | { |
| 57 | - volatile gboolean *val = user_data; |
| 58 | - *val = TRUE; |
| 59 | + gboolean *val = user_data; /* (atomic) */ |
| 60 | + g_atomic_int_set (val, TRUE); |
| 61 | _log ("destroynotify fired for %p", val); |
| 62 | g_main_loop_quit (loop); |
| 63 | } |
| 64 | @@ -143,10 +143,10 @@ test_connection_life_cycle (void) |
| 65 | GDBusConnection *c; |
| 66 | GDBusConnection *c2; |
| 67 | GError *error; |
| 68 | - volatile gboolean on_signal_registration_freed_called; |
| 69 | - volatile gboolean on_filter_freed_called; |
| 70 | - volatile gboolean on_register_object_freed_called; |
| 71 | - volatile gboolean quit_mainloop_fired; |
| 72 | + gboolean on_signal_registration_freed_called; /* (atomic) */ |
| 73 | + gboolean on_filter_freed_called; /* (atomic) */ |
| 74 | + gboolean on_register_object_freed_called; /* (atomic) */ |
| 75 | + gboolean quit_mainloop_fired; /* (atomic) */ |
| 76 | guint quit_mainloop_id; |
| 77 | guint registration_id; |
| 78 | |
| 79 | @@ -208,7 +208,7 @@ test_connection_life_cycle (void) |
| 80 | g_assert_no_error (error); |
| 81 | g_assert_nonnull (c2); |
| 82 | /* signal registration */ |
| 83 | - on_signal_registration_freed_called = FALSE; |
| 84 | + g_atomic_int_set (&on_signal_registration_freed_called, FALSE); |
| 85 | g_dbus_connection_signal_subscribe (c2, |
| 86 | "org.freedesktop.DBus", /* bus name */ |
| 87 | "org.freedesktop.DBus", /* interface */ |
| 88 | @@ -220,13 +220,13 @@ test_connection_life_cycle (void) |
| 89 | (gpointer) &on_signal_registration_freed_called, |
| 90 | a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop); |
| 91 | /* filter func */ |
| 92 | - on_filter_freed_called = FALSE; |
| 93 | + g_atomic_int_set (&on_filter_freed_called, FALSE); |
| 94 | g_dbus_connection_add_filter (c2, |
| 95 | some_filter_func, |
| 96 | (gpointer) &on_filter_freed_called, |
| 97 | a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop); |
| 98 | /* object registration */ |
| 99 | - on_register_object_freed_called = FALSE; |
| 100 | + g_atomic_int_set (&on_register_object_freed_called, FALSE); |
| 101 | error = NULL; |
| 102 | registration_id = g_dbus_connection_register_object (c2, |
| 103 | "/foo", |
| 104 | @@ -239,7 +239,7 @@ test_connection_life_cycle (void) |
| 105 | g_assert_cmpuint (registration_id, >, 0); |
| 106 | /* ok, finalize the connection and check that all the GDestroyNotify functions are invoked as expected */ |
| 107 | g_object_unref (c2); |
| 108 | - quit_mainloop_fired = FALSE; |
| 109 | + g_atomic_int_set (&quit_mainloop_fired, FALSE); |
| 110 | quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, (gpointer) &quit_mainloop_fired); |
| 111 | _log ("destroynotifies for\n" |
| 112 | " register_object %p\n" |
| 113 | @@ -250,21 +250,21 @@ test_connection_life_cycle (void) |
| 114 | &on_signal_registration_freed_called); |
| 115 | while (TRUE) |
| 116 | { |
| 117 | - if (on_signal_registration_freed_called && |
| 118 | - on_filter_freed_called && |
| 119 | - on_register_object_freed_called) |
| 120 | + if (g_atomic_int_get (&on_signal_registration_freed_called) && |
| 121 | + g_atomic_int_get (&on_filter_freed_called) && |
| 122 | + g_atomic_int_get (&on_register_object_freed_called)) |
| 123 | break; |
| 124 | - if (quit_mainloop_fired) |
| 125 | + if (g_atomic_int_get (&quit_mainloop_fired)) |
| 126 | break; |
| 127 | _log ("entering loop"); |
| 128 | g_main_loop_run (loop); |
| 129 | _log ("exiting loop"); |
| 130 | } |
| 131 | g_source_remove (quit_mainloop_id); |
| 132 | - g_assert_true (on_signal_registration_freed_called); |
| 133 | - g_assert_true (on_filter_freed_called); |
| 134 | - g_assert_true (on_register_object_freed_called); |
| 135 | - g_assert_false (quit_mainloop_fired); |
| 136 | + g_assert_true (g_atomic_int_get (&on_signal_registration_freed_called)); |
| 137 | + g_assert_true (g_atomic_int_get (&on_filter_freed_called)); |
| 138 | + g_assert_true (g_atomic_int_get (&on_register_object_freed_called)); |
| 139 | + g_assert_false (g_atomic_int_get (&quit_mainloop_fired)); |
| 140 | |
| 141 | /* |
| 142 | * Check for correct behavior when the bus goes away |
| 143 | --- a/gio/tests/gdbus-overflow.c |
| 144 | +++ b/gio/tests/gdbus-overflow.c |
| 145 | @@ -86,8 +86,8 @@ overflow_filter_func (GDBusConnection *c |
| 146 | gboolean incoming, |
| 147 | gpointer user_data) |
| 148 | { |
| 149 | - volatile gint *counter = user_data; |
| 150 | - *counter += 1; |
| 151 | + gint *counter = user_data; /* (atomic) */ |
| 152 | + g_atomic_int_inc (counter); |
| 153 | return message; |
| 154 | } |
| 155 | |
| 156 | @@ -108,8 +108,8 @@ test_overflow (void) |
| 157 | GDBusConnection *producer, *consumer; |
| 158 | GError *error; |
| 159 | GTimer *timer; |
| 160 | - volatile gint n_messages_received; |
| 161 | - volatile gint n_messages_sent; |
| 162 | + gint n_messages_received; /* (atomic) */ |
| 163 | + gint n_messages_sent; /* (atomic) */ |
| 164 | |
| 165 | g_assert_cmpint (socketpair (AF_UNIX, SOCK_STREAM, 0, sv), ==, 0); |
| 166 | |
| 167 | @@ -129,7 +129,7 @@ test_overflow (void) |
| 168 | g_dbus_connection_set_exit_on_close (producer, TRUE); |
| 169 | g_assert_no_error (error); |
| 170 | g_object_unref (socket_connection); |
| 171 | - n_messages_sent = 0; |
| 172 | + g_atomic_int_set (&n_messages_sent, 0); |
| 173 | g_dbus_connection_add_filter (producer, overflow_filter_func, (gpointer) &n_messages_sent, NULL); |
| 174 | |
| 175 | /* send enough data that we get an EAGAIN */ |
| 176 | @@ -155,7 +155,7 @@ test_overflow (void) |
| 177 | */ |
| 178 | g_timeout_add (500, overflow_on_500ms_later_func, NULL); |
| 179 | g_main_loop_run (loop); |
| 180 | - g_assert_cmpint (n_messages_sent, <, OVERFLOW_NUM_SIGNALS); |
| 181 | + g_assert_cmpint (g_atomic_int_get (&n_messages_sent), <, OVERFLOW_NUM_SIGNALS); |
| 182 | |
| 183 | /* now suck it all out as a client, and add it up */ |
| 184 | socket = g_socket_new_from_fd (sv[1], &error); |
| 185 | @@ -171,18 +171,18 @@ test_overflow (void) |
| 186 | &error); |
| 187 | g_assert_no_error (error); |
| 188 | g_object_unref (socket_connection); |
| 189 | - n_messages_received = 0; |
| 190 | + g_atomic_int_set (&n_messages_received, 0); |
| 191 | g_dbus_connection_add_filter (consumer, overflow_filter_func, (gpointer) &n_messages_received, NULL); |
| 192 | g_dbus_connection_start_message_processing (consumer); |
| 193 | |
| 194 | timer = g_timer_new (); |
| 195 | g_timer_start (timer); |
| 196 | |
| 197 | - while (n_messages_received < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC) |
| 198 | + while (g_atomic_int_get (&n_messages_received) < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC) |
| 199 | g_main_context_iteration (NULL, FALSE); |
| 200 | |
| 201 | - g_assert_cmpint (n_messages_sent, ==, OVERFLOW_NUM_SIGNALS); |
| 202 | - g_assert_cmpint (n_messages_received, ==, OVERFLOW_NUM_SIGNALS); |
| 203 | + g_assert_cmpint (g_atomic_int_get (&n_messages_sent), ==, OVERFLOW_NUM_SIGNALS); |
| 204 | + g_assert_cmpint (g_atomic_int_get (&n_messages_received), ==, OVERFLOW_NUM_SIGNALS); |
| 205 | |
| 206 | g_timer_destroy (timer); |
| 207 | g_object_unref (consumer); |
| 208 | --- a/gio/tests/socket-service.c |
| 209 | +++ b/gio/tests/socket-service.c |
| 210 | @@ -99,7 +99,7 @@ test_start_stop (void) |
| 211 | |
| 212 | GMutex mutex_712570; |
| 213 | GCond cond_712570; |
| 214 | -volatile gboolean finalized; |
| 215 | +gboolean finalized; /* (atomic) */ |
| 216 | |
| 217 | GType test_threaded_socket_service_get_type (void); |
| 218 | typedef GThreadedSocketService TestThreadedSocketService; |
| 219 | @@ -120,7 +120,7 @@ test_threaded_socket_service_finalize (G |
| 220 | /* Signal the main thread that finalization completed successfully |
| 221 | * rather than hanging. |
| 222 | */ |
| 223 | - finalized = TRUE; |
| 224 | + g_atomic_int_set (&finalized, TRUE); |
| 225 | g_cond_signal (&cond_712570); |
| 226 | g_mutex_unlock (&mutex_712570); |
| 227 | } |
| 228 | @@ -235,7 +235,7 @@ test_threaded_712570 (void) |
| 229 | */ |
| 230 | g_object_unref (service); |
| 231 | |
| 232 | - while (!finalized) |
| 233 | + while (!g_atomic_int_get (&finalized)) |
| 234 | g_cond_wait (&cond_712570, &mutex_712570); |
| 235 | g_mutex_unlock (&mutex_712570); |
| 236 | } |
| 237 | --- a/gio/tests/task.c |
| 238 | +++ b/gio/tests/task.c |
| 239 | @@ -957,7 +957,7 @@ task_weak_notify (gpointer user_data, |
| 240 | gboolean *weak_notify_ran = user_data; |
| 241 | |
| 242 | g_mutex_lock (&run_in_thread_mutex); |
| 243 | - *weak_notify_ran = TRUE; |
| 244 | + g_atomic_int_set (weak_notify_ran, TRUE); |
| 245 | g_cond_signal (&run_in_thread_cond); |
| 246 | g_mutex_unlock (&run_in_thread_mutex); |
| 247 | } |
| 248 | @@ -1007,7 +1007,7 @@ run_in_thread_thread (GTask *task |
| 249 | g_assert (g_thread_self () != main_thread); |
| 250 | |
| 251 | g_mutex_lock (&run_in_thread_mutex); |
| 252 | - *thread_ran = TRUE; |
| 253 | + g_atomic_int_set (thread_ran, TRUE); |
| 254 | g_cond_signal (&run_in_thread_cond); |
| 255 | g_mutex_unlock (&run_in_thread_mutex); |
| 256 | |
| 257 | @@ -1018,8 +1018,8 @@ static void |
| 258 | test_run_in_thread (void) |
| 259 | { |
| 260 | GTask *task; |
| 261 | - volatile gboolean thread_ran = FALSE; |
| 262 | - volatile gboolean weak_notify_ran = FALSE; |
| 263 | + gboolean thread_ran = FALSE; /* (atomic) */ |
| 264 | + gboolean weak_notify_ran = FALSE; /* (atomic) */ |
| 265 | gboolean notification_emitted = FALSE; |
| 266 | gboolean done = FALSE; |
| 267 | |
| 268 | @@ -1033,12 +1033,12 @@ test_run_in_thread (void) |
| 269 | g_task_run_in_thread (task, run_in_thread_thread); |
| 270 | |
| 271 | g_mutex_lock (&run_in_thread_mutex); |
| 272 | - while (!thread_ran) |
| 273 | + while (!g_atomic_int_get (&thread_ran)) |
| 274 | g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); |
| 275 | g_mutex_unlock (&run_in_thread_mutex); |
| 276 | |
| 277 | g_assert (done == FALSE); |
| 278 | - g_assert (weak_notify_ran == FALSE); |
| 279 | + g_assert_false (g_atomic_int_get (&weak_notify_ran)); |
| 280 | |
| 281 | g_main_loop_run (loop); |
| 282 | |
| 283 | @@ -1050,7 +1050,7 @@ test_run_in_thread (void) |
| 284 | g_object_unref (task); |
| 285 | |
| 286 | g_mutex_lock (&run_in_thread_mutex); |
| 287 | - while (!weak_notify_ran) |
| 288 | + while (!g_atomic_int_get (&weak_notify_ran)) |
| 289 | g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); |
| 290 | g_mutex_unlock (&run_in_thread_mutex); |
| 291 | } |
| 292 | @@ -1081,7 +1081,7 @@ run_in_thread_sync_thread (GTask |
| 293 | |
| 294 | g_assert (g_thread_self () != main_thread); |
| 295 | |
| 296 | - *thread_ran = TRUE; |
| 297 | + g_atomic_int_set (thread_ran, TRUE); |
| 298 | g_task_return_int (task, magic); |
| 299 | } |
| 300 | |
| 301 | @@ -1102,7 +1102,7 @@ test_run_in_thread_sync (void) |
| 302 | g_task_set_task_data (task, &thread_ran, NULL); |
| 303 | g_task_run_in_thread_sync (task, run_in_thread_sync_thread); |
| 304 | |
| 305 | - g_assert (thread_ran == TRUE); |
| 306 | + g_assert_true (g_atomic_int_get (&thread_ran)); |
| 307 | g_assert (task != NULL); |
| 308 | g_assert (!g_task_had_error (task)); |
| 309 | g_assert_true (g_task_get_completed (task)); |
| 310 | @@ -1487,8 +1487,8 @@ test_return_on_cancel (void) |
| 311 | { |
| 312 | GTask *task; |
| 313 | GCancellable *cancellable; |
| 314 | - volatile ThreadState thread_state; |
| 315 | - volatile gboolean weak_notify_ran = FALSE; |
| 316 | + ThreadState thread_state; /* (atomic) */ |
| 317 | + gboolean weak_notify_ran = FALSE; /* (atomic) */ |
| 318 | gboolean callback_ran; |
| 319 | gboolean notification_emitted = FALSE; |
| 320 | |
| 321 | @@ -1498,7 +1498,7 @@ test_return_on_cancel (void) |
| 322 | * early. |
| 323 | */ |
| 324 | callback_ran = FALSE; |
| 325 | - thread_state = THREAD_STARTING; |
| 326 | + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| 327 | task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); |
| 328 | g_signal_connect (task, "notify::completed", |
| 329 | (GCallback) completed_cb, ¬ification_emitted); |
| 330 | @@ -1509,18 +1509,18 @@ test_return_on_cancel (void) |
| 331 | g_task_run_in_thread (task, return_on_cancel_thread); |
| 332 | g_object_unref (task); |
| 333 | |
| 334 | - while (thread_state == THREAD_STARTING) |
| 335 | + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| 336 | g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| 337 | g_mutex_unlock (&roc_init_mutex); |
| 338 | |
| 339 | - g_assert (thread_state == THREAD_RUNNING); |
| 340 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| 341 | g_assert (callback_ran == FALSE); |
| 342 | |
| 343 | g_cancellable_cancel (cancellable); |
| 344 | g_mutex_unlock (&roc_finish_mutex); |
| 345 | g_main_loop_run (loop); |
| 346 | |
| 347 | - g_assert (thread_state == THREAD_COMPLETED); |
| 348 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED); |
| 349 | g_assert (callback_ran == TRUE); |
| 350 | g_assert_true (notification_emitted); |
| 351 | |
| 352 | @@ -1529,7 +1529,7 @@ test_return_on_cancel (void) |
| 353 | /* If return-on-cancel is TRUE, it does return early */ |
| 354 | callback_ran = FALSE; |
| 355 | notification_emitted = FALSE; |
| 356 | - thread_state = THREAD_STARTING; |
| 357 | + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| 358 | task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); |
| 359 | g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran); |
| 360 | g_signal_connect (task, "notify::completed", |
| 361 | @@ -1542,27 +1542,27 @@ test_return_on_cancel (void) |
| 362 | g_task_run_in_thread (task, return_on_cancel_thread); |
| 363 | g_object_unref (task); |
| 364 | |
| 365 | - while (thread_state == THREAD_STARTING) |
| 366 | + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| 367 | g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| 368 | g_mutex_unlock (&roc_init_mutex); |
| 369 | |
| 370 | - g_assert (thread_state == THREAD_RUNNING); |
| 371 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| 372 | g_assert (callback_ran == FALSE); |
| 373 | |
| 374 | g_cancellable_cancel (cancellable); |
| 375 | g_main_loop_run (loop); |
| 376 | - g_assert (thread_state == THREAD_RUNNING); |
| 377 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| 378 | g_assert (callback_ran == TRUE); |
| 379 | |
| 380 | - g_assert (weak_notify_ran == FALSE); |
| 381 | + g_assert_false (g_atomic_int_get (&weak_notify_ran)); |
| 382 | |
| 383 | - while (thread_state == THREAD_RUNNING) |
| 384 | + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) |
| 385 | g_cond_wait (&roc_finish_cond, &roc_finish_mutex); |
| 386 | g_mutex_unlock (&roc_finish_mutex); |
| 387 | |
| 388 | - g_assert (thread_state == THREAD_CANCELLED); |
| 389 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); |
| 390 | g_mutex_lock (&run_in_thread_mutex); |
| 391 | - while (!weak_notify_ran) |
| 392 | + while (!g_atomic_int_get (&weak_notify_ran)) |
| 393 | g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); |
| 394 | g_mutex_unlock (&run_in_thread_mutex); |
| 395 | |
| 396 | @@ -1574,7 +1574,7 @@ test_return_on_cancel (void) |
| 397 | */ |
| 398 | callback_ran = FALSE; |
| 399 | notification_emitted = FALSE; |
| 400 | - thread_state = THREAD_STARTING; |
| 401 | + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| 402 | task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); |
| 403 | g_signal_connect (task, "notify::completed", |
| 404 | (GCallback) completed_cb, ¬ification_emitted); |
| 405 | @@ -1591,17 +1591,17 @@ test_return_on_cancel (void) |
| 406 | g_main_loop_run (loop); |
| 407 | g_assert (callback_ran == TRUE); |
| 408 | |
| 409 | - while (thread_state == THREAD_STARTING) |
| 410 | + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| 411 | g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| 412 | g_mutex_unlock (&roc_init_mutex); |
| 413 | |
| 414 | - g_assert (thread_state == THREAD_RUNNING); |
| 415 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| 416 | |
| 417 | - while (thread_state == THREAD_RUNNING) |
| 418 | + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) |
| 419 | g_cond_wait (&roc_finish_cond, &roc_finish_mutex); |
| 420 | g_mutex_unlock (&roc_finish_mutex); |
| 421 | |
| 422 | - g_assert (thread_state == THREAD_CANCELLED); |
| 423 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); |
| 424 | g_assert_true (notification_emitted); |
| 425 | |
| 426 | g_object_unref (cancellable); |
| 427 | @@ -1621,7 +1621,7 @@ test_return_on_cancel_sync (void) |
| 428 | { |
| 429 | GTask *task; |
| 430 | GCancellable *cancellable; |
| 431 | - volatile ThreadState thread_state; |
| 432 | + ThreadState thread_state; /* (atomic) */ |
| 433 | GThread *runner_thread; |
| 434 | gssize ret; |
| 435 | GError *error = NULL; |
| 436 | @@ -1630,7 +1630,7 @@ test_return_on_cancel_sync (void) |
| 437 | |
| 438 | /* If return-on-cancel is FALSE, the task does not return early. |
| 439 | */ |
| 440 | - thread_state = THREAD_STARTING; |
| 441 | + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| 442 | task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); |
| 443 | |
| 444 | g_task_set_task_data (task, (gpointer)&thread_state, NULL); |
| 445 | @@ -1639,16 +1639,16 @@ test_return_on_cancel_sync (void) |
| 446 | runner_thread = g_thread_new ("return-on-cancel-sync runner thread", |
| 447 | cancel_sync_runner_thread, task); |
| 448 | |
| 449 | - while (thread_state == THREAD_STARTING) |
| 450 | + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| 451 | g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| 452 | g_mutex_unlock (&roc_init_mutex); |
| 453 | |
| 454 | - g_assert (thread_state == THREAD_RUNNING); |
| 455 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| 456 | |
| 457 | g_cancellable_cancel (cancellable); |
| 458 | g_mutex_unlock (&roc_finish_mutex); |
| 459 | g_thread_join (runner_thread); |
| 460 | - g_assert (thread_state == THREAD_COMPLETED); |
| 461 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED); |
| 462 | |
| 463 | ret = g_task_propagate_int (task, &error); |
| 464 | g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); |
| 465 | @@ -1660,7 +1660,7 @@ test_return_on_cancel_sync (void) |
| 466 | g_cancellable_reset (cancellable); |
| 467 | |
| 468 | /* If return-on-cancel is TRUE, it does return early */ |
| 469 | - thread_state = THREAD_STARTING; |
| 470 | + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| 471 | task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); |
| 472 | g_task_set_return_on_cancel (task, TRUE); |
| 473 | |
| 474 | @@ -1670,15 +1670,15 @@ test_return_on_cancel_sync (void) |
| 475 | runner_thread = g_thread_new ("return-on-cancel-sync runner thread", |
| 476 | cancel_sync_runner_thread, task); |
| 477 | |
| 478 | - while (thread_state == THREAD_STARTING) |
| 479 | + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| 480 | g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| 481 | g_mutex_unlock (&roc_init_mutex); |
| 482 | |
| 483 | - g_assert (thread_state == THREAD_RUNNING); |
| 484 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| 485 | |
| 486 | g_cancellable_cancel (cancellable); |
| 487 | g_thread_join (runner_thread); |
| 488 | - g_assert (thread_state == THREAD_RUNNING); |
| 489 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| 490 | |
| 491 | ret = g_task_propagate_int (task, &error); |
| 492 | g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); |
| 493 | @@ -1687,18 +1687,18 @@ test_return_on_cancel_sync (void) |
| 494 | |
| 495 | g_object_unref (task); |
| 496 | |
| 497 | - while (thread_state == THREAD_RUNNING) |
| 498 | + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) |
| 499 | g_cond_wait (&roc_finish_cond, &roc_finish_mutex); |
| 500 | g_mutex_unlock (&roc_finish_mutex); |
| 501 | |
| 502 | - g_assert (thread_state == THREAD_CANCELLED); |
| 503 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); |
| 504 | |
| 505 | g_cancellable_reset (cancellable); |
| 506 | |
| 507 | /* If the task is already cancelled before it starts, it returns |
| 508 | * immediately, but the thread func still runs. |
| 509 | */ |
| 510 | - thread_state = THREAD_STARTING; |
| 511 | + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| 512 | task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); |
| 513 | g_task_set_return_on_cancel (task, TRUE); |
| 514 | |
| 515 | @@ -1711,7 +1711,7 @@ test_return_on_cancel_sync (void) |
| 516 | cancel_sync_runner_thread, task); |
| 517 | |
| 518 | g_thread_join (runner_thread); |
| 519 | - g_assert (thread_state == THREAD_STARTING); |
| 520 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_STARTING); |
| 521 | |
| 522 | ret = g_task_propagate_int (task, &error); |
| 523 | g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); |
| 524 | @@ -1720,17 +1720,17 @@ test_return_on_cancel_sync (void) |
| 525 | |
| 526 | g_object_unref (task); |
| 527 | |
| 528 | - while (thread_state == THREAD_STARTING) |
| 529 | + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| 530 | g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| 531 | g_mutex_unlock (&roc_init_mutex); |
| 532 | |
| 533 | - g_assert (thread_state == THREAD_RUNNING); |
| 534 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| 535 | |
| 536 | - while (thread_state == THREAD_RUNNING) |
| 537 | + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) |
| 538 | g_cond_wait (&roc_finish_cond, &roc_finish_mutex); |
| 539 | g_mutex_unlock (&roc_finish_mutex); |
| 540 | |
| 541 | - g_assert (thread_state == THREAD_CANCELLED); |
| 542 | + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); |
| 543 | |
| 544 | g_object_unref (cancellable); |
| 545 | } |
| 546 | @@ -1776,7 +1776,7 @@ return_on_cancel_atomic_thread (GTask |
| 547 | gpointer task_data, |
| 548 | GCancellable *cancellable) |
| 549 | { |
| 550 | - gint *state = task_data; |
| 551 | + gint *state = task_data; /* (atomic) */ |
| 552 | |
| 553 | g_assert (source_object == g_task_get_source_object (task)); |
| 554 | g_assert (task_data == g_task_get_task_data (task)); |
| 555 | @@ -1784,34 +1784,34 @@ return_on_cancel_atomic_thread (GTask |
| 556 | g_assert_false (g_task_get_completed (task)); |
| 557 | |
| 558 | g_assert (g_thread_self () != main_thread); |
| 559 | - g_assert_cmpint (*state, ==, 0); |
| 560 | + g_assert_cmpint (g_atomic_int_get (state), ==, 0); |
| 561 | |
| 562 | g_mutex_lock (&roca_mutex_1); |
| 563 | - *state = 1; |
| 564 | + g_atomic_int_set (state, 1); |
| 565 | g_cond_signal (&roca_cond_1); |
| 566 | g_mutex_unlock (&roca_mutex_1); |
| 567 | |
| 568 | g_mutex_lock (&roca_mutex_2); |
| 569 | if (g_task_set_return_on_cancel (task, FALSE)) |
| 570 | - *state = 2; |
| 571 | + g_atomic_int_set (state, 2); |
| 572 | else |
| 573 | - *state = 3; |
| 574 | + g_atomic_int_set (state, 3); |
| 575 | g_cond_signal (&roca_cond_2); |
| 576 | g_mutex_unlock (&roca_mutex_2); |
| 577 | |
| 578 | g_mutex_lock (&roca_mutex_1); |
| 579 | if (g_task_set_return_on_cancel (task, TRUE)) |
| 580 | - *state = 4; |
| 581 | + g_atomic_int_set (state, 4); |
| 582 | else |
| 583 | - *state = 5; |
| 584 | + g_atomic_int_set (state, 5); |
| 585 | g_cond_signal (&roca_cond_1); |
| 586 | g_mutex_unlock (&roca_mutex_1); |
| 587 | |
| 588 | g_mutex_lock (&roca_mutex_2); |
| 589 | if (g_task_set_return_on_cancel (task, TRUE)) |
| 590 | - *state = 6; |
| 591 | + g_atomic_int_set (state, 6); |
| 592 | else |
| 593 | - *state = 7; |
| 594 | + g_atomic_int_set (state, 7); |
| 595 | g_cond_signal (&roca_cond_2); |
| 596 | g_mutex_unlock (&roca_mutex_2); |
| 597 | |
| 598 | @@ -1823,7 +1823,7 @@ test_return_on_cancel_atomic (void) |
| 599 | { |
| 600 | GTask *task; |
| 601 | GCancellable *cancellable; |
| 602 | - volatile gint state; |
| 603 | + gint state; /* (atomic) */ |
| 604 | gboolean notification_emitted = FALSE; |
| 605 | gboolean callback_ran; |
| 606 | |
| 607 | @@ -1832,7 +1832,7 @@ test_return_on_cancel_atomic (void) |
| 608 | g_mutex_lock (&roca_mutex_2); |
| 609 | |
| 610 | /* If we don't cancel it, each set_return_on_cancel() call will succeed */ |
| 611 | - state = 0; |
| 612 | + g_atomic_int_set (&state, 0); |
| 613 | callback_ran = FALSE; |
| 614 | task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran); |
| 615 | g_task_set_return_on_cancel (task, TRUE); |
| 616 | @@ -1843,23 +1843,23 @@ test_return_on_cancel_atomic (void) |
| 617 | g_task_run_in_thread (task, return_on_cancel_atomic_thread); |
| 618 | g_object_unref (task); |
| 619 | |
| 620 | - g_assert_cmpint (state, ==, 0); |
| 621 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 0); |
| 622 | |
| 623 | - while (state == 0) |
| 624 | + while (g_atomic_int_get (&state) == 0) |
| 625 | g_cond_wait (&roca_cond_1, &roca_mutex_1); |
| 626 | - g_assert (state == 1); |
| 627 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 1); |
| 628 | |
| 629 | - while (state == 1) |
| 630 | + while (g_atomic_int_get (&state) == 1) |
| 631 | g_cond_wait (&roca_cond_2, &roca_mutex_2); |
| 632 | - g_assert (state == 2); |
| 633 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 2); |
| 634 | |
| 635 | - while (state == 2) |
| 636 | + while (g_atomic_int_get (&state) == 2) |
| 637 | g_cond_wait (&roca_cond_1, &roca_mutex_1); |
| 638 | - g_assert (state == 4); |
| 639 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 4); |
| 640 | |
| 641 | - while (state == 4) |
| 642 | + while (g_atomic_int_get (&state) == 4) |
| 643 | g_cond_wait (&roca_cond_2, &roca_mutex_2); |
| 644 | - g_assert (state == 6); |
| 645 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 6); |
| 646 | |
| 647 | /* callback assumes there'll be a cancelled error */ |
| 648 | g_cancellable_cancel (cancellable); |
| 649 | @@ -1876,7 +1876,7 @@ test_return_on_cancel_atomic (void) |
| 650 | * task won't complete right away, and further |
| 651 | * g_task_set_return_on_cancel() calls will return FALSE. |
| 652 | */ |
| 653 | - state = 0; |
| 654 | + g_atomic_int_set (&state, 0); |
| 655 | callback_ran = FALSE; |
| 656 | notification_emitted = FALSE; |
| 657 | task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran); |
| 658 | @@ -1887,16 +1887,16 @@ test_return_on_cancel_atomic (void) |
| 659 | g_task_set_task_data (task, (gpointer)&state, NULL); |
| 660 | g_task_run_in_thread (task, return_on_cancel_atomic_thread); |
| 661 | |
| 662 | - g_assert_cmpint (state, ==, 0); |
| 663 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 0); |
| 664 | |
| 665 | - while (state == 0) |
| 666 | + while (g_atomic_int_get (&state) == 0) |
| 667 | g_cond_wait (&roca_cond_1, &roca_mutex_1); |
| 668 | - g_assert (state == 1); |
| 669 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 1); |
| 670 | g_assert (g_task_get_return_on_cancel (task)); |
| 671 | |
| 672 | - while (state == 1) |
| 673 | + while (g_atomic_int_get (&state) == 1) |
| 674 | g_cond_wait (&roca_cond_2, &roca_mutex_2); |
| 675 | - g_assert (state == 2); |
| 676 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 2); |
| 677 | g_assert (!g_task_get_return_on_cancel (task)); |
| 678 | |
| 679 | g_cancellable_cancel (cancellable); |
| 680 | @@ -1904,18 +1904,18 @@ test_return_on_cancel_atomic (void) |
| 681 | g_main_loop_run (loop); |
| 682 | g_assert (callback_ran == FALSE); |
| 683 | |
| 684 | - while (state == 2) |
| 685 | + while (g_atomic_int_get (&state) == 2) |
| 686 | g_cond_wait (&roca_cond_1, &roca_mutex_1); |
| 687 | - g_assert (state == 5); |
| 688 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 5); |
| 689 | g_assert (!g_task_get_return_on_cancel (task)); |
| 690 | |
| 691 | g_main_loop_run (loop); |
| 692 | g_assert (callback_ran == TRUE); |
| 693 | g_assert_true (notification_emitted); |
| 694 | |
| 695 | - while (state == 5) |
| 696 | + while (g_atomic_int_get (&state) == 5) |
| 697 | g_cond_wait (&roca_cond_2, &roca_mutex_2); |
| 698 | - g_assert (state == 7); |
| 699 | + g_assert_cmpint (g_atomic_int_get (&state), ==, 7); |
| 700 | |
| 701 | g_object_unref (cancellable); |
| 702 | g_mutex_unlock (&roca_mutex_1); |