mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 15:36:14 +01:00
Merge branch 'wip/rishi/gtask-return-cancellation-test' into 'master'
gio/tests/task: Run the worker indefinitely until it's cancelled See merge request GNOME/glib!648
This commit is contained in:
commit
6199d8ba9f
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012 Red Hat, Inc.
|
* Copyright 2012-2019 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -657,14 +657,21 @@ name_callback (GObject *object,
|
|||||||
/* test_asynchronous_cancellation: cancelled tasks are returned
|
/* test_asynchronous_cancellation: cancelled tasks are returned
|
||||||
* asynchronously, i.e. not from inside the GCancellable::cancelled
|
* asynchronously, i.e. not from inside the GCancellable::cancelled
|
||||||
* handler.
|
* handler.
|
||||||
|
*
|
||||||
|
* The test is set up further below in test_asynchronous_cancellation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* asynchronous_cancellation_callback represents the callback that the
|
||||||
|
* caller of a typical asynchronous API would have passed. See
|
||||||
|
* test_asynchronous_cancellation.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
asynchronous_cancellation_callback (GObject *object,
|
asynchronous_cancellation_callback (GObject *object,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
guint run_task_id;
|
||||||
|
|
||||||
g_assert_null (object);
|
g_assert_null (object);
|
||||||
g_assert_true (g_task_is_valid (result, object));
|
g_assert_true (g_task_is_valid (result, object));
|
||||||
@ -672,6 +679,9 @@ asynchronous_cancellation_callback (GObject *object,
|
|||||||
g_assert_true (g_task_had_error (G_TASK (result)));
|
g_assert_true (g_task_had_error (G_TASK (result)));
|
||||||
g_assert_false (g_task_get_completed (G_TASK (result)));
|
g_assert_false (g_task_get_completed (G_TASK (result)));
|
||||||
|
|
||||||
|
run_task_id = GPOINTER_TO_UINT (g_task_get_task_data (G_TASK (result)));
|
||||||
|
g_assert_cmpuint (run_task_id, ==, 0);
|
||||||
|
|
||||||
g_task_propagate_boolean (G_TASK (result), &error);
|
g_task_propagate_boolean (G_TASK (result), &error);
|
||||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
@ -681,6 +691,10 @@ asynchronous_cancellation_callback (GObject *object,
|
|||||||
g_main_loop_quit (loop);
|
g_main_loop_quit (loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* asynchronous_cancellation_cancel_task represents a user cancelling
|
||||||
|
* the ongoing operation. To make it somewhat realistic it is delayed
|
||||||
|
* by 50ms via a timeout GSource. See test_asynchronous_cancellation.
|
||||||
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
asynchronous_cancellation_cancel_task (gpointer user_data)
|
asynchronous_cancellation_cancel_task (gpointer user_data)
|
||||||
{
|
{
|
||||||
@ -696,6 +710,10 @@ asynchronous_cancellation_cancel_task (gpointer user_data)
|
|||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* asynchronous_cancellation_cancelled is the GCancellable::cancelled
|
||||||
|
* handler that's used by the asynchronous implementation for
|
||||||
|
* cancelling itself.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
asynchronous_cancellation_cancelled (GCancellable *cancellable,
|
asynchronous_cancellation_cancelled (GCancellable *cancellable,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
@ -706,13 +724,20 @@ asynchronous_cancellation_cancelled (GCancellable *cancellable,
|
|||||||
g_assert_true (cancellable == g_task_get_cancellable (task));
|
g_assert_true (cancellable == g_task_get_cancellable (task));
|
||||||
|
|
||||||
run_task_id = GPOINTER_TO_UINT (g_task_get_task_data (task));
|
run_task_id = GPOINTER_TO_UINT (g_task_get_task_data (task));
|
||||||
if (run_task_id != 0)
|
g_assert_cmpuint (run_task_id, !=, 0);
|
||||||
g_source_remove (run_task_id);
|
|
||||||
|
g_source_remove (run_task_id);
|
||||||
|
g_task_set_task_data (task, GUINT_TO_POINTER (0), NULL);
|
||||||
|
|
||||||
g_task_return_boolean (task, FALSE);
|
g_task_return_boolean (task, FALSE);
|
||||||
g_assert_false (g_task_get_completed (task));
|
g_assert_false (g_task_get_completed (task));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* asynchronous_cancellation_run_task represents the actual
|
||||||
|
* asynchronous work being done in an idle GSource as was mentioned
|
||||||
|
* above. This is effectively meant to be an infinite loop so that
|
||||||
|
* the only way to break out of it is via cancellation.
|
||||||
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
asynchronous_cancellation_run_task (gpointer user_data)
|
asynchronous_cancellation_run_task (gpointer user_data)
|
||||||
{
|
{
|
||||||
@ -723,12 +748,18 @@ asynchronous_cancellation_run_task (gpointer user_data)
|
|||||||
g_assert_true (G_IS_CANCELLABLE (cancellable));
|
g_assert_true (G_IS_CANCELLABLE (cancellable));
|
||||||
g_assert_false (g_cancellable_is_cancelled (cancellable));
|
g_assert_false (g_cancellable_is_cancelled (cancellable));
|
||||||
|
|
||||||
g_task_set_task_data (task, GUINT_TO_POINTER (0), NULL);
|
return G_SOURCE_CONTINUE;
|
||||||
return G_SOURCE_REMOVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test that cancellation is always asynchronous. The completion callback for
|
/* Test that cancellation is always asynchronous. The completion callback for
|
||||||
* a #GTask must not be called from inside the cancellation handler. */
|
* a #GTask must not be called from inside the cancellation handler.
|
||||||
|
*
|
||||||
|
* The body of the loop inside test_asynchronous_cancellation
|
||||||
|
* represents what would have been a typical asynchronous API call,
|
||||||
|
* and its implementation. They are fused together without an API
|
||||||
|
* boundary. The actual work done by this asynchronous API is
|
||||||
|
* represented by an idle GSource.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
test_asynchronous_cancellation (void)
|
test_asynchronous_cancellation (void)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user