mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 23:16:14 +01:00
gio: deprecate gioscheduler, soft deprecate GSimpleAsyncResult
Reimplement gioscheduler in terms of GTask, and deprecate the original gioscheduler methods. Update docs to point people to GTask rather than gioscheduler and GSimpleAsyncResult, but don't actually formally deprecate GSimpleAsyncResult yet. https://bugzilla.gnome.org/show_bug.cgi?id=661767
This commit is contained in:
parent
b20eec3294
commit
55e7ca6e1b
@ -40,9 +40,9 @@
|
|||||||
<title>Asynchronous I/O</title>
|
<title>Asynchronous I/O</title>
|
||||||
<xi:include href="xml/gcancellable.xml"/>
|
<xi:include href="xml/gcancellable.xml"/>
|
||||||
<xi:include href="xml/gasyncresult.xml"/>
|
<xi:include href="xml/gasyncresult.xml"/>
|
||||||
|
<xi:include href="xml/gtask.xml"/>
|
||||||
<xi:include href="xml/gioscheduler.xml"/>
|
<xi:include href="xml/gioscheduler.xml"/>
|
||||||
<xi:include href="xml/gsimpleasyncresult.xml"/>
|
<xi:include href="xml/gsimpleasyncresult.xml"/>
|
||||||
<xi:include href="xml/gtask.xml"/>
|
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="conversion">
|
<chapter id="conversion">
|
||||||
<title>Data conversion</title>
|
<title>Data conversion</title>
|
||||||
|
@ -64,13 +64,13 @@
|
|||||||
*
|
*
|
||||||
* for (l = self->priv->init_results; l != NULL; l = l->next)
|
* for (l = self->priv->init_results; l != NULL; l = l->next)
|
||||||
* {
|
* {
|
||||||
* GSimpleAsyncResult *simple = l->data;
|
* GTask *task = l->data;
|
||||||
*
|
*
|
||||||
* if (!self->priv->success)
|
* if (self->priv->success)
|
||||||
* g_simple_async_result_set_error (simple, ...);
|
* g_task_return_boolean (task, TRUE);
|
||||||
*
|
* else
|
||||||
* g_simple_async_result_complete (simple);
|
* g_task_return_new_error (task, ...);
|
||||||
* g_object_unref (simple);
|
* g_object_unref (task);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* g_list_free (self->priv->init_results);
|
* g_list_free (self->priv->init_results);
|
||||||
@ -85,31 +85,28 @@
|
|||||||
* gpointer user_data)
|
* gpointer user_data)
|
||||||
* {
|
* {
|
||||||
* Foo *self = FOO (initable);
|
* Foo *self = FOO (initable);
|
||||||
* GSimpleAsyncResult *simple;
|
* GTask *task;
|
||||||
*
|
*
|
||||||
* simple = g_simple_async_result_new (G_OBJECT (initable)
|
* task = g_task_new (initable, cancellable, callback, user_data);
|
||||||
* callback,
|
|
||||||
* user_data,
|
|
||||||
* foo_init_async);
|
|
||||||
*
|
*
|
||||||
* switch (self->priv->state)
|
* switch (self->priv->state)
|
||||||
* {
|
* {
|
||||||
* case NOT_INITIALIZED:
|
* case NOT_INITIALIZED:
|
||||||
* _foo_get_ready (self);
|
* _foo_get_ready (self);
|
||||||
* self->priv->init_results = g_list_append (self->priv->init_results,
|
* self->priv->init_results = g_list_append (self->priv->init_results,
|
||||||
* simple);
|
* task);
|
||||||
* self->priv->state = INITIALIZING;
|
* self->priv->state = INITIALIZING;
|
||||||
* break;
|
* break;
|
||||||
* case INITIALIZING:
|
* case INITIALIZING:
|
||||||
* self->priv->init_results = g_list_append (self->priv->init_results,
|
* self->priv->init_results = g_list_append (self->priv->init_results,
|
||||||
* simple);
|
* task);
|
||||||
* break;
|
* break;
|
||||||
* case INITIALIZED:
|
* case INITIALIZED:
|
||||||
* if (!self->priv->success)
|
* if (!self->priv->success)
|
||||||
* g_simple_async_result_set_error (simple, ...);
|
* g_task_return_new_error (task, ...);
|
||||||
*
|
* else
|
||||||
* g_simple_async_result_complete_in_idle (simple);
|
* g_task_return_boolean (task, TRUE);
|
||||||
* g_object_unref (simple);
|
* g_object_unref (task);
|
||||||
* break;
|
* break;
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
@ -119,14 +116,9 @@
|
|||||||
* GAsyncResult *result,
|
* GAsyncResult *result,
|
||||||
* GError **error)
|
* GError **error)
|
||||||
* {
|
* {
|
||||||
* g_return_val_if_fail (g_simple_async_result_is_valid (result,
|
* g_return_val_if_fail (g_task_is_valid (result, initable), FALSE);
|
||||||
* G_OBJECT (initable), foo_init_async), FALSE);
|
|
||||||
*
|
*
|
||||||
* if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
|
* return g_task_propagate_boolean (G_TASK (result), error);
|
||||||
* error))
|
|
||||||
* return FALSE;
|
|
||||||
*
|
|
||||||
* return TRUE;
|
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* static void
|
* static void
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
* SECTION:gasyncresult
|
* SECTION:gasyncresult
|
||||||
* @short_description: Asynchronous Function Results
|
* @short_description: Asynchronous Function Results
|
||||||
* @include: gio/gio.h
|
* @include: gio/gio.h
|
||||||
* @see_also: #GSimpleAsyncResult
|
* @see_also: #GTask
|
||||||
*
|
*
|
||||||
* Provides a base class for implementing asynchronous function results.
|
* 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
|
* The callback for an asynchronous operation is called only once, and is
|
||||||
* always called, even in the case of a cancelled operation. On cancellation
|
* always called, even in the case of a cancelled operation. On cancellation
|
||||||
* the result is a %G_IO_ERROR_CANCELLED error.
|
* the result is a %G_IO_ERROR_CANCELLED error.
|
||||||
|
*
|
||||||
|
* <para id="io-priority"><indexterm><primary>I/O
|
||||||
|
* priority</primary></indexterm> 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 <emphasis>not</emphasis> 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. </para>
|
||||||
**/
|
**/
|
||||||
|
|
||||||
typedef GAsyncResultIface GAsyncResultInterface;
|
typedef GAsyncResultIface GAsyncResultInterface;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "gdbusprivate.h"
|
#include "gdbusprivate.h"
|
||||||
#include "gdbusmethodinvocation.h"
|
#include "gdbusmethodinvocation.h"
|
||||||
#include "gdbusconnection.h"
|
#include "gdbusconnection.h"
|
||||||
#include "gioscheduler.h"
|
#include "gtask.h"
|
||||||
#include "gioerror.h"
|
#include "gioerror.h"
|
||||||
|
|
||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
@ -459,17 +459,13 @@ typedef struct
|
|||||||
GDBusInterfaceSkeleton *interface;
|
GDBusInterfaceSkeleton *interface;
|
||||||
GDBusInterfaceMethodCallFunc method_call_func;
|
GDBusInterfaceMethodCallFunc method_call_func;
|
||||||
GDBusMethodInvocation *invocation;
|
GDBusMethodInvocation *invocation;
|
||||||
GMainContext *context;
|
|
||||||
} DispatchData;
|
} DispatchData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dispatch_data_unref (DispatchData *data)
|
dispatch_data_unref (DispatchData *data)
|
||||||
{
|
{
|
||||||
if (g_atomic_int_dec_and_test (&data->ref_count))
|
if (g_atomic_int_dec_and_test (&data->ref_count))
|
||||||
{
|
g_slice_free (DispatchData, data);
|
||||||
g_main_context_unref (data->context);
|
|
||||||
g_free (data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DispatchData *
|
static DispatchData *
|
||||||
@ -494,12 +490,13 @@ dispatch_invoke_in_context_func (gpointer user_data)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
dispatch_in_thread_func (GIOSchedulerJob *job,
|
dispatch_in_thread_func (GTask *task,
|
||||||
GCancellable *cancellable,
|
gpointer source_object,
|
||||||
gpointer user_data)
|
gpointer task_data,
|
||||||
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
DispatchData *data = user_data;
|
DispatchData *data = task_data;
|
||||||
GDBusInterfaceSkeletonFlags flags;
|
GDBusInterfaceSkeletonFlags flags;
|
||||||
GDBusObject *object;
|
GDBusObject *object;
|
||||||
gboolean authorized;
|
gboolean authorized;
|
||||||
@ -549,8 +546,8 @@ dispatch_in_thread_func (GIOSchedulerJob *job,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* bah, back to original context */
|
/* bah, back to original context */
|
||||||
g_main_context_invoke_full (data->context,
|
g_main_context_invoke_full (g_task_get_context (task),
|
||||||
G_PRIORITY_DEFAULT,
|
g_task_get_priority (task),
|
||||||
dispatch_invoke_in_context_func,
|
dispatch_invoke_in_context_func,
|
||||||
dispatch_data_ref (data),
|
dispatch_data_ref (data),
|
||||||
(GDestroyNotify) dispatch_data_unref);
|
(GDestroyNotify) dispatch_data_unref);
|
||||||
@ -563,8 +560,6 @@ dispatch_in_thread_func (GIOSchedulerJob *job,
|
|||||||
|
|
||||||
if (object != NULL)
|
if (object != NULL)
|
||||||
g_object_unref (object);
|
g_object_unref (object);
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -623,18 +618,19 @@ g_dbus_interface_method_dispatch_helper (GDBusInterfaceSkeleton *interface
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
GTask *task;
|
||||||
DispatchData *data;
|
DispatchData *data;
|
||||||
data = g_new0 (DispatchData, 1);
|
|
||||||
|
data = g_slice_new0 (DispatchData);
|
||||||
data->interface = interface;
|
data->interface = interface;
|
||||||
data->method_call_func = method_call_func;
|
data->method_call_func = method_call_func;
|
||||||
data->invocation = invocation;
|
data->invocation = invocation;
|
||||||
data->context = g_main_context_ref_thread_default ();
|
|
||||||
data->ref_count = 1;
|
data->ref_count = 1;
|
||||||
g_io_scheduler_push_job (dispatch_in_thread_func,
|
|
||||||
data,
|
task = g_task_new (interface, NULL, NULL, NULL);
|
||||||
(GDestroyNotify) dispatch_data_unref,
|
g_task_set_task_data (task, data, (GDestroyNotify) dispatch_data_unref);
|
||||||
G_PRIORITY_DEFAULT,
|
g_task_run_in_thread (task, dispatch_in_thread_func);
|
||||||
NULL); /* GCancellable* */
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object != NULL)
|
if (object != NULL)
|
||||||
|
67
gio/gfile.c
67
gio/gfile.c
@ -5947,7 +5947,6 @@ typedef struct {
|
|||||||
GFileCopyFlags flags;
|
GFileCopyFlags flags;
|
||||||
GFileProgressCallback progress_cb;
|
GFileProgressCallback progress_cb;
|
||||||
gpointer progress_cb_data;
|
gpointer progress_cb_data;
|
||||||
GIOSchedulerJob *job;
|
|
||||||
} CopyAsyncData;
|
} CopyAsyncData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -5955,7 +5954,7 @@ copy_async_data_free (CopyAsyncData *data)
|
|||||||
{
|
{
|
||||||
g_object_unref (data->source);
|
g_object_unref (data->source);
|
||||||
g_object_unref (data->destination);
|
g_object_unref (data->destination);
|
||||||
g_free (data);
|
g_slice_free (CopyAsyncData, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -5982,7 +5981,8 @@ copy_async_progress_callback (goffset current_num_bytes,
|
|||||||
goffset total_num_bytes,
|
goffset total_num_bytes,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
CopyAsyncData *data = user_data;
|
GTask *task = user_data;
|
||||||
|
CopyAsyncData *data = g_task_get_task_data (task);
|
||||||
ProgressData *progress;
|
ProgressData *progress;
|
||||||
|
|
||||||
progress = g_new (ProgressData, 1);
|
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->current_num_bytes = current_num_bytes;
|
||||||
progress->total_num_bytes = total_num_bytes;
|
progress->total_num_bytes = total_num_bytes;
|
||||||
|
|
||||||
g_io_scheduler_job_send_to_mainloop_async (data->job,
|
g_main_context_invoke_full (g_task_get_context (task),
|
||||||
copy_async_progress_in_main,
|
g_task_get_priority (task),
|
||||||
progress,
|
copy_async_progress_in_main,
|
||||||
g_free);
|
progress,
|
||||||
|
g_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
copy_async_thread (GIOSchedulerJob *job,
|
copy_async_thread (GTask *task,
|
||||||
GCancellable *cancellable,
|
gpointer source,
|
||||||
gpointer user_data)
|
gpointer task_data,
|
||||||
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
GSimpleAsyncResult *res;
|
CopyAsyncData *data = task_data;
|
||||||
CopyAsyncData *data;
|
|
||||||
gboolean result;
|
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,
|
result = g_file_copy (data->source,
|
||||||
data->destination,
|
data->destination,
|
||||||
data->flags,
|
data->flags,
|
||||||
cancellable,
|
cancellable,
|
||||||
(data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
|
(data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
|
||||||
data,
|
task,
|
||||||
&error);
|
&error);
|
||||||
|
if (result)
|
||||||
if (!result)
|
g_task_return_boolean (task, TRUE);
|
||||||
g_simple_async_result_take_error (res, error);
|
else
|
||||||
|
g_task_return_error (task, error);
|
||||||
g_simple_async_result_complete_in_idle (res);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -6038,20 +6031,21 @@ g_file_real_copy_async (GFile *source,
|
|||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GSimpleAsyncResult *res;
|
GTask *task;
|
||||||
CopyAsyncData *data;
|
CopyAsyncData *data;
|
||||||
|
|
||||||
data = g_new0 (CopyAsyncData, 1);
|
data = g_slice_new (CopyAsyncData);
|
||||||
data->source = g_object_ref (source);
|
data->source = g_object_ref (source);
|
||||||
data->destination = g_object_ref (destination);
|
data->destination = g_object_ref (destination);
|
||||||
data->flags = flags;
|
data->flags = flags;
|
||||||
data->progress_cb = progress_callback;
|
data->progress_cb = progress_callback;
|
||||||
data->progress_cb_data = progress_callback_data;
|
data->progress_cb_data = progress_callback_data;
|
||||||
|
|
||||||
res = g_simple_async_result_new (G_OBJECT (source), callback, user_data, g_file_real_copy_async);
|
task = g_task_new (source, cancellable, callback, user_data);
|
||||||
g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)copy_async_data_free);
|
g_task_set_task_data (task, data, (GDestroyNotify)copy_async_data_free);
|
||||||
|
g_task_set_priority (task, io_priority);
|
||||||
g_io_scheduler_push_job (copy_async_thread, res, g_object_unref, io_priority, cancellable);
|
g_task_run_in_thread (task, copy_async_thread);
|
||||||
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -6059,12 +6053,7 @@ g_file_real_copy_finish (GFile *file,
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
return g_task_propagate_boolean (G_TASK (res), error);
|
||||||
|
|
||||||
if (g_simple_async_result_propagate_error (simple, error))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ next_async_callback_wrapper (GObject *source_object,
|
|||||||
* g_file_enumerator_next_files_async:
|
* g_file_enumerator_next_files_async:
|
||||||
* @enumerator: a #GFileEnumerator.
|
* @enumerator: a #GFileEnumerator.
|
||||||
* @num_files: the number of file info objects to request
|
* @num_files: the number of file info objects to request
|
||||||
* @io_priority: the <link linkend="gioscheduler">io priority</link>
|
* @io_priority: the <link linkend="io-priority">io priority</link>
|
||||||
* of the request.
|
* of the request.
|
||||||
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
|
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
|
||||||
* @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
|
* @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
|
||||||
|
@ -24,34 +24,30 @@
|
|||||||
|
|
||||||
#include "gioscheduler.h"
|
#include "gioscheduler.h"
|
||||||
#include "gcancellable.h"
|
#include "gcancellable.h"
|
||||||
|
#include "gtask.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gioscheduler
|
* SECTION:gioscheduler
|
||||||
* @short_description: I/O Scheduler
|
* @short_description: I/O Scheduler
|
||||||
* @include: gio/gio.h
|
* @include: gio/gio.h
|
||||||
*
|
*
|
||||||
|
* <note><para>
|
||||||
|
* As of GLib 2.36, the <literal>g_io_scheduler</literal> methods
|
||||||
|
* are deprecated in favor of #GThreadPool and #GTask.
|
||||||
|
* </para></note>
|
||||||
|
*
|
||||||
* Schedules asynchronous I/O operations. #GIOScheduler integrates
|
* Schedules asynchronous I/O operations. #GIOScheduler integrates
|
||||||
* into the main event loop (#GMainLoop) and uses threads.
|
* into the main event loop (#GMainLoop) and uses threads.
|
||||||
*
|
|
||||||
* <para id="io-priority"><indexterm><primary>I/O priority</primary></indexterm>
|
|
||||||
* Each I/O operation has a priority, and the scheduler uses the priorities
|
|
||||||
* to determine the order in which operations are executed. They are
|
|
||||||
* <emphasis>not</emphasis> 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.
|
|
||||||
* </para>
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
struct _GIOSchedulerJob {
|
struct _GIOSchedulerJob {
|
||||||
GList *active_link;
|
GList *active_link;
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
GIOSchedulerJobFunc job_func;
|
GIOSchedulerJobFunc job_func;
|
||||||
GSourceFunc cancel_func; /* Runs under job map lock */
|
|
||||||
gpointer data;
|
gpointer data;
|
||||||
GDestroyNotify destroy_notify;
|
GDestroyNotify destroy_notify;
|
||||||
|
|
||||||
gint io_priority;
|
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
gulong cancellable_id;
|
gulong cancellable_id;
|
||||||
GMainContext *context;
|
GMainContext *context;
|
||||||
@ -60,98 +56,29 @@ struct _GIOSchedulerJob {
|
|||||||
G_LOCK_DEFINE_STATIC(active_jobs);
|
G_LOCK_DEFINE_STATIC(active_jobs);
|
||||||
static GList *active_jobs = NULL;
|
static GList *active_jobs = NULL;
|
||||||
|
|
||||||
static GThreadPool *job_thread_pool = NULL;
|
|
||||||
|
|
||||||
static void io_job_thread (gpointer data,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_io_job_free (GIOSchedulerJob *job)
|
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)
|
if (job->destroy_notify)
|
||||||
job->destroy_notify (job->data);
|
job->destroy_notify (job->data);
|
||||||
|
|
||||||
G_LOCK (active_jobs);
|
G_LOCK (active_jobs);
|
||||||
active_jobs = g_list_delete_link (active_jobs, job->active_link);
|
active_jobs = g_list_delete_link (active_jobs, job->active_link);
|
||||||
G_UNLOCK (active_jobs);
|
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
|
static void
|
||||||
io_job_thread (gpointer data,
|
io_job_thread (GTask *task,
|
||||||
gpointer user_data)
|
gpointer source_object,
|
||||||
|
gpointer task_data,
|
||||||
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
GIOSchedulerJob *job = data;
|
GIOSchedulerJob *job = task_data;
|
||||||
gboolean result;
|
gboolean result;
|
||||||
|
|
||||||
if (job->cancellable)
|
if (job->cancellable)
|
||||||
@ -165,8 +92,6 @@ io_job_thread (gpointer data,
|
|||||||
|
|
||||||
if (job->cancellable)
|
if (job->cancellable)
|
||||||
g_cancellable_pop_current (job->cancellable);
|
g_cancellable_pop_current (job->cancellable);
|
||||||
|
|
||||||
job_destroy (job);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,7 +99,7 @@ io_job_thread (gpointer data,
|
|||||||
* @job_func: a #GIOSchedulerJobFunc.
|
* @job_func: a #GIOSchedulerJobFunc.
|
||||||
* @user_data: data to pass to @job_func
|
* @user_data: data to pass to @job_func
|
||||||
* @notify: (allow-none): a #GDestroyNotify for @user_data, or %NULL
|
* @notify: (allow-none): a #GDestroyNotify for @user_data, or %NULL
|
||||||
* @io_priority: the <link linkend="gioscheduler">I/O priority</link>
|
* @io_priority: the <link linkend="io-priority">I/O priority</link>
|
||||||
* of the request.
|
* of the request.
|
||||||
* @cancellable: optional #GCancellable object, %NULL to ignore.
|
* @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
|
* If @cancellable is not %NULL, it can be used to cancel the I/O job
|
||||||
* by calling g_cancellable_cancel() or by calling
|
* by calling g_cancellable_cancel() or by calling
|
||||||
* g_io_scheduler_cancel_all_jobs().
|
* g_io_scheduler_cancel_all_jobs().
|
||||||
|
*
|
||||||
|
* Deprecated: use #GThreadPool or g_task_run_in_thread()
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
g_io_scheduler_push_job (GIOSchedulerJobFunc job_func,
|
g_io_scheduler_push_job (GIOSchedulerJobFunc job_func,
|
||||||
@ -194,23 +121,18 @@ g_io_scheduler_push_job (GIOSchedulerJobFunc job_func,
|
|||||||
gint io_priority,
|
gint io_priority,
|
||||||
GCancellable *cancellable)
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
static GOnce once_init = G_ONCE_INIT;
|
|
||||||
GIOSchedulerJob *job;
|
GIOSchedulerJob *job;
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
g_return_if_fail (job_func != NULL);
|
g_return_if_fail (job_func != NULL);
|
||||||
|
|
||||||
job = g_new0 (GIOSchedulerJob, 1);
|
job = g_slice_new0 (GIOSchedulerJob);
|
||||||
job->job_func = job_func;
|
job->job_func = job_func;
|
||||||
job->data = user_data;
|
job->data = user_data;
|
||||||
job->destroy_notify = notify;
|
job->destroy_notify = notify;
|
||||||
job->io_priority = io_priority;
|
|
||||||
|
|
||||||
if (cancellable)
|
if (cancellable)
|
||||||
{
|
job->cancellable = g_object_ref (cancellable);
|
||||||
job->cancellable = g_object_ref (cancellable);
|
|
||||||
job->cancellable_id = g_cancellable_connect (job->cancellable, (GCallback)on_job_canceled,
|
|
||||||
job, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
job->context = g_main_context_ref_thread_default ();
|
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;
|
job->active_link = active_jobs;
|
||||||
G_UNLOCK (active_jobs);
|
G_UNLOCK (active_jobs);
|
||||||
|
|
||||||
g_once (&once_init, init_scheduler, NULL);
|
task = g_task_new (NULL, cancellable, NULL, NULL);
|
||||||
g_thread_pool_push (job_thread_pool, job, 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
|
* A job is cancellable if a #GCancellable was passed into
|
||||||
* g_io_scheduler_push_job().
|
* 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
|
void
|
||||||
g_io_scheduler_cancel_all_jobs (void)
|
g_io_scheduler_cancel_all_jobs (void)
|
||||||
@ -305,6 +234,8 @@ mainloop_proxy_free (MainLoopProxy *proxy)
|
|||||||
* blocking the I/O job).
|
* blocking the I/O job).
|
||||||
*
|
*
|
||||||
* Returns: The return value of @func
|
* Returns: The return value of @func
|
||||||
|
*
|
||||||
|
* Deprecated: Use g_main_context_invoke().
|
||||||
**/
|
**/
|
||||||
gboolean
|
gboolean
|
||||||
g_io_scheduler_job_send_to_mainloop (GIOSchedulerJob *job,
|
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
|
* on to this function you have to ensure that it is not freed before
|
||||||
* @func is called, either by passing %NULL as @notify to
|
* @func is called, either by passing %NULL as @notify to
|
||||||
* g_io_scheduler_push_job() or by using refcounting for @user_data.
|
* g_io_scheduler_push_job() or by using refcounting for @user_data.
|
||||||
|
*
|
||||||
|
* Deprecated: Use g_main_context_invoke().
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
g_io_scheduler_job_send_to_mainloop_async (GIOSchedulerJob *job,
|
g_io_scheduler_job_send_to_mainloop_async (GIOSchedulerJob *job,
|
||||||
|
@ -32,16 +32,20 @@
|
|||||||
G_BEGIN_DECLS
|
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,
|
void g_io_scheduler_push_job (GIOSchedulerJobFunc job_func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify notify,
|
GDestroyNotify notify,
|
||||||
gint io_priority,
|
gint io_priority,
|
||||||
GCancellable *cancellable);
|
GCancellable *cancellable);
|
||||||
|
GLIB_DEPRECATED_IN_2_36
|
||||||
void g_io_scheduler_cancel_all_jobs (void);
|
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,
|
gboolean g_io_scheduler_job_send_to_mainloop (GIOSchedulerJob *job,
|
||||||
GSourceFunc func,
|
GSourceFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify notify);
|
GDestroyNotify notify);
|
||||||
|
GLIB_DEPRECATED_IN_2_36_FOR (g_main_context_invoke)
|
||||||
void g_io_scheduler_job_send_to_mainloop_async (GIOSchedulerJob *job,
|
void g_io_scheduler_job_send_to_mainloop_async (GIOSchedulerJob *job,
|
||||||
GSourceFunc func,
|
GSourceFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
|
@ -45,10 +45,12 @@
|
|||||||
* @include: gio/gio.h
|
* @include: gio/gio.h
|
||||||
* @see_also: #GAsyncResult
|
* @see_also: #GAsyncResult
|
||||||
*
|
*
|
||||||
* Implements #GAsyncResult for simple cases. Most of the time, this
|
* <note><para>
|
||||||
* will be all an application needs, and will be used transparently.
|
* As of GLib 2.36, #GSimpleAsyncResult is deprecated in favor of
|
||||||
* Because of this, #GSimpleAsyncResult is used throughout GIO for
|
* #GTask, which provides a simpler API.
|
||||||
* handling asynchronous functions.
|
* </para></note>
|
||||||
|
*
|
||||||
|
* #GSimpleAsyncResult implements #GAsyncResult.
|
||||||
*
|
*
|
||||||
* GSimpleAsyncResult handles #GAsyncReadyCallback<!-- -->s, error
|
* GSimpleAsyncResult handles #GAsyncReadyCallback<!-- -->s, error
|
||||||
* reporting, operation cancellation and the final state of an operation,
|
* 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;
|
data->cancellable = cancellable;
|
||||||
if (cancellable)
|
if (cancellable)
|
||||||
g_object_ref (cancellable);
|
g_object_ref (cancellable);
|
||||||
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||||
g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
|
g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
|
||||||
|
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user