## FmJob FmJob — Base class of all kinds of asynchronous jobs. |

## Synopsis

    struct              FmJob;
    gpointer            (*FmJobCallMainThreadFunc)          (FmJob *job,
                                                             gpointer user_data);
    struct              FmJobClass;
    enum                FmJobErrorAction;
    enum                FmJobErrorSeverity;
    gint                fm_job_ask                          (FmJob *job,
                                                             const char *question,
                                                             ...);
    gint                fm_job_ask_valist                   (FmJob *job,
                                                             const char *question,
                                                             va_list options);
    gint                fm_job_askv                         (FmJob *job,
                                                             const char *question,
                                                             gchar * const *options);
    gpointer            fm_job_call_main_thread             (FmJob *job,
                                                             FmJobCallMainThreadFunc func,
                                                             gpointer user_data);
    void                fm_job_cancel                       (FmJob *job);
    FmJobErrorAction    fm_job_emit_error                   (FmJob *job,
                                                             GError *err,
                                                             FmJobErrorSeverity severity);
    void                fm_job_finish                       (FmJob *job);
    GCancellable *      fm_job_get_cancellable              (FmJob *job);
    void                fm_job_init_cancellable             (FmJob *job);
    gboolean            fm_job_is_cancelled                 (FmJob *job);
    gboolean            fm_job_is_running                   (FmJob *job);
    gboolean            fm_job_pause                        (FmJob *job);
    void                fm_job_resume                       (FmJob *job);
    gboolean            fm_job_run_async                    (FmJob *job);
    gboolean            fm_job_run_sync                     (FmJob *job);
    gboolean            fm_job_run_sync_with_mainloop       (FmJob *job);
    void                fm_job_set_cancellable              (FmJob *job,
                                                             GCancellable *cancellable);

## Object Hierarchy

      GObject
       +----FmJob
             +----FmDeepCountJob
             +----FmDirListJob
             +----FmFileInfoJob
             +----FmFileOpsJob

## Signals

      "ask"                                            : Run Last
      "cancelled"                                      : Run First
      "error"                                          : Run Last
      "finished"                                       : Run First

## Description

`include`: libfm/fm.h

The FmJob can be used to create asynchronous jobs performing some time-consuming tasks in another worker thread. To run a FmJob in another thread you simply call `fm_job_run_async()`, and then the task will be done in another worker thread. Later, when the job is finished, "finished" signal is emitted. When the job is still running, it's possible to cancel it from main thread by calling `fm_job_cancel()`. Then, "cancelled" signal will be emitted before emitting "finished" signal. You can also run the job in blocking fashion instead of running it asynchronously by calling `fm_job_run_sync()`.

## Details

### struct FmJob

    struct FmJob;

### FmJobCallMainThreadFunc ()

    gpointer            (*FmJobCallMainThreadFunc)          (FmJob *job,
                                                             gpointer user_data);

### struct FmJobClass

    struct FmJobClass {
        GObjectClass parent_class;

        /* the class closures for signals */
        void (*finished)(FmJob* job);
        guint (*error)(FmJob* job, GError* err, guint severity);
                    /* guint above are: FmJobErrorAction and FmJobErrorSeverity */
        void (*cancelled)(FmJob* job);
        gint (*ask)(FmJob* job, const gchar* question, gchar* const *options);

        /* routines used by methods */
        gboolean (*run_async)(FmJob* job); /* for fm_job_run_async() */
        gboolean (*run)(FmJob* job); /* for any fm_job_run_*() */
        void (*cancel)(FmJob* job); /* for fm_job_cancel() */
    };

GObjectClass `parent_class`; | the parent class
`finished` () | the class closure for the "finished" signal.
`error` () | the class closure for the "error" signal.
`cancelled` () | the class closure for the "cancelled" signal.
`ask` () | the class closure for the "ask" signal.
`run_async` () | the `run_async` function called to create a thread for the job execution. Returns `TRUE` if thread was created successfully. The most probably should be not overridden by any derived class.
`run` () | the `run` function is called to perform actual job actions. Returns value that will be returned from call `fm_job_run_sync()`. Should be set by any class derived from FmJob.
`cancel` () | the `cancel` function is called when the job is cancelled. It can perform some class-specific operations then.

### enum FmJobErrorAction

    typedef enum {
        FM_JOB_CONTINUE,
        FM_JOB_RETRY,
        FM_JOB_ABORT
    } FmJobErrorAction;

The action that should be performed after error happened. Usually chosen by user.

`FM_JOB_CONTINUE` | ignore the error and continue remaining work
`FM_JOB_RETRY` | retry the previously failed operation. (not every kind of job support this)
`FM_JOB_ABORT` | abort the whole job

### enum FmJobErrorSeverity

    typedef enum {
        FM_JOB_ERROR_WARNING,
        FM_JOB_ERROR_MILD,
        FM_JOB_ERROR_MODERATE,
        FM_JOB_ERROR_SEVERE,
        FM_JOB_ERROR_CRITICAL
    } FmJobErrorSeverity;

