X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgioscheduler.c;h=4c826c67ee4a743ddd651fd46e631b9fedadf8fb;hb=356a3987cee7ceddcb3fe623edf0bd2881895add;hp=e75e3308d193d8b2e1f7da60ce82a1fa252f1e11;hpb=449a1e8bfd0ea7e8db1e3a436cf182b5cc71aa75;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gioscheduler.c b/gio/gioscheduler.c index e75e330..4c826c6 100644 --- a/gio/gioscheduler.c +++ b/gio/gioscheduler.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Author: Alexander Larsson */ @@ -24,150 +22,59 @@ #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, #GIOScheduler is 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 { - GSList *active_link; + 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; }; G_LOCK_DEFINE_STATIC(active_jobs); -static GSList *active_jobs = NULL; - -static GThreadPool *job_thread_pool = NULL; - -static void io_job_thread (gpointer data, - gpointer user_data); +static GList *active_jobs = NULL; static void g_io_job_free (GIOSchedulerJob *job) { - if (job->cancellable) - g_object_unref (job->cancellable); - if (job->context) - 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); - /* It's kinda weird that this is a global setting - * instead of per threadpool. However, we really - * want to cache some threads, but not keep around - * those threads forever. */ - g_thread_pool_set_max_idle_time (15 * 1000); - g_thread_pool_set_max_unused_threads (2); - } - } - return NULL; -} + if (job->destroy_notify) + job->destroy_notify (job->data); -static void -remove_active_job (GIOSchedulerJob *job) -{ - GIOSchedulerJob *other_job; - GSList *l; - gboolean resort_jobs; - G_LOCK (active_jobs); - active_jobs = g_slist_delete_link (active_jobs, job->active_link); - - resort_jobs = FALSE; - for (l = active_jobs; l != NULL; l = l->next) - { - other_job = l->data; - if (other_job->io_priority >= 0 && - g_cancellable_is_cancelled (other_job->cancellable)) - { - other_job->io_priority = -1; - resort_jobs = TRUE; - } - } + active_jobs = g_list_delete_link (active_jobs, job->active_link); G_UNLOCK (active_jobs); - - if (resort_jobs && - 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); - - remove_active_job (job); - 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) @@ -181,20 +88,18 @@ io_job_thread (gpointer data, if (job->cancellable) g_cancellable_pop_current (job->cancellable); - - job_destroy (job); } /** * g_io_scheduler_push_job: * @job_func: a #GIOSchedulerJobFunc. * @user_data: data to pass to @job_func - * @notify: a #GDestroyNotify for @user_data, or %NULL - * @io_priority: the I/O priority + * @notify: (allow-none): a #GDestroyNotify for @user_data, or %NULL + * @io_priority: the [I/O priority][io-priority] * of the request. * @cancellable: optional #GCancellable object, %NULL to ignore. * - * Schedules the I/O job to run. + * Schedules the I/O job to run in another thread. * * @notify will be called on @user_data after @job_func has returned, * regardless whether the job was cancelled or has run to completion. @@ -202,6 +107,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, @@ -210,31 +117,31 @@ 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->context = g_main_context_get_thread_default (); - if (job->context) - g_main_context_ref (job->context); + job->context = g_main_context_ref_thread_default (); G_LOCK (active_jobs); - active_jobs = g_slist_prepend (active_jobs, job); + active_jobs = g_list_prepend (active_jobs, job); 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); } /** @@ -244,11 +151,15 @@ 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) { - GSList *cancellable_list, *l; + GList *cancellable_list, *l; G_LOCK (active_jobs); cancellable_list = NULL; @@ -256,8 +167,8 @@ g_io_scheduler_cancel_all_jobs (void) { GIOSchedulerJob *job = l->data; if (job->cancellable) - cancellable_list = g_slist_prepend (cancellable_list, - g_object_ref (job->cancellable)); + cancellable_list = g_list_prepend (cancellable_list, + g_object_ref (job->cancellable)); } G_UNLOCK (active_jobs); @@ -267,7 +178,7 @@ g_io_scheduler_cancel_all_jobs (void) g_cancellable_cancel (c); g_object_unref (c); } - g_slist_free (cancellable_list); + g_list_free (cancellable_list); } typedef struct { @@ -312,13 +223,15 @@ mainloop_proxy_free (MainLoopProxy *proxy) * @job: a #GIOSchedulerJob * @func: a #GSourceFunc callback that will be called in the original thread * @user_data: data to pass to @func - * @notify: a #GDestroyNotify for @user_data, or %NULL + * @notify: (allow-none): a #GDestroyNotify for @user_data, or %NULL * * Used from an I/O job to send a callback to be run in the thread * that the job was started from, waiting for the result (and thus * 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, @@ -345,6 +258,7 @@ g_io_scheduler_job_send_to_mainloop (GIOSchedulerJob *job, g_source_set_priority (source, G_PRIORITY_DEFAULT); g_source_set_callback (source, mainloop_proxy_func, proxy, NULL); + g_source_set_name (source, "[gio] mainloop_proxy_func"); g_source_attach (source, job->context); g_source_unref (source); @@ -364,7 +278,7 @@ g_io_scheduler_job_send_to_mainloop (GIOSchedulerJob *job, * @job: a #GIOSchedulerJob * @func: a #GSourceFunc callback that will be called in the original thread * @user_data: data to pass to @func - * @notify: a #GDestroyNotify for @user_data, or %NULL + * @notify: (allow-none): a #GDestroyNotify for @user_data, or %NULL * * Used from an I/O job to send a callback to be run asynchronously in * the thread that the job was started from. The callback will be run @@ -375,6 +289,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, @@ -399,6 +315,7 @@ g_io_scheduler_job_send_to_mainloop_async (GIOSchedulerJob *job, g_source_set_priority (source, G_PRIORITY_DEFAULT); g_source_set_callback (source, mainloop_proxy_func, proxy, (GDestroyNotify)mainloop_proxy_free); + g_source_set_name (source, "[gio] mainloop_proxy_func"); g_source_attach (source, job->context); g_source_unref (source);