[Xfce4-commits] <exo:master> Update job docs. Only cancel the cancellable if the job is running.
Jannis Pohlmann
jannis at xfce.org
Wed Sep 2 16:20:03 CEST 2009
Updating branch refs/heads/master
to f3ea0ce56d15769de9184fb2c04e338a3ad83a0e (commit)
from d89f1faae0e279264f5fc79537dda9b81f922b34 (commit)
commit f3ea0ce56d15769de9184fb2c04e338a3ad83a0e
Author: Jannis Pohlmann <jannis at xfce.org>
Date: Wed Sep 2 16:18:55 2009 +0200
Update job docs. Only cancel the cancellable if the job is running.
exo/exo-job.c | 82 +++++++++++++++++++++++++++++++-------------------
exo/exo-simple-job.c | 75 +++++++++++++++++++++++++++++++++++++++++----
2 files changed, 119 insertions(+), 38 deletions(-)
diff --git a/exo/exo-job.c b/exo/exo-job.c
index b90fa08..d7a8ad0 100644
--- a/exo/exo-job.c
+++ b/exo/exo-job.c
@@ -43,16 +43,16 @@
* <link linkend="ExoJob">ExoJob</link> is an abstract base class
* intended to wrap threaded/asynchronous operations (called jobs here).
* It was written because the ways of dealing with threads provided by
- * GLib were too low-level and not exactly object-oriented.
+ * GLib are not exactly object-oriented.
*
* It can be used to wrap any kind of long-running or possibly-blocking
- * operation, like file operations or communication with web services.
- * The benefit of using <link linkend="ExoJob">ExoJob</link> is that you
- * get an object associated with an operation. After creating the job
- * you can connect to signals like <link linkend="ExoJob::error">"error"
+ * operation like file operations or communication with web services.
+ * The benefit of using <link linkend="ExoJob">ExoJob</link> is that one
+ * gets an object associated with each operation. After creating the job
+ * the caller can connect to signals like <link linkend="ExoJob::error">"error"
* </link> or <link linkend="ExoJob::percent">"percent"</link>. This
- * design integrates very well in the usual object-oriented design of
- * applications based on GLib.
+ * design integrates very well with the usual object-oriented design of
+ * applications based on GObject.
**/
@@ -131,7 +131,16 @@ exo_job_class_init (ExoJobClass *klass)
* @job : an #ExoJob.
* @error : a #GError describing the cause.
*
- * Emitted whenever an error occurs while executing the @job.
+ * Emitted whenever an error occurs while executing the @job. This signal
+ * may not be emitted from within #ExoJob subclasses. If a subclass wants
+ * to emit an "error" signal (and thereby terminate the operation), it has
+ * to fill the #GError structure and abort from its execute() method.
+ * #ExoJob will automatically emit the "error" signal when the #GError is
+ * filled after the execute() method has finished.
+ *
+ * Callers interested in whether the @job was cancelled can connect to
+ * the "cancelled" signal of the #GCancellable returned from
+ * exo_job_get_cancellable().
**/
job_signals[ERROR] =
g_signal_new (I_("error"),
@@ -148,7 +157,9 @@ exo_job_class_init (ExoJobClass *klass)
*
* This signal will be automatically emitted once the @job finishes
* its execution, no matter whether @job completed successfully or
- * was cancelled by the user.
+ * was cancelled by the user. It may not be emitted by subclasses of
+ * #ExoJob as it is automatically emitted by #ExoJob after the execute()
+ * method has finished.
**/
job_signals[FINISHED] =
g_signal_new (I_("finished"),
@@ -164,8 +175,8 @@ exo_job_class_init (ExoJobClass *klass)
* @job : an #ExoJob.
* @message : information to be displayed about @job.
*
- * This signal is emitted to display information about the * @job.
- * Examples of messages are "Preparing..." or "Cleaning up...".
+ * This signal is emitted to display information about the status of
+ * the @job. Examples of messages are "Preparing..." or "Cleaning up...".
*
* The @message is garanteed to contain valid UTF-8, so it can be
* displayed by #GtkWidget<!---->s out of the box.
@@ -184,9 +195,9 @@ exo_job_class_init (ExoJobClass *klass)
* @job : an #ExoJob.
* @percent : the percentage of completeness.
*
- * This signal is emitted to present the state of the overall
- * progress. The @percent value is garantied to be in the range 0.0
- * to 100.0.
+ * This signal is emitted to present the overall progress of the
+ * operation. The @percent value is garantied to be a value between
+ * 0.0 and 100.0.
**/
job_signals[PERCENT] =
g_signal_new (I_("percent"),
@@ -216,7 +227,9 @@ exo_job_finalize (GObject *object)
{
ExoJob *job = EXO_JOB (object);
- exo_job_cancel (job);
+ if (job->priv->running)
+ exo_job_cancel (job);
+
g_object_unref (job->priv->cancellable);
(*G_OBJECT_CLASS (exo_job_parent_class)->finalize) (object);
@@ -234,7 +247,7 @@ exo_job_finalize (GObject *object)
* from the @result into @error.
*
* Returns: %TRUE if there was no error during the operation,
- * %FALSE otherwise.
+ * %FALSE otherwise.
**/
static gboolean
exo_job_finish (ExoJob *job,
@@ -273,7 +286,7 @@ exo_job_async_ready (GObject *object,
{
g_assert (error != NULL);
- /* don't treat cancellation as an error for now */
+ /* don't treat cancellation as an error */
if (error->code != G_IO_ERROR_CANCELLED)
exo_job_error (job, error);
@@ -281,6 +294,8 @@ exo_job_async_ready (GObject *object,
}
exo_job_finished (job);
+
+ job->priv->running = FALSE;
}
@@ -293,7 +308,7 @@ exo_job_async_ready (GObject *object,
*
* This function is called by the #GIOScheduler to execute the
* operation associated with the job. It basically calls the
- * ExoJobClass#execute function.
+ * execute() function of #ExoJobClass.
*
* Returns: %FALSE, to stop the thread at the end of the operation.
**/
@@ -312,7 +327,7 @@ exo_job_scheduler_job_func (GIOSchedulerJob *scheduler_job,
success = (*EXO_JOB_GET_CLASS (job)->execute) (job, &error);
- /* TODO why was this necessary again? */
+ /* TODO why was this necessary again? GIO uses this too, for some reason. */
g_io_scheduler_job_send_to_mainloop (scheduler_job, (GSourceFunc) gtk_false,
NULL, NULL);
@@ -337,7 +352,7 @@ exo_job_scheduler_job_func (GIOSchedulerJob *scheduler_job,
* specified by the @user_data.
*
* Returns: %FALSE, to keep the function from being called
- * multiple times in a row.
+ * multiple times in a row.
**/
static gboolean
exo_job_emit_valist_in_mainloop (gpointer user_data)
@@ -361,9 +376,8 @@ exo_job_emit_valist_in_mainloop (gpointer user_data)
* return type of the signal is G_TYPE_NONE, the return
* value location can be omitted.
*
- * Send a the signal with the given @signal_id and @signal_detail to the
- * main loop of the application and waits for the listeners to handle
- * it.
+ * Sends a the signal with the given @signal_id and @signal_detail to the
+ * main loop of the application and waits for listeners to handle it.
**/
static void
exo_job_emit_valist (ExoJob *job,
@@ -438,8 +452,8 @@ exo_job_finished (ExoJob *job)
* @job : an #ExoJob.
*
* This functions schedules the @job to be run as soon as possible, in
- * a separate thread. The caller can then connect to the signals of the
- * returned #ExoJob in order to be notified on errors, progress updates
+ * a separate thread. The caller can connect to signals of the @job prior
+ * or after this call in order to be notified on errors, progress updates
* and the end of the operation.
*
* Returns: the @job itself.
@@ -480,12 +494,17 @@ exo_job_launch (ExoJob *job)
* after the cancellation of @job, it may still emit signals, so you
* must take care of disconnecting all handlers appropriately if you
* cannot handle signals after cancellation.
+ *
+ * Calling this function when the @job has not been launched yet or
+ * when it has already finished will have no effect.
**/
void
exo_job_cancel (ExoJob *job)
{
_exo_return_if_fail (EXO_IS_JOB (job));
- g_cancellable_cancel (job->priv->cancellable);
+
+ if (job->priv->running)
+ g_cancellable_cancel (job->priv->cancellable);
}
@@ -539,7 +558,8 @@ exo_job_get_cancellable (const ExoJob *job)
* g_cancellable_set_error_if_cancelled (cancellable, error);
* </programlisting></informalexample>
*
- * Returns: %TRUE if the job was cancelled and @error is now set, %FALSE otherwise.
+ * Returns: %TRUE if the job was cancelled and @error is now set,
+ * %FALSE otherwise.
**/
gboolean
exo_job_set_error_if_cancelled (ExoJob *job,
@@ -561,7 +581,7 @@ exo_job_set_error_if_cancelled (ExoJob *job,
* return type of the signal is G_TYPE_NONE, the return
* value location can be omitted.
*
- * Sends the signal with @signal_id and @signal_id to the application's
+ * Sends the signal with @signal_id and @signal_detail to the application's
* main loop and waits for listeners to handle it.
**/
void
@@ -626,7 +646,7 @@ exo_job_percent (ExoJob *job,
{
_exo_return_if_fail (EXO_IS_JOB (job));
- percent = MAX (0.0, MIN (100.0, percent));
+ percent = CLAMP (percent, 0.0, 100.0);
exo_job_emit (job, job_signals[PERCENT], 0, percent);
}
@@ -639,8 +659,8 @@ exo_job_percent (ExoJob *job,
* @user_data : data to pass to @func.
* @destroy_notify : a #GDestroyNotify for @user_data, or %NULL.
*
- * This functions schedules the @job to be run in the main loop (main thread),
- * waiting for the result (and thus blocking the I/O job).
+ * This functions schedules @func to be run in the main loop (main thread),
+ * waiting for the result (and blocking the job in the meantime).
*
* Returns: The return value of @func.
**/
diff --git a/exo/exo-simple-job.c b/exo/exo-simple-job.c
index 94c0b20..a7918ee 100644
--- a/exo/exo-simple-job.c
+++ b/exo/exo-simple-job.c
@@ -43,11 +43,14 @@
/**
* SECTION: exo-simple-job
* @title: ExoSimpleJob
- * @short_description: FIXME
+ * @short_description: Simple interface to execute functions asynchronously
* @include: exo/exo.h
- * @see_also:
+ * @see_also: <link linkend="ExoJob">ExoJob</link>
*
- * FIXME
+ * <link linkend="ExoSimpleJob">ExoSimpleJob</link> can be used to execute
+ * functions asynchronously in an #ExoJob wrapper object. It is easier to
+ * use than the #GThread system and provides basic signals to follow the
+ * progress of an operation.
**/
@@ -71,9 +74,9 @@ struct _ExoSimpleJobClass
**/
struct _ExoSimpleJob
{
- ExoJob __parent__;
ExoSimpleJobFunc func;
GValueArray *param_values;
+ ExoJob __parent__;
};
@@ -168,11 +171,69 @@ exo_simple_job_execute (ExoJob *job,
* An example could be:
*
* <informalexample><programlisting>
- * exo_simple_job_launch (list_directory_job, 1, G_TYPE_FILE, file);
+ * static gboolean
+ * list_directory (ExoJob *job,
+ * GValueArray *param_values,
+ * GError **error)
+ * {
+ * GFileEnumerator *enumerator;
+ * GFileInfo *info;
+ * GError *err = NULL;
+ * GFile *directory;
+ *
+ * if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
+ * return FALSE;
+ *
+ * directory = g_value_get_object (g_value_array_get_nth (param_values, 0));
+ *
+ * enumerator = g_file_enumerate_children (directory,
+ * "standard::display-name",
+ * G_FILE_QUERY_INFO_NONE,
+ * exo_job_get_cancellable (job),
+ * &err);
+ *
+ * if (err != NULL)
+ * {
+ * g_propagate_error (error, err);
+ * return FALSE;
+ * }
+ *
+ * while (TRUE)
+ * {
+ * info = g_file_enumerator_next_file (enumerator,
+ * exo_job_get_cancellable (job),
+ * &err);
+ *
+ * if (info == NULL)
+ * break;
+ *
+ * exo_job_info_message (job, _("Child: %s"),
+ * g_file_info_get_display_name (info));
+ *
+ * g_object_unref (info);
+ * }
+ *
+ * g_object_unref (enumerator);
+ *
+ * if (err != NULL)
+ * {
+ * g_propagate_error (error, err);
+ * return FALSE;
+ * }
+ * else
+ * {
+ * return TRUE;
+ * }
+ * }
+ *
+ * ...
+ *
+ * GFile *file = g_file_new_for_path ("/home/user");
+ * exo_simple_job_launch (list_directory, 1, G_TYPE_FILE, file);
* </programlisting></informalexample>
*
- * The caller is responsible to release the returned object using
- * g_object_unref() when no longer needed.
+ * The caller is responsible to release the returned #ExoJob object
+ * using g_object_unref() when no longer needed.
*
* Returns: the launched #ExoJob.
**/
More information about the Xfce4-commits
mailing list