`FM_JOB_ERROR_WARNING` | not an error, just a warning
`FM_JOB_ERROR_MILD` | no big deal, can be ignored most of the time
`FM_JOB_ERROR_MODERATE` | moderate errors
`FM_JOB_ERROR_SEVERE` | severe errors, whether to abort operation depends on error handlers
`FM_JOB_ERROR_CRITICAL` | critical errors, the operation is aborted

### fm_job_ask ()

    gint                fm_job_ask                          (FmJob *job,
                                                             const char *question,
                                                             ...);

Asks the user for some interactions. The user will have a list of available options and should make a choice.

This APIs is private to FmJob and should only be used in the implementation of classes derived from FmJob.

This function should be called from working thread only.

`job` : | the job that calls main thread
`question` : | the text to ask the user
`...` : | list of choices to give the user
Returns : | user's choice.

Since 0.1.0

### fm_job_ask_valist ()

    gint                fm_job_ask_valist                   (FmJob *job,
                                                             const char *question,
                                                             va_list options);

Asks the user for some interactions. The user will have a list of available options and should make a choice.

This APIs is private to FmJob and should only be used in the implementation of classes derived from FmJob.

This function should be called from working thread only.

`job` : | the job that calls main thread
`question` : | the text to ask the user
`options` : | list of choices to give the user
Returns : | user's choice.

Since 0.1.0

### fm_job_askv ()

    gint                fm_job_askv                         (FmJob *job,
                                                             const char *question,
                                                             gchar * const *options);

Asks the user for some interactions. The user will have a list of available options and should make a choice.

This APIs is private to FmJob and should only be used in the implementation of classes derived from FmJob.

This function should be called from working thread only.

`job` : | the job that calls main thread
`question` : | the text to ask the user
`options` : | list of choices to give the user
Returns : | user's choice.

Since 0.1.0

### fm_job_call_main_thread ()

    gpointer            fm_job_call_main_thread             (FmJob *job,
                                                             FmJobCallMainThreadFunc func,
                                                             gpointer user_data);

Stops calling thread, waits main thread for idle, passes `user_data` to callback `func` in main thread, gathers result of callback, and returns it to caller.

This APIs is private to FmJob and should only be used in the implementation of classes derived from FmJob.

This function should be called from working thread only.

`job` : | the job that calls main thread
`func` : | callback to run from main thread
`user_data` : | user data for the callback
Returns : | return value from running `func`.

Since 0.1.0

### fm_job_cancel ()

    void                fm_job_cancel                       (FmJob *job);

Cancels the `job`.

`job` : | a job to cancel

Since 0.1.0

### fm_job_emit_error ()

    FmJobErrorAction    fm_job_emit_error                   (FmJob *job,
                                                             GError *err,
                                                             FmJobErrorSeverity severity);

Emits an "error" signal in the main thread to notify it when an error occurs. The return value of this function is the return value returned by the connected signal handlers. If `severity` is FM_JOB_ERROR_CRITICAL, the returned value is ignored and `fm_job_cancel()` is called to abort the job. Otherwise, the signal handler of this error can return FM_JOB_RETRY to ask for retrying the failed operation, return FM_JOB_CONTINUE to ignore the error and continue the remaining job, or return FM_JOB_ABORT to abort the job. If FM_JOB_ABORT is returned by the signal handler, `fm_job_cancel()` will be called in `fm_job_emit_error()`.

This APIs is private to FmJob and should only be used in the implementation of classes derived from FmJob.

This function should be called from working thread only.

`job` : | a job that emitted the signal
`err` : | an error descriptor
`severity` : | severity of the error
Returns : | action that should be performed on that error.

Since 0.1.0

### fm_job_finish ()

    void                fm_job_finish                       (FmJob *job);

Schedules the finishing of job. Once this function is called the `job` becomes invalid for the caller and should be not used anymore.

This APIs is private to FmJob and should only be used in the implementation of classes derived from FmJob.

This function should be called from working thread only.

`job` : | the job that was finished

Since 0.1.0

### fm_job_get_cancellable ()

    GCancellable *      fm_job_get_cancellable              (FmJob *job);

Get an existing GCancellable object from `job` for use with gio in another job by calling `fm_job_set_cancellable()`. This can be used when you wish to share a cancellable object among different jobs.

This APIs is private to FmJob and should only be used in the implementation of classes derived from FmJob.

`job` : | the job to inspect
Returns : | a GCancellable object if it was initialized for `job`.

Since 0.1.9

### fm_job_init_cancellable ()

    void                fm_job_init_cancellable             (FmJob *job);

Used by derived classes to implement FmJobClass:`run()` using gio inside. This API tries to initialize a GCancellable object for use with gio and should only be called once in the constructor of derived classes which require the use of GCancellable.

This APIs is private to FmJob and should only be used in the implementation of classes derived from FmJob.

