mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 19:36:18 +01:00
Merge branch 'wip/ernestask/bz-693576-annotations' into 'master'
Make GTask more binding-friendly See merge request GNOME/glib!1216
This commit is contained in:
commit
eadc17f894
@ -4459,6 +4459,7 @@ g_task_get_name
|
||||
g_task_return_boolean
|
||||
g_task_return_int
|
||||
g_task_return_pointer
|
||||
g_task_return_value
|
||||
g_task_return_error
|
||||
g_task_return_new_error
|
||||
g_task_return_error_if_cancelled
|
||||
@ -4466,6 +4467,7 @@ g_task_return_error_if_cancelled
|
||||
g_task_propagate_boolean
|
||||
g_task_propagate_int
|
||||
g_task_propagate_pointer
|
||||
g_task_propagate_value
|
||||
g_task_had_error
|
||||
g_task_get_completed
|
||||
<SUBSECTION>
|
||||
|
100
gio/gtask.c
100
gio/gtask.c
@ -27,6 +27,8 @@
|
||||
|
||||
#include "glibintl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* SECTION:gtask
|
||||
* @short_description: Cancellable synchronous or asynchronous task
|
||||
@ -1497,7 +1499,7 @@ g_task_start_task_thread (GTask *task,
|
||||
/**
|
||||
* g_task_run_in_thread:
|
||||
* @task: a #GTask
|
||||
* @task_func: a #GTaskThreadFunc
|
||||
* @task_func: (scope async): a #GTaskThreadFunc
|
||||
*
|
||||
* Runs @task_func in another thread. When @task_func returns, @task's
|
||||
* #GAsyncReadyCallback will be invoked in @task's #GMainContext.
|
||||
@ -1540,7 +1542,7 @@ g_task_run_in_thread (GTask *task,
|
||||
/**
|
||||
* g_task_run_in_thread_sync:
|
||||
* @task: a #GTask
|
||||
* @task_func: a #GTaskThreadFunc
|
||||
* @task_func: (scope async): a #GTaskThreadFunc
|
||||
*
|
||||
* Runs @task_func in another thread, and waits for it to return or be
|
||||
* cancelled. You can use g_task_propagate_pointer(), etc, afterward
|
||||
@ -1959,6 +1961,100 @@ g_task_had_error (GTask *task)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
value_free (gpointer value)
|
||||
{
|
||||
g_value_unset (value);
|
||||
g_free (value);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_task_return_value:
|
||||
* @task: a #GTask
|
||||
* @result: (nullable) (transfer none): the #GValue result of
|
||||
* a task function
|
||||
*
|
||||
* Sets @task's result to @result (by copying it) and completes the task.
|
||||
*
|
||||
* If @result is %NULL then a #GValue of type #G_TYPE_POINTER
|
||||
* with a value of %NULL will be used for the result.
|
||||
*
|
||||
* This is a very generic low-level method intended primarily for use
|
||||
* by language bindings; for C code, g_task_return_pointer() and the
|
||||
* like will normally be much easier to use.
|
||||
*
|
||||
* Since: 2.64
|
||||
*/
|
||||
void
|
||||
g_task_return_value (GTask *task,
|
||||
GValue *result)
|
||||
{
|
||||
GValue *value;
|
||||
|
||||
g_return_if_fail (G_IS_TASK (task));
|
||||
g_return_if_fail (!task->ever_returned);
|
||||
|
||||
value = g_new0 (GValue, 1);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
g_value_init (value, G_TYPE_POINTER);
|
||||
g_value_set_pointer (value, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_init (value, G_VALUE_TYPE (result));
|
||||
g_value_copy (result, value);
|
||||
}
|
||||
|
||||
g_task_return_pointer (task, value, value_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_task_propagate_value:
|
||||
* @task: a #GTask
|
||||
* @value: (out) (caller-allocates): return location for the #GValue
|
||||
* @error: return location for a #GError
|
||||
*
|
||||
* Gets the result of @task as a #GValue, and transfers ownership of
|
||||
* that value to the caller. As with g_task_return_value(), this is
|
||||
* a generic low-level method; g_task_propagate_pointer() and the like
|
||||
* will usually be more useful for C code.
|
||||
*
|
||||
* If the task resulted in an error, or was cancelled, then this will
|
||||
* instead set @error and return %FALSE.
|
||||
*
|
||||
* Since this method transfers ownership of the return value (or
|
||||
* error) to the caller, you may only call it once.
|
||||
*
|
||||
* Returns: %TRUE if @task succeeded, %FALSE on error.
|
||||
*
|
||||
* Since: 2.64
|
||||
*/
|
||||
gboolean
|
||||
g_task_propagate_value (GTask *task,
|
||||
GValue *value,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_TASK (task), FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (g_task_propagate_error (task, error))
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (task->result_set, FALSE);
|
||||
g_return_val_if_fail (task->result_destroy == value_free, FALSE);
|
||||
|
||||
memcpy (value, task->result.pointer, sizeof (GValue));
|
||||
g_free (task->result.pointer);
|
||||
|
||||
task->result_destroy = NULL;
|
||||
task->result_set = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_task_get_completed:
|
||||
* @task: a #GTask.
|
||||
|
@ -142,6 +142,9 @@ void g_task_return_new_error (GTask *task,
|
||||
gint code,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF (4, 5);
|
||||
GLIB_AVAILABLE_IN_2_64
|
||||
void g_task_return_value (GTask *task,
|
||||
GValue *result);
|
||||
|
||||
GLIB_AVAILABLE_IN_2_36
|
||||
gboolean g_task_return_error_if_cancelled (GTask *task);
|
||||
@ -155,6 +158,10 @@ gboolean g_task_propagate_boolean (GTask *task,
|
||||
GLIB_AVAILABLE_IN_2_36
|
||||
gssize g_task_propagate_int (GTask *task,
|
||||
GError **error);
|
||||
GLIB_AVAILABLE_IN_2_64
|
||||
gboolean g_task_propagate_value (GTask *task,
|
||||
GValue *value,
|
||||
GError **error);
|
||||
GLIB_AVAILABLE_IN_2_36
|
||||
gboolean g_task_had_error (GTask *task);
|
||||
GLIB_AVAILABLE_IN_2_44
|
||||
|
@ -2009,6 +2009,47 @@ test_return_pointer (void)
|
||||
g_assert_null (task);
|
||||
}
|
||||
|
||||
static void
|
||||
test_return_value (void)
|
||||
{
|
||||
GObject *object;
|
||||
GValue value = G_VALUE_INIT;
|
||||
GValue ret = G_VALUE_INIT;
|
||||
GTask *task;
|
||||
GError *error = NULL;
|
||||
|
||||
object = (GObject *)g_dummy_object_new ();
|
||||
g_assert_cmpint (object->ref_count, ==, 1);
|
||||
g_object_add_weak_pointer (object, (gpointer *)&object);
|
||||
|
||||
g_value_init (&value, G_TYPE_OBJECT);
|
||||
g_value_set_object (&value, object);
|
||||
g_assert_cmpint (object->ref_count, ==, 2);
|
||||
|
||||
task = g_task_new (NULL, NULL, NULL, NULL);
|
||||
g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
|
||||
g_task_return_value (task, &value);
|
||||
g_assert_cmpint (object->ref_count, ==, 3);
|
||||
|
||||
g_assert_true (g_task_propagate_value (task, &ret, &error));
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (g_value_get_object (&ret) == object);
|
||||
g_assert_cmpint (object->ref_count, ==, 3);
|
||||
|
||||
g_object_unref (task);
|
||||
g_assert_nonnull (task);
|
||||
wait_for_completed_notification (task);
|
||||
g_assert_null (task);
|
||||
|
||||
g_assert_cmpint (object->ref_count, ==, 3);
|
||||
g_value_unset (&ret);
|
||||
g_assert_cmpint (object->ref_count, ==, 2);
|
||||
g_value_unset (&value);
|
||||
g_assert_cmpint (object->ref_count, ==, 1);
|
||||
g_object_unref (object);
|
||||
g_assert_null (object);
|
||||
}
|
||||
|
||||
/* test_object_keepalive: GTask takes a ref on its source object */
|
||||
|
||||
static GObject *keepalive_object;
|
||||
@ -2348,6 +2389,7 @@ main (int argc, char **argv)
|
||||
g_test_add_func ("/gtask/return-on-cancel-sync", test_return_on_cancel_sync);
|
||||
g_test_add_func ("/gtask/return-on-cancel-atomic", test_return_on_cancel_atomic);
|
||||
g_test_add_func ("/gtask/return-pointer", test_return_pointer);
|
||||
g_test_add_func ("/gtask/return-value", test_return_value);
|
||||
g_test_add_func ("/gtask/object-keepalive", test_object_keepalive);
|
||||
g_test_add_func ("/gtask/legacy-error", test_legacy_error);
|
||||
g_test_add_func ("/gtask/return/in-idle/error-first", test_return_in_idle_error_first);
|
||||
|
Loading…
Reference in New Issue
Block a user