| From 7f905ff1faf0acbe0d2ce69937e031fcacce9294 Mon Sep 17 00:00:00 2001 |
| From: Philip Withnall <pwithnall@endlessos.org> |
| Date: Wed, 11 Nov 2020 18:21:00 +0000 |
| Subject: [PATCH 05/29] tests: Fix non-atomic access to some shared variables |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| And drop the `volatile` qualifier from the variables, as that doesn’t |
| help with thread safety. |
| |
| Signed-off-by: Philip Withnall <pwithnall@endlessos.org> |
| |
| Helps: #600 |
| Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1719] |
| --- |
| gio/tests/gdbus-connection-flush.c | 6 +- |
| gio/tests/gdbus-connection.c | 40 ++++---- |
| gio/tests/gdbus-overflow.c | 20 ++-- |
| gio/tests/socket-service.c | 6 +- |
| gio/tests/task.c | 150 ++++++++++++++--------------- |
| 5 files changed, 111 insertions(+), 111 deletions(-) |
| |
| --- a/gio/tests/gdbus-connection-flush.c |
| +++ b/gio/tests/gdbus-connection-flush.c |
| @@ -43,9 +43,9 @@ G_LOCK_DEFINE_STATIC (write); |
| typedef struct { |
| GFilterOutputStream parent; |
| |
| - volatile gint started; |
| - volatile gint finished; |
| - volatile gint flushed; |
| + gint started; /* (atomic) */ |
| + gint finished; /* (atomic) */ |
| + gint flushed; /* (atomic) */ |
| |
| GOutputStream *real_output; |
| } MyOutputStream; |
| --- a/gio/tests/gdbus-connection.c |
| +++ b/gio/tests/gdbus-connection.c |
| @@ -61,9 +61,9 @@ _log (const gchar *format, ...) |
| static gboolean |
| test_connection_quit_mainloop (gpointer user_data) |
| { |
| - volatile gboolean *quit_mainloop_fired = user_data; |
| + gboolean *quit_mainloop_fired = user_data; /* (atomic) */ |
| _log ("quit_mainloop_fired"); |
| - *quit_mainloop_fired = TRUE; |
| + g_atomic_int_set (quit_mainloop_fired, TRUE); |
| g_main_loop_quit (loop); |
| return TRUE; |
| } |
| @@ -113,8 +113,8 @@ on_name_owner_changed (GDBusConnection * |
| static void |
| a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop (gpointer user_data) |
| { |
| - volatile gboolean *val = user_data; |
| - *val = TRUE; |
| + gboolean *val = user_data; /* (atomic) */ |
| + g_atomic_int_set (val, TRUE); |
| _log ("destroynotify fired for %p", val); |
| g_main_loop_quit (loop); |
| } |
| @@ -143,10 +143,10 @@ test_connection_life_cycle (void) |
| GDBusConnection *c; |
| GDBusConnection *c2; |
| GError *error; |
| - volatile gboolean on_signal_registration_freed_called; |
| - volatile gboolean on_filter_freed_called; |
| - volatile gboolean on_register_object_freed_called; |
| - volatile gboolean quit_mainloop_fired; |
| + gboolean on_signal_registration_freed_called; /* (atomic) */ |
| + gboolean on_filter_freed_called; /* (atomic) */ |
| + gboolean on_register_object_freed_called; /* (atomic) */ |
| + gboolean quit_mainloop_fired; /* (atomic) */ |
| guint quit_mainloop_id; |
| guint registration_id; |
| |
| @@ -208,7 +208,7 @@ test_connection_life_cycle (void) |
| g_assert_no_error (error); |
| g_assert_nonnull (c2); |
| /* signal registration */ |
| - on_signal_registration_freed_called = FALSE; |
| + g_atomic_int_set (&on_signal_registration_freed_called, FALSE); |
| g_dbus_connection_signal_subscribe (c2, |
| "org.freedesktop.DBus", /* bus name */ |
| "org.freedesktop.DBus", /* interface */ |
| @@ -220,13 +220,13 @@ test_connection_life_cycle (void) |
| (gpointer) &on_signal_registration_freed_called, |
| a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop); |
| /* filter func */ |
| - on_filter_freed_called = FALSE; |
| + g_atomic_int_set (&on_filter_freed_called, FALSE); |
| g_dbus_connection_add_filter (c2, |
| some_filter_func, |
| (gpointer) &on_filter_freed_called, |
| a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop); |
| /* object registration */ |
| - on_register_object_freed_called = FALSE; |
| + g_atomic_int_set (&on_register_object_freed_called, FALSE); |
| error = NULL; |
| registration_id = g_dbus_connection_register_object (c2, |
| "/foo", |
| @@ -239,7 +239,7 @@ test_connection_life_cycle (void) |
| g_assert_cmpuint (registration_id, >, 0); |
| /* ok, finalize the connection and check that all the GDestroyNotify functions are invoked as expected */ |
| g_object_unref (c2); |
| - quit_mainloop_fired = FALSE; |
| + g_atomic_int_set (&quit_mainloop_fired, FALSE); |
| quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, (gpointer) &quit_mainloop_fired); |
| _log ("destroynotifies for\n" |
| " register_object %p\n" |
| @@ -250,21 +250,21 @@ test_connection_life_cycle (void) |
| &on_signal_registration_freed_called); |
| while (TRUE) |
| { |
| - if (on_signal_registration_freed_called && |
| - on_filter_freed_called && |
| - on_register_object_freed_called) |
| + if (g_atomic_int_get (&on_signal_registration_freed_called) && |
| + g_atomic_int_get (&on_filter_freed_called) && |
| + g_atomic_int_get (&on_register_object_freed_called)) |
| break; |
| - if (quit_mainloop_fired) |
| + if (g_atomic_int_get (&quit_mainloop_fired)) |
| break; |
| _log ("entering loop"); |
| g_main_loop_run (loop); |
| _log ("exiting loop"); |
| } |
| g_source_remove (quit_mainloop_id); |
| - g_assert_true (on_signal_registration_freed_called); |
| - g_assert_true (on_filter_freed_called); |
| - g_assert_true (on_register_object_freed_called); |
| - g_assert_false (quit_mainloop_fired); |
| + g_assert_true (g_atomic_int_get (&on_signal_registration_freed_called)); |
| + g_assert_true (g_atomic_int_get (&on_filter_freed_called)); |
| + g_assert_true (g_atomic_int_get (&on_register_object_freed_called)); |
| + g_assert_false (g_atomic_int_get (&quit_mainloop_fired)); |
| |
| /* |
| * Check for correct behavior when the bus goes away |
| --- a/gio/tests/gdbus-overflow.c |
| +++ b/gio/tests/gdbus-overflow.c |
| @@ -86,8 +86,8 @@ overflow_filter_func (GDBusConnection *c |
| gboolean incoming, |
| gpointer user_data) |
| { |
| - volatile gint *counter = user_data; |
| - *counter += 1; |
| + gint *counter = user_data; /* (atomic) */ |
| + g_atomic_int_inc (counter); |
| return message; |
| } |
| |
| @@ -108,8 +108,8 @@ test_overflow (void) |
| GDBusConnection *producer, *consumer; |
| GError *error; |
| GTimer *timer; |
| - volatile gint n_messages_received; |
| - volatile gint n_messages_sent; |
| + gint n_messages_received; /* (atomic) */ |
| + gint n_messages_sent; /* (atomic) */ |
| |
| g_assert_cmpint (socketpair (AF_UNIX, SOCK_STREAM, 0, sv), ==, 0); |
| |
| @@ -129,7 +129,7 @@ test_overflow (void) |
| g_dbus_connection_set_exit_on_close (producer, TRUE); |
| g_assert_no_error (error); |
| g_object_unref (socket_connection); |
| - n_messages_sent = 0; |
| + g_atomic_int_set (&n_messages_sent, 0); |
| g_dbus_connection_add_filter (producer, overflow_filter_func, (gpointer) &n_messages_sent, NULL); |
| |
| /* send enough data that we get an EAGAIN */ |
| @@ -155,7 +155,7 @@ test_overflow (void) |
| */ |
| g_timeout_add (500, overflow_on_500ms_later_func, NULL); |
| g_main_loop_run (loop); |
| - g_assert_cmpint (n_messages_sent, <, OVERFLOW_NUM_SIGNALS); |
| + g_assert_cmpint (g_atomic_int_get (&n_messages_sent), <, OVERFLOW_NUM_SIGNALS); |
| |
| /* now suck it all out as a client, and add it up */ |
| socket = g_socket_new_from_fd (sv[1], &error); |
| @@ -171,18 +171,18 @@ test_overflow (void) |
| &error); |
| g_assert_no_error (error); |
| g_object_unref (socket_connection); |
| - n_messages_received = 0; |
| + g_atomic_int_set (&n_messages_received, 0); |
| g_dbus_connection_add_filter (consumer, overflow_filter_func, (gpointer) &n_messages_received, NULL); |
| g_dbus_connection_start_message_processing (consumer); |
| |
| timer = g_timer_new (); |
| g_timer_start (timer); |
| |
| - while (n_messages_received < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC) |
| + while (g_atomic_int_get (&n_messages_received) < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC) |
| g_main_context_iteration (NULL, FALSE); |
| |
| - g_assert_cmpint (n_messages_sent, ==, OVERFLOW_NUM_SIGNALS); |
| - g_assert_cmpint (n_messages_received, ==, OVERFLOW_NUM_SIGNALS); |
| + g_assert_cmpint (g_atomic_int_get (&n_messages_sent), ==, OVERFLOW_NUM_SIGNALS); |
| + g_assert_cmpint (g_atomic_int_get (&n_messages_received), ==, OVERFLOW_NUM_SIGNALS); |
| |
| g_timer_destroy (timer); |
| g_object_unref (consumer); |
| --- a/gio/tests/socket-service.c |
| +++ b/gio/tests/socket-service.c |
| @@ -99,7 +99,7 @@ test_start_stop (void) |
| |
| GMutex mutex_712570; |
| GCond cond_712570; |
| -volatile gboolean finalized; |
| +gboolean finalized; /* (atomic) */ |
| |
| GType test_threaded_socket_service_get_type (void); |
| typedef GThreadedSocketService TestThreadedSocketService; |
| @@ -120,7 +120,7 @@ test_threaded_socket_service_finalize (G |
| /* Signal the main thread that finalization completed successfully |
| * rather than hanging. |
| */ |
| - finalized = TRUE; |
| + g_atomic_int_set (&finalized, TRUE); |
| g_cond_signal (&cond_712570); |
| g_mutex_unlock (&mutex_712570); |
| } |
| @@ -235,7 +235,7 @@ test_threaded_712570 (void) |
| */ |
| g_object_unref (service); |
| |
| - while (!finalized) |
| + while (!g_atomic_int_get (&finalized)) |
| g_cond_wait (&cond_712570, &mutex_712570); |
| g_mutex_unlock (&mutex_712570); |
| } |
| --- a/gio/tests/task.c |
| +++ b/gio/tests/task.c |
| @@ -957,7 +957,7 @@ task_weak_notify (gpointer user_data, |
| gboolean *weak_notify_ran = user_data; |
| |
| g_mutex_lock (&run_in_thread_mutex); |
| - *weak_notify_ran = TRUE; |
| + g_atomic_int_set (weak_notify_ran, TRUE); |
| g_cond_signal (&run_in_thread_cond); |
| g_mutex_unlock (&run_in_thread_mutex); |
| } |
| @@ -1007,7 +1007,7 @@ run_in_thread_thread (GTask *task |
| g_assert (g_thread_self () != main_thread); |
| |
| g_mutex_lock (&run_in_thread_mutex); |
| - *thread_ran = TRUE; |
| + g_atomic_int_set (thread_ran, TRUE); |
| g_cond_signal (&run_in_thread_cond); |
| g_mutex_unlock (&run_in_thread_mutex); |
| |
| @@ -1018,8 +1018,8 @@ static void |
| test_run_in_thread (void) |
| { |
| GTask *task; |
| - volatile gboolean thread_ran = FALSE; |
| - volatile gboolean weak_notify_ran = FALSE; |
| + gboolean thread_ran = FALSE; /* (atomic) */ |
| + gboolean weak_notify_ran = FALSE; /* (atomic) */ |
| gboolean notification_emitted = FALSE; |
| gboolean done = FALSE; |
| |
| @@ -1033,12 +1033,12 @@ test_run_in_thread (void) |
| g_task_run_in_thread (task, run_in_thread_thread); |
| |
| g_mutex_lock (&run_in_thread_mutex); |
| - while (!thread_ran) |
| + while (!g_atomic_int_get (&thread_ran)) |
| g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); |
| g_mutex_unlock (&run_in_thread_mutex); |
| |
| g_assert (done == FALSE); |
| - g_assert (weak_notify_ran == FALSE); |
| + g_assert_false (g_atomic_int_get (&weak_notify_ran)); |
| |
| g_main_loop_run (loop); |
| |
| @@ -1050,7 +1050,7 @@ test_run_in_thread (void) |
| g_object_unref (task); |
| |
| g_mutex_lock (&run_in_thread_mutex); |
| - while (!weak_notify_ran) |
| + while (!g_atomic_int_get (&weak_notify_ran)) |
| g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); |
| g_mutex_unlock (&run_in_thread_mutex); |
| } |
| @@ -1081,7 +1081,7 @@ run_in_thread_sync_thread (GTask |
| |
| g_assert (g_thread_self () != main_thread); |
| |
| - *thread_ran = TRUE; |
| + g_atomic_int_set (thread_ran, TRUE); |
| g_task_return_int (task, magic); |
| } |
| |
| @@ -1102,7 +1102,7 @@ test_run_in_thread_sync (void) |
| g_task_set_task_data (task, &thread_ran, NULL); |
| g_task_run_in_thread_sync (task, run_in_thread_sync_thread); |
| |
| - g_assert (thread_ran == TRUE); |
| + g_assert_true (g_atomic_int_get (&thread_ran)); |
| g_assert (task != NULL); |
| g_assert (!g_task_had_error (task)); |
| g_assert_true (g_task_get_completed (task)); |
| @@ -1487,8 +1487,8 @@ test_return_on_cancel (void) |
| { |
| GTask *task; |
| GCancellable *cancellable; |
| - volatile ThreadState thread_state; |
| - volatile gboolean weak_notify_ran = FALSE; |
| + ThreadState thread_state; /* (atomic) */ |
| + gboolean weak_notify_ran = FALSE; /* (atomic) */ |
| gboolean callback_ran; |
| gboolean notification_emitted = FALSE; |
| |
| @@ -1498,7 +1498,7 @@ test_return_on_cancel (void) |
| * early. |
| */ |
| callback_ran = FALSE; |
| - thread_state = THREAD_STARTING; |
| + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); |
| g_signal_connect (task, "notify::completed", |
| (GCallback) completed_cb, ¬ification_emitted); |
| @@ -1509,18 +1509,18 @@ test_return_on_cancel (void) |
| g_task_run_in_thread (task, return_on_cancel_thread); |
| g_object_unref (task); |
| |
| - while (thread_state == THREAD_STARTING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| g_mutex_unlock (&roc_init_mutex); |
| |
| - g_assert (thread_state == THREAD_RUNNING); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| g_assert (callback_ran == FALSE); |
| |
| g_cancellable_cancel (cancellable); |
| g_mutex_unlock (&roc_finish_mutex); |
| g_main_loop_run (loop); |
| |
| - g_assert (thread_state == THREAD_COMPLETED); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED); |
| g_assert (callback_ran == TRUE); |
| g_assert_true (notification_emitted); |
| |
| @@ -1529,7 +1529,7 @@ test_return_on_cancel (void) |
| /* If return-on-cancel is TRUE, it does return early */ |
| callback_ran = FALSE; |
| notification_emitted = FALSE; |
| - thread_state = THREAD_STARTING; |
| + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); |
| g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran); |
| g_signal_connect (task, "notify::completed", |
| @@ -1542,27 +1542,27 @@ test_return_on_cancel (void) |
| g_task_run_in_thread (task, return_on_cancel_thread); |
| g_object_unref (task); |
| |
| - while (thread_state == THREAD_STARTING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| g_mutex_unlock (&roc_init_mutex); |
| |
| - g_assert (thread_state == THREAD_RUNNING); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| g_assert (callback_ran == FALSE); |
| |
| g_cancellable_cancel (cancellable); |
| g_main_loop_run (loop); |
| - g_assert (thread_state == THREAD_RUNNING); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| g_assert (callback_ran == TRUE); |
| |
| - g_assert (weak_notify_ran == FALSE); |
| + g_assert_false (g_atomic_int_get (&weak_notify_ran)); |
| |
| - while (thread_state == THREAD_RUNNING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) |
| g_cond_wait (&roc_finish_cond, &roc_finish_mutex); |
| g_mutex_unlock (&roc_finish_mutex); |
| |
| - g_assert (thread_state == THREAD_CANCELLED); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); |
| g_mutex_lock (&run_in_thread_mutex); |
| - while (!weak_notify_ran) |
| + while (!g_atomic_int_get (&weak_notify_ran)) |
| g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); |
| g_mutex_unlock (&run_in_thread_mutex); |
| |
| @@ -1574,7 +1574,7 @@ test_return_on_cancel (void) |
| */ |
| callback_ran = FALSE; |
| notification_emitted = FALSE; |
| - thread_state = THREAD_STARTING; |
| + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); |
| g_signal_connect (task, "notify::completed", |
| (GCallback) completed_cb, ¬ification_emitted); |
| @@ -1591,17 +1591,17 @@ test_return_on_cancel (void) |
| g_main_loop_run (loop); |
| g_assert (callback_ran == TRUE); |
| |
| - while (thread_state == THREAD_STARTING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| g_mutex_unlock (&roc_init_mutex); |
| |
| - g_assert (thread_state == THREAD_RUNNING); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| |
| - while (thread_state == THREAD_RUNNING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) |
| g_cond_wait (&roc_finish_cond, &roc_finish_mutex); |
| g_mutex_unlock (&roc_finish_mutex); |
| |
| - g_assert (thread_state == THREAD_CANCELLED); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); |
| g_assert_true (notification_emitted); |
| |
| g_object_unref (cancellable); |
| @@ -1621,7 +1621,7 @@ test_return_on_cancel_sync (void) |
| { |
| GTask *task; |
| GCancellable *cancellable; |
| - volatile ThreadState thread_state; |
| + ThreadState thread_state; /* (atomic) */ |
| GThread *runner_thread; |
| gssize ret; |
| GError *error = NULL; |
| @@ -1630,7 +1630,7 @@ test_return_on_cancel_sync (void) |
| |
| /* If return-on-cancel is FALSE, the task does not return early. |
| */ |
| - thread_state = THREAD_STARTING; |
| + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); |
| |
| g_task_set_task_data (task, (gpointer)&thread_state, NULL); |
| @@ -1639,16 +1639,16 @@ test_return_on_cancel_sync (void) |
| runner_thread = g_thread_new ("return-on-cancel-sync runner thread", |
| cancel_sync_runner_thread, task); |
| |
| - while (thread_state == THREAD_STARTING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| g_mutex_unlock (&roc_init_mutex); |
| |
| - g_assert (thread_state == THREAD_RUNNING); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| |
| g_cancellable_cancel (cancellable); |
| g_mutex_unlock (&roc_finish_mutex); |
| g_thread_join (runner_thread); |
| - g_assert (thread_state == THREAD_COMPLETED); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED); |
| |
| ret = g_task_propagate_int (task, &error); |
| g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); |
| @@ -1660,7 +1660,7 @@ test_return_on_cancel_sync (void) |
| g_cancellable_reset (cancellable); |
| |
| /* If return-on-cancel is TRUE, it does return early */ |
| - thread_state = THREAD_STARTING; |
| + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); |
| g_task_set_return_on_cancel (task, TRUE); |
| |
| @@ -1670,15 +1670,15 @@ test_return_on_cancel_sync (void) |
| runner_thread = g_thread_new ("return-on-cancel-sync runner thread", |
| cancel_sync_runner_thread, task); |
| |
| - while (thread_state == THREAD_STARTING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| g_mutex_unlock (&roc_init_mutex); |
| |
| - g_assert (thread_state == THREAD_RUNNING); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| |
| g_cancellable_cancel (cancellable); |
| g_thread_join (runner_thread); |
| - g_assert (thread_state == THREAD_RUNNING); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| |
| ret = g_task_propagate_int (task, &error); |
| g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); |
| @@ -1687,18 +1687,18 @@ test_return_on_cancel_sync (void) |
| |
| g_object_unref (task); |
| |
| - while (thread_state == THREAD_RUNNING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) |
| g_cond_wait (&roc_finish_cond, &roc_finish_mutex); |
| g_mutex_unlock (&roc_finish_mutex); |
| |
| - g_assert (thread_state == THREAD_CANCELLED); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); |
| |
| g_cancellable_reset (cancellable); |
| |
| /* If the task is already cancelled before it starts, it returns |
| * immediately, but the thread func still runs. |
| */ |
| - thread_state = THREAD_STARTING; |
| + g_atomic_int_set (&thread_state, THREAD_STARTING); |
| task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); |
| g_task_set_return_on_cancel (task, TRUE); |
| |
| @@ -1711,7 +1711,7 @@ test_return_on_cancel_sync (void) |
| cancel_sync_runner_thread, task); |
| |
| g_thread_join (runner_thread); |
| - g_assert (thread_state == THREAD_STARTING); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_STARTING); |
| |
| ret = g_task_propagate_int (task, &error); |
| g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); |
| @@ -1720,17 +1720,17 @@ test_return_on_cancel_sync (void) |
| |
| g_object_unref (task); |
| |
| - while (thread_state == THREAD_STARTING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) |
| g_cond_wait (&roc_init_cond, &roc_init_mutex); |
| g_mutex_unlock (&roc_init_mutex); |
| |
| - g_assert (thread_state == THREAD_RUNNING); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); |
| |
| - while (thread_state == THREAD_RUNNING) |
| + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) |
| g_cond_wait (&roc_finish_cond, &roc_finish_mutex); |
| g_mutex_unlock (&roc_finish_mutex); |
| |
| - g_assert (thread_state == THREAD_CANCELLED); |
| + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); |
| |
| g_object_unref (cancellable); |
| } |
| @@ -1776,7 +1776,7 @@ return_on_cancel_atomic_thread (GTask |
| gpointer task_data, |
| GCancellable *cancellable) |
| { |
| - gint *state = task_data; |
| + gint *state = task_data; /* (atomic) */ |
| |
| g_assert (source_object == g_task_get_source_object (task)); |
| g_assert (task_data == g_task_get_task_data (task)); |
| @@ -1784,34 +1784,34 @@ return_on_cancel_atomic_thread (GTask |
| g_assert_false (g_task_get_completed (task)); |
| |
| g_assert (g_thread_self () != main_thread); |
| - g_assert_cmpint (*state, ==, 0); |
| + g_assert_cmpint (g_atomic_int_get (state), ==, 0); |
| |
| g_mutex_lock (&roca_mutex_1); |
| - *state = 1; |
| + g_atomic_int_set (state, 1); |
| g_cond_signal (&roca_cond_1); |
| g_mutex_unlock (&roca_mutex_1); |
| |
| g_mutex_lock (&roca_mutex_2); |
| if (g_task_set_return_on_cancel (task, FALSE)) |
| - *state = 2; |
| + g_atomic_int_set (state, 2); |
| else |
| - *state = 3; |
| + g_atomic_int_set (state, 3); |
| g_cond_signal (&roca_cond_2); |
| g_mutex_unlock (&roca_mutex_2); |
| |
| g_mutex_lock (&roca_mutex_1); |
| if (g_task_set_return_on_cancel (task, TRUE)) |
| - *state = 4; |
| + g_atomic_int_set (state, 4); |
| else |
| - *state = 5; |
| + g_atomic_int_set (state, 5); |
| g_cond_signal (&roca_cond_1); |
| g_mutex_unlock (&roca_mutex_1); |
| |
| g_mutex_lock (&roca_mutex_2); |
| if (g_task_set_return_on_cancel (task, TRUE)) |
| - *state = 6; |
| + g_atomic_int_set (state, 6); |
| else |
| - *state = 7; |
| + g_atomic_int_set (state, 7); |
| g_cond_signal (&roca_cond_2); |
| g_mutex_unlock (&roca_mutex_2); |
| |
| @@ -1823,7 +1823,7 @@ test_return_on_cancel_atomic (void) |
| { |
| GTask *task; |
| GCancellable *cancellable; |
| - volatile gint state; |
| + gint state; /* (atomic) */ |
| gboolean notification_emitted = FALSE; |
| gboolean callback_ran; |
| |
| @@ -1832,7 +1832,7 @@ test_return_on_cancel_atomic (void) |
| g_mutex_lock (&roca_mutex_2); |
| |
| /* If we don't cancel it, each set_return_on_cancel() call will succeed */ |
| - state = 0; |
| + g_atomic_int_set (&state, 0); |
| callback_ran = FALSE; |
| task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran); |
| g_task_set_return_on_cancel (task, TRUE); |
| @@ -1843,23 +1843,23 @@ test_return_on_cancel_atomic (void) |
| g_task_run_in_thread (task, return_on_cancel_atomic_thread); |
| g_object_unref (task); |
| |
| - g_assert_cmpint (state, ==, 0); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 0); |
| |
| - while (state == 0) |
| + while (g_atomic_int_get (&state) == 0) |
| g_cond_wait (&roca_cond_1, &roca_mutex_1); |
| - g_assert (state == 1); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 1); |
| |
| - while (state == 1) |
| + while (g_atomic_int_get (&state) == 1) |
| g_cond_wait (&roca_cond_2, &roca_mutex_2); |
| - g_assert (state == 2); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 2); |
| |
| - while (state == 2) |
| + while (g_atomic_int_get (&state) == 2) |
| g_cond_wait (&roca_cond_1, &roca_mutex_1); |
| - g_assert (state == 4); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 4); |
| |
| - while (state == 4) |
| + while (g_atomic_int_get (&state) == 4) |
| g_cond_wait (&roca_cond_2, &roca_mutex_2); |
| - g_assert (state == 6); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 6); |
| |
| /* callback assumes there'll be a cancelled error */ |
| g_cancellable_cancel (cancellable); |
| @@ -1876,7 +1876,7 @@ test_return_on_cancel_atomic (void) |
| * task won't complete right away, and further |
| * g_task_set_return_on_cancel() calls will return FALSE. |
| */ |
| - state = 0; |
| + g_atomic_int_set (&state, 0); |
| callback_ran = FALSE; |
| notification_emitted = FALSE; |
| task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran); |
| @@ -1887,16 +1887,16 @@ test_return_on_cancel_atomic (void) |
| g_task_set_task_data (task, (gpointer)&state, NULL); |
| g_task_run_in_thread (task, return_on_cancel_atomic_thread); |
| |
| - g_assert_cmpint (state, ==, 0); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 0); |
| |
| - while (state == 0) |
| + while (g_atomic_int_get (&state) == 0) |
| g_cond_wait (&roca_cond_1, &roca_mutex_1); |
| - g_assert (state == 1); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 1); |
| g_assert (g_task_get_return_on_cancel (task)); |
| |
| - while (state == 1) |
| + while (g_atomic_int_get (&state) == 1) |
| g_cond_wait (&roca_cond_2, &roca_mutex_2); |
| - g_assert (state == 2); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 2); |
| g_assert (!g_task_get_return_on_cancel (task)); |
| |
| g_cancellable_cancel (cancellable); |
| @@ -1904,18 +1904,18 @@ test_return_on_cancel_atomic (void) |
| g_main_loop_run (loop); |
| g_assert (callback_ran == FALSE); |
| |
| - while (state == 2) |
| + while (g_atomic_int_get (&state) == 2) |
| g_cond_wait (&roca_cond_1, &roca_mutex_1); |
| - g_assert (state == 5); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 5); |
| g_assert (!g_task_get_return_on_cancel (task)); |
| |
| g_main_loop_run (loop); |
| g_assert (callback_ran == TRUE); |
| g_assert_true (notification_emitted); |
| |
| - while (state == 5) |
| + while (g_atomic_int_get (&state) == 5) |
| g_cond_wait (&roca_cond_2, &roca_mutex_2); |
| - g_assert (state == 7); |
| + g_assert_cmpint (g_atomic_int_get (&state), ==, 7); |
| |
| g_object_unref (cancellable); |
| g_mutex_unlock (&roca_mutex_1); |