`job` : | the job to init

Since 0.1.0

### fm_job_is_cancelled ()

    gboolean            fm_job_is_cancelled                 (FmJob *job);

Checks if the job is already cancelled.

`job` : | the job to inspect
Returns : | `TRUE` if the job is already cancelled.

Since 0.1.9

### fm_job_is_running ()

    gboolean            fm_job_is_running                   (FmJob *job);

Checks if the job is still running.

`job` : | the job to inspect
Returns : | `TRUE` if the job is still running.

Since 0.1.9

### fm_job_pause ()

    gboolean            fm_job_pause                        (FmJob *job);

Locks execution of job until next call to `fm_job_resume()`. This call may be used from thread different from the thread where the job runs in. This call may be done again (but have no extra effect) from the same thread. Any other usage may lead to deadlock.

`job` : | a job to apply
Returns : | `FALSE` if job cannot be locked.

Since 1.2.0

### fm_job_resume ()

    void                fm_job_resume                       (FmJob *job);

Unlocks execution of `job` that was made by previous call to `fm_job_pause()`. This call may be used only from the same thread where previous `fm_job_pause()` was made. Any other usage may lead to deadlock.

`job` : | a job to apply

Since 1.2.0

### fm_job_run_async ()

    gboolean            fm_job_run_async                    (FmJob *job);

Starts the `job` asyncronously creating new thread. If job starts successfully then the "finished" signal will be emitted when `job` is either succeeded or was cancelled. If `job` could not be started then "cancelled" signal is emitted before return from this function.

`job` : | a job to run
Returns : | `TRUE` if job started successfully.

Since 0.1.0

### fm_job_run_sync ()

    gboolean            fm_job_run_sync                     (FmJob *job);

Runs the `job` in current thread in a blocking fashion. The job will emit either "cancelled" signal if job was cancelled or "finished" signal if it finished successfully.

`job` : | a job to run
Returns : | `TRUE` if `job` ran successfully.

Since 0.1.0

### fm_job_run_sync_with_mainloop ()

    gboolean            fm_job_run_sync_with_mainloop       (FmJob *job);

Runs the `job` in current thread in a blocking fashion and an additional mainloop being created to prevent blocking of user interface. If `job` started successfully then "finished" signal is emitted when `job` is either succeeded or was cancelled. Note: using this API from within GTK main loop will lead to deadlock therefore if it is a GTK application then caller should unlock GDK threads before calling this API and lock them back after return from it. This statement is valid for any GTK application that uses locks.

`job` : | a job to run
Returns : | `TRUE` if job started successfully.

Since 0.1.1

### fm_job_set_cancellable ()

    void                fm_job_set_cancellable              (FmJob *job,
                                                             GCancellable *cancellable);

Lets the job to use an existing `cancellable` object. This can be used when you wish to share a cancellable object among different jobs. This should only be called before the `job` is launched.

This APIs is private to FmJob and should only be used in the implementation of classes derived from FmJob.

`job` : | the job to set
`cancellable` : | a shared cancellable object. [allow-none]

Since 0.1.0

## Signal Details

### The `"ask"` signal

    gint                user_function                      (FmJob   *job,
                                                            gpointer question,
                                                            gpointer options,
                                                            gpointer user_data)      : Run Last

The "ask" signal is emitted when the job asks for some user interactions. The user then will have a list of available `options`. If there is more than one handler connected to the signal then only one of them will receive it.

`job` : | a job that emitted the signal
`question` : | (const gchar *) a question to ask user
`options` : | (gchar* const *) list of choices to ask user
`user_data` : | user data set when the signal handler was connected.
Returns : | user's choice.

Since 0.1.0

### The `"cancelled"` signal

    void                user_function                      (FmJob   *job,
                                                            gpointer user_data)      : Run First

The "cancelled" signal is emitted when the job is cancelled or aborted due to critical errors.

`job` : | a job that emitted the signal
`user_data` : | user data set when the signal handler was connected.

Since 0.1.0

### The `"error"` signal

    guint               user_function                      (FmJob   *job,
                                                            GError  *error,
                                                            guint    severity,
                                                            gpointer user_data)      : Run Last

The "error" signal is emitted when errors happen. A case if more than one handler is connected to this signal is ambiguous.

`job` : | a job that emitted the signal
`error` : | an error descriptor
`severity` : | FmJobErrorSeverity of the error
`user_data` : | user data set when the signal handler was connected.
Returns : | FmJobErrorAction that should be performed on that error.

Since 0.1.0

### The `"finished"` signal

    void                user_function                      (FmJob   *job,
                                                            gpointer user_data)      : Run First

The "finished" signal is emitted after the job is finished. The signal is never emitted if the fm_job_run_XXX function returned `FALSE`, in that case the "cancelled" signal will be emitted instead.

`job` : | a job that emitted the signal
`user_data` : | user data set when the signal handler was connected.

Since 0.1.0