[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