diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml
index f1ad8a350..03dd28deb 100644
--- a/docs/reference/gio/gio-docs.xml
+++ b/docs/reference/gio/gio-docs.xml
@@ -40,9 +40,9 @@
Asynchronous I/O
+
-
Data conversion
diff --git a/gio/gasyncinitable.c b/gio/gasyncinitable.c
index d5712a517..2508b9c03 100644
--- a/gio/gasyncinitable.c
+++ b/gio/gasyncinitable.c
@@ -64,13 +64,13 @@
*
* for (l = self->priv->init_results; l != NULL; l = l->next)
* {
- * GSimpleAsyncResult *simple = l->data;
+ * GTask *task = l->data;
*
- * if (!self->priv->success)
- * g_simple_async_result_set_error (simple, ...);
- *
- * g_simple_async_result_complete (simple);
- * g_object_unref (simple);
+ * if (self->priv->success)
+ * g_task_return_boolean (task, TRUE);
+ * else
+ * g_task_return_new_error (task, ...);
+ * g_object_unref (task);
* }
*
* g_list_free (self->priv->init_results);
@@ -85,31 +85,28 @@
* gpointer user_data)
* {
* Foo *self = FOO (initable);
- * GSimpleAsyncResult *simple;
+ * GTask *task;
*
- * simple = g_simple_async_result_new (G_OBJECT (initable)
- * callback,
- * user_data,
- * foo_init_async);
+ * task = g_task_new (initable, cancellable, callback, user_data);
*
* switch (self->priv->state)
* {
* case NOT_INITIALIZED:
* _foo_get_ready (self);
* self->priv->init_results = g_list_append (self->priv->init_results,
- * simple);
+ * task);
* self->priv->state = INITIALIZING;
* break;
* case INITIALIZING:
* self->priv->init_results = g_list_append (self->priv->init_results,
- * simple);
+ * task);
* break;
* case INITIALIZED:
* if (!self->priv->success)
- * g_simple_async_result_set_error (simple, ...);
- *
- * g_simple_async_result_complete_in_idle (simple);
- * g_object_unref (simple);
+ * g_task_return_new_error (task, ...);
+ * else
+ * g_task_return_boolean (task, TRUE);
+ * g_object_unref (task);
* break;
* }
* }
@@ -119,14 +116,9 @@
* GAsyncResult *result,
* GError **error)
* {
- * g_return_val_if_fail (g_simple_async_result_is_valid (result,
- * G_OBJECT (initable), foo_init_async), FALSE);
+ * g_return_val_if_fail (g_task_is_valid (result, initable), FALSE);
*
- * if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
- * error))
- * return FALSE;
- *
- * return TRUE;
+ * return g_task_propagate_boolean (G_TASK (result), error);
* }
*
* static void
diff --git a/gio/gasyncresult.c b/gio/gasyncresult.c
index f4dbf32e8..c86b3dc59 100644
--- a/gio/gasyncresult.c
+++ b/gio/gasyncresult.c
@@ -30,7 +30,7 @@
* SECTION:gasyncresult
* @short_description: Asynchronous Function Results
* @include: gio/gio.h
- * @see_also: #GSimpleAsyncResult
+ * @see_also: #GTask
*
* Provides a base class for implementing asynchronous function results.
*
@@ -103,6 +103,16 @@
* The callback for an asynchronous operation is called only once, and is
* always called, even in the case of a cancelled operation. On cancellation
* the result is a %G_IO_ERROR_CANCELLED error.
+ *
+ * I/O
+ * priority Many I/O-related asynchronous
+ * operations have a priority parameter, which is used in certain
+ * cases to determine the order in which operations are executed. They
+ * are not used to determine system-wide I/O
+ * scheduling. Priorities are integers, with lower numbers indicating
+ * higher priority. It is recommended to choose priorities between
+ * %G_PRIORITY_LOW and %G_PRIORITY_HIGH, with %G_PRIORITY_DEFAULT as a
+ * default.
**/
typedef GAsyncResultIface GAsyncResultInterface;
diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c
index e425f3fd9..5eb63d982 100644
--- a/gio/gdbusinterfaceskeleton.c
+++ b/gio/gdbusinterfaceskeleton.c
@@ -29,7 +29,7 @@
#include "gdbusprivate.h"
#include "gdbusmethodinvocation.h"
#include "gdbusconnection.h"
-#include "gioscheduler.h"
+#include "gtask.h"
#include "gioerror.h"
#include "glibintl.h"
@@ -459,17 +459,13 @@ typedef struct
GDBusInterfaceSkeleton *interface;
GDBusInterfaceMethodCallFunc method_call_func;
GDBusMethodInvocation *invocation;
- GMainContext *context;
} DispatchData;
static void
dispatch_data_unref (DispatchData *data)
{
if (g_atomic_int_dec_and_test (&data->ref_count))
- {
- g_main_context_unref (data->context);
- g_free (data);
- }
+ g_slice_free (DispatchData, data);
}
static DispatchData *
@@ -494,12 +490,13 @@ dispatch_invoke_in_context_func (gpointer user_data)
return FALSE;
}
-static gboolean
-dispatch_in_thread_func (GIOSchedulerJob *job,
- GCancellable *cancellable,
- gpointer user_data)
+static void
+dispatch_in_thread_func (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
- DispatchData *data = user_data;
+ DispatchData *data = task_data;
GDBusInterfaceSkeletonFlags flags;
GDBusObject *object;
gboolean authorized;
@@ -549,8 +546,8 @@ dispatch_in_thread_func (GIOSchedulerJob *job,
else
{
/* bah, back to original context */
- g_main_context_invoke_full (data->context,
- G_PRIORITY_DEFAULT,
+ g_main_context_invoke_full (g_task_get_context (task),
+ g_task_get_priority (task),
dispatch_invoke_in_context_func,
dispatch_data_ref (data),
(GDestroyNotify) dispatch_data_unref);
@@ -563,8 +560,6 @@ dispatch_in_thread_func (GIOSchedulerJob *job,
if (object != NULL)
g_object_unref (object);
-
- return FALSE;
}
static void
@@ -623,18 +618,19 @@ g_dbus_interface_method_dispatch_helper (GDBusInterfaceSkeleton *interface
}
else
{
+ GTask *task;
DispatchData *data;
- data = g_new0 (DispatchData, 1);
+
+ data = g_slice_new0 (DispatchData);
data->interface = interface;
data->method_call_func = method_call_func;
data->invocation = invocation;
- data->context = g_main_context_ref_thread_default ();
data->ref_count = 1;
- g_io_scheduler_push_job (dispatch_in_thread_func,
- data,
- (GDestroyNotify) dispatch_data_unref,
- G_PRIORITY_DEFAULT,
- NULL); /* GCancellable* */
+
+ task = g_task_new (interface, NULL, NULL, NULL);
+ g_task_set_task_data (task, data, (GDestroyNotify) dispatch_data_unref);
+ g_task_run_in_thread (task, dispatch_in_thread_func);
+ g_object_unref (task);
}
if (object != NULL)
diff --git a/gio/gfile.c b/gio/gfile.c
index 56fcf3ba7..18be0965c 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -5947,7 +5947,6 @@ typedef struct {
GFileCopyFlags flags;
GFileProgressCallback progress_cb;
gpointer progress_cb_data;
- GIOSchedulerJob *job;
} CopyAsyncData;
static void
@@ -5955,7 +5954,7 @@ copy_async_data_free (CopyAsyncData *data)
{
g_object_unref (data->source);
g_object_unref (data->destination);
- g_free (data);
+ g_slice_free (CopyAsyncData, data);
}
typedef struct {
@@ -5982,7 +5981,8 @@ copy_async_progress_callback (goffset current_num_bytes,
goffset total_num_bytes,
gpointer user_data)
{
- CopyAsyncData *data = user_data;
+ GTask *task = user_data;
+ CopyAsyncData *data = g_task_get_task_data (task);
ProgressData *progress;
progress = g_new (ProgressData, 1);
@@ -5990,41 +5990,34 @@ copy_async_progress_callback (goffset current_num_bytes,
progress->current_num_bytes = current_num_bytes;
progress->total_num_bytes = total_num_bytes;
- g_io_scheduler_job_send_to_mainloop_async (data->job,
- copy_async_progress_in_main,
- progress,
- g_free);
+ g_main_context_invoke_full (g_task_get_context (task),
+ g_task_get_priority (task),
+ copy_async_progress_in_main,
+ progress,
+ g_free);
}
-static gboolean
-copy_async_thread (GIOSchedulerJob *job,
- GCancellable *cancellable,
- gpointer user_data)
+static void
+copy_async_thread (GTask *task,
+ gpointer source,
+ gpointer task_data,
+ GCancellable *cancellable)
{
- GSimpleAsyncResult *res;
- CopyAsyncData *data;
+ CopyAsyncData *data = task_data;
gboolean result;
- GError *error;
+ GError *error = NULL;
- res = user_data;
- data = g_simple_async_result_get_op_res_gpointer (res);
-
- error = NULL;
- data->job = job;
result = g_file_copy (data->source,
data->destination,
data->flags,
cancellable,
(data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
- data,
+ task,
&error);
-
- if (!result)
- g_simple_async_result_take_error (res, error);
-
- g_simple_async_result_complete_in_idle (res);
-
- return FALSE;
+ if (result)
+ g_task_return_boolean (task, TRUE);
+ else
+ g_task_return_error (task, error);
}
static void
@@ -6038,20 +6031,21 @@ g_file_real_copy_async (GFile *source,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *res;
+ GTask *task;
CopyAsyncData *data;
- data = g_new0 (CopyAsyncData, 1);
+ data = g_slice_new (CopyAsyncData);
data->source = g_object_ref (source);
data->destination = g_object_ref (destination);
data->flags = flags;
data->progress_cb = progress_callback;
data->progress_cb_data = progress_callback_data;
- res = g_simple_async_result_new (G_OBJECT (source), callback, user_data, g_file_real_copy_async);
- g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)copy_async_data_free);
-
- g_io_scheduler_push_job (copy_async_thread, res, g_object_unref, io_priority, cancellable);
+ task = g_task_new (source, cancellable, callback, user_data);
+ g_task_set_task_data (task, data, (GDestroyNotify)copy_async_data_free);
+ g_task_set_priority (task, io_priority);
+ g_task_run_in_thread (task, copy_async_thread);
+ g_object_unref (task);
}
static gboolean
@@ -6059,12 +6053,7 @@ g_file_real_copy_finish (GFile *file,
GAsyncResult *res,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
-
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (res), error);
}
diff --git a/gio/gfileenumerator.c b/gio/gfileenumerator.c
index a6db242fa..d8f622b39 100644
--- a/gio/gfileenumerator.c
+++ b/gio/gfileenumerator.c
@@ -303,7 +303,7 @@ next_async_callback_wrapper (GObject *source_object,
* g_file_enumerator_next_files_async:
* @enumerator: a #GFileEnumerator.
* @num_files: the number of file info objects to request
- * @io_priority: the io priority
+ * @io_priority: the io priority
* of the request.
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
* @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
diff --git a/gio/gioscheduler.c b/gio/gioscheduler.c
index f63996e8d..182931de8 100644
--- a/gio/gioscheduler.c
+++ b/gio/gioscheduler.c
@@ -24,34 +24,30 @@
#include "gioscheduler.h"
#include "gcancellable.h"
-
+#include "gtask.h"
/**
* SECTION:gioscheduler
* @short_description: I/O Scheduler
* @include: gio/gio.h
*
+ *
+ * As of GLib 2.36, the g_io_scheduler methods
+ * are deprecated in favor of #GThreadPool and #GTask.
+ *
+ *
* Schedules asynchronous I/O operations. #GIOScheduler integrates
* into the main event loop (#GMainLoop) and uses threads.
- *
- * I/O priority
- * Each I/O operation has a priority, and the scheduler uses the priorities
- * to determine the order in which operations are executed. They are
- * not used to determine system-wide I/O scheduling.
- * Priorities are integers, with lower numbers indicating higher priority.
- * It is recommended to choose priorities between %G_PRIORITY_LOW and
- * %G_PRIORITY_HIGH, with %G_PRIORITY_DEFAULT as a default.
- *
**/
struct _GIOSchedulerJob {
GList *active_link;
+ GTask *task;
+
GIOSchedulerJobFunc job_func;
- GSourceFunc cancel_func; /* Runs under job map lock */
gpointer data;
GDestroyNotify destroy_notify;
- gint io_priority;
GCancellable *cancellable;
gulong cancellable_id;
GMainContext *context;
@@ -60,98 +56,29 @@ struct _GIOSchedulerJob {
G_LOCK_DEFINE_STATIC(active_jobs);
static GList *active_jobs = NULL;
-static GThreadPool *job_thread_pool = NULL;
-
-static void io_job_thread (gpointer data,
- gpointer user_data);
-
static void
g_io_job_free (GIOSchedulerJob *job)
{
- if (job->cancellable)
- {
- if (job->cancellable_id)
- g_cancellable_disconnect (job->cancellable, job->cancellable_id);
- g_object_unref (job->cancellable);
- }
- g_main_context_unref (job->context);
- g_free (job);
-}
-
-static gint
-g_io_job_compare (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
-{
- const GIOSchedulerJob *aa = a;
- const GIOSchedulerJob *bb = b;
-
- /* Cancelled jobs are set prio == -1, so that
- they are executed as quickly as possible */
-
- /* Lower value => higher priority */
- if (aa->io_priority < bb->io_priority)
- return -1;
- if (aa->io_priority == bb->io_priority)
- return 0;
- return 1;
-}
-
-static gpointer
-init_scheduler (gpointer arg)
-{
- if (job_thread_pool == NULL)
- {
- /* TODO: thread_pool_new can fail */
- job_thread_pool = g_thread_pool_new (io_job_thread,
- NULL,
- 10,
- FALSE,
- NULL);
- if (job_thread_pool != NULL)
- {
- g_thread_pool_set_sort_function (job_thread_pool,
- g_io_job_compare,
- NULL);
- }
- }
- return NULL;
-}
-
-static void
-on_job_canceled (GCancellable *cancellable,
- gpointer user_data)
-{
- GIOSchedulerJob *job = user_data;
-
- /* This might be called more than once */
- job->io_priority = -1;
-
- if (job_thread_pool != NULL)
- g_thread_pool_set_sort_function (job_thread_pool,
- g_io_job_compare,
- NULL);
-}
-
-static void
-job_destroy (gpointer data)
-{
- GIOSchedulerJob *job = data;
-
if (job->destroy_notify)
job->destroy_notify (job->data);
G_LOCK (active_jobs);
active_jobs = g_list_delete_link (active_jobs, job->active_link);
G_UNLOCK (active_jobs);
- g_io_job_free (job);
+
+ if (job->cancellable)
+ g_object_unref (job->cancellable);
+ g_main_context_unref (job->context);
+ g_slice_free (GIOSchedulerJob, job);
}
static void
-io_job_thread (gpointer data,
- gpointer user_data)
+io_job_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
- GIOSchedulerJob *job = data;
+ GIOSchedulerJob *job = task_data;
gboolean result;
if (job->cancellable)
@@ -165,8 +92,6 @@ io_job_thread (gpointer data,
if (job->cancellable)
g_cancellable_pop_current (job->cancellable);
-
- job_destroy (job);
}
/**
@@ -174,7 +99,7 @@ io_job_thread (gpointer data,
* @job_func: a #GIOSchedulerJobFunc.
* @user_data: data to pass to @job_func
* @notify: (allow-none): a #GDestroyNotify for @user_data, or %NULL
- * @io_priority: the I/O priority
+ * @io_priority: the I/O priority
* of the request.
* @cancellable: optional #GCancellable object, %NULL to ignore.
*
@@ -186,6 +111,8 @@ io_job_thread (gpointer data,
* If @cancellable is not %NULL, it can be used to cancel the I/O job
* by calling g_cancellable_cancel() or by calling
* g_io_scheduler_cancel_all_jobs().
+ *
+ * Deprecated: use #GThreadPool or g_task_run_in_thread()
**/
void
g_io_scheduler_push_job (GIOSchedulerJobFunc job_func,
@@ -194,23 +121,18 @@ g_io_scheduler_push_job (GIOSchedulerJobFunc job_func,
gint io_priority,
GCancellable *cancellable)
{
- static GOnce once_init = G_ONCE_INIT;
GIOSchedulerJob *job;
+ GTask *task;
g_return_if_fail (job_func != NULL);
- job = g_new0 (GIOSchedulerJob, 1);
+ job = g_slice_new0 (GIOSchedulerJob);
job->job_func = job_func;
job->data = user_data;
job->destroy_notify = notify;
- job->io_priority = io_priority;
-
+
if (cancellable)
- {
- job->cancellable = g_object_ref (cancellable);
- job->cancellable_id = g_cancellable_connect (job->cancellable, (GCallback)on_job_canceled,
- job, NULL);
- }
+ job->cancellable = g_object_ref (cancellable);
job->context = g_main_context_ref_thread_default ();
@@ -219,8 +141,11 @@ g_io_scheduler_push_job (GIOSchedulerJobFunc job_func,
job->active_link = active_jobs;
G_UNLOCK (active_jobs);
- g_once (&once_init, init_scheduler, NULL);
- g_thread_pool_push (job_thread_pool, job, NULL);
+ task = g_task_new (NULL, cancellable, NULL, NULL);
+ g_task_set_task_data (task, job, (GDestroyNotify)g_io_job_free);
+ g_task_set_priority (task, io_priority);
+ g_task_run_in_thread (task, io_job_thread);
+ g_object_unref (task);
}
/**
@@ -230,6 +155,10 @@ g_io_scheduler_push_job (GIOSchedulerJobFunc job_func,
*
* A job is cancellable if a #GCancellable was passed into
* g_io_scheduler_push_job().
+ *
+ * Deprecated: You should never call this function, since you don't
+ * know how other libraries in your program might be making use of
+ * gioscheduler.
**/
void
g_io_scheduler_cancel_all_jobs (void)
@@ -305,6 +234,8 @@ mainloop_proxy_free (MainLoopProxy *proxy)
* blocking the I/O job).
*
* Returns: The return value of @func
+ *
+ * Deprecated: Use g_main_context_invoke().
**/
gboolean
g_io_scheduler_job_send_to_mainloop (GIOSchedulerJob *job,
@@ -361,6 +292,8 @@ g_io_scheduler_job_send_to_mainloop (GIOSchedulerJob *job,
* on to this function you have to ensure that it is not freed before
* @func is called, either by passing %NULL as @notify to
* g_io_scheduler_push_job() or by using refcounting for @user_data.
+ *
+ * Deprecated: Use g_main_context_invoke().
**/
void
g_io_scheduler_job_send_to_mainloop_async (GIOSchedulerJob *job,
diff --git a/gio/gioscheduler.h b/gio/gioscheduler.h
index 7d6b52738..431f06eb2 100644
--- a/gio/gioscheduler.h
+++ b/gio/gioscheduler.h
@@ -32,16 +32,20 @@
G_BEGIN_DECLS
+GLIB_DEPRECATED_IN_2_36_FOR ("GThreadPool or g_task_run_in_thread")
void g_io_scheduler_push_job (GIOSchedulerJobFunc job_func,
gpointer user_data,
GDestroyNotify notify,
gint io_priority,
GCancellable *cancellable);
+GLIB_DEPRECATED_IN_2_36
void g_io_scheduler_cancel_all_jobs (void);
+GLIB_DEPRECATED_IN_2_36_FOR (g_main_context_invoke)
gboolean g_io_scheduler_job_send_to_mainloop (GIOSchedulerJob *job,
GSourceFunc func,
gpointer user_data,
GDestroyNotify notify);
+GLIB_DEPRECATED_IN_2_36_FOR (g_main_context_invoke)
void g_io_scheduler_job_send_to_mainloop_async (GIOSchedulerJob *job,
GSourceFunc func,
gpointer user_data,
diff --git a/gio/gsimpleasyncresult.c b/gio/gsimpleasyncresult.c
index cd56b2a2c..c5d8103d5 100644
--- a/gio/gsimpleasyncresult.c
+++ b/gio/gsimpleasyncresult.c
@@ -45,10 +45,12 @@
* @include: gio/gio.h
* @see_also: #GAsyncResult
*
- * Implements #GAsyncResult for simple cases. Most of the time, this
- * will be all an application needs, and will be used transparently.
- * Because of this, #GSimpleAsyncResult is used throughout GIO for
- * handling asynchronous functions.
+ *
+ * As of GLib 2.36, #GSimpleAsyncResult is deprecated in favor of
+ * #GTask, which provides a simpler API.
+ *
+ *
+ * #GSimpleAsyncResult implements #GAsyncResult.
*
* GSimpleAsyncResult handles #GAsyncReadyCallbacks, error
* reporting, operation cancellation and the final state of an operation,
@@ -911,7 +913,9 @@ g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple,
data->cancellable = cancellable;
if (cancellable)
g_object_ref (cancellable);
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
+ G_GNUC_END_IGNORE_DEPRECATIONS;
}
/**