GdaThreadWrapper

GdaThreadWrapper — Execute functions in a sub thread

Synopsis

#include <libgda/thread-wrapper/gda-thread-wrapper.h>

                    GdaThreadWrapper;
GdaThreadWrapper *  gda_thread_wrapper_new              (void);
gpointer            (*GdaThreadWrapperFunc)             (gpointer arg,
                                                         GError **error);
guint               gda_thread_wrapper_execute          (GdaThreadWrapper *wrapper,
                                                         GdaThreadWrapperFunc func,
                                                         gpointer arg,
                                                         GDestroyNotify arg_destroy_func,
                                                         GError **error);
void                (*GdaThreadWrapperVoidFunc)         (gpointer arg,
                                                         GError **error);
guint               gda_thread_wrapper_execute_void     (GdaThreadWrapper *wrapper,
                                                         GdaThreadWrapperVoidFunc func,
                                                         gpointer arg,
                                                         GDestroyNotify arg_destroy_func,
                                                         GError **error);
gboolean            gda_thread_wrapper_cancel           (GdaThreadWrapper *wrapper,
                                                         guint id);
void                gda_thread_wrapper_iterate          (GdaThreadWrapper *wrapper,
                                                         gboolean may_block);
gpointer            gda_thread_wrapper_fetch_result     (GdaThreadWrapper *wrapper,
                                                         gboolean may_lock,
                                                         guint exp_id,
                                                         GError **error);
gint                gda_thread_wrapper_get_waiting_size (GdaThreadWrapper *wrapper);
void                (*GdaThreadWrapperCallback)         (GdaThreadWrapper *wrapper,
                                                         gpointer instance,
                                                         const gchar *signame,
                                                         gint n_param_values,
                                                         const GValue *param_values,
                                                         gpointer gda_reserved,
                                                         gpointer data);
gulong              gda_thread_wrapper_connect_raw      (GdaThreadWrapper *wrapper,
                                                         gpointer instance,
                                                         const gchar *sig_name,
                                                         gboolean private_thread,
                                                         gboolean private_job,
                                                         GdaThreadWrapperCallback callback,
                                                         gpointer data);
void                gda_thread_wrapper_disconnect       (GdaThreadWrapper *wrapper,
                                                         gulong id);
void                gda_thread_wrapper_steal_signal     (GdaThreadWrapper *wrapper,
                                                         gulong id);

Object Hierarchy

  GObject
   +----GdaThreadWrapper

Description

The purpose of the GdaThreadWrapper object is to execute functions in an isolated sub thread. As the GdaThreadWrapper is thread safe, one is able to isolate some code's execution is a private worker thread, and make a non thread safe code thread safe.

The downside of this is that the actual execution of the code will be slower as it requires threads to be synchronized.

The GdaThreadWrapper implements its own locking mechanism and can safely be used from multiple threads at once without needing further locking.

Each thread using a GdaThreadWrapper object can use it as if it was the only user: the GdaThreadWrapper will simply dispatch all the execution requests to its private worker thread and report the execution's status only to the thread which made the request.

The user can also specify a callback function to be called when an object exmits a signal while being used by the worker thread, see the gda_thread_wrapper_connect_raw() method.

The following diagram illustrates the conceptual working of the GdaThreadWrapper object: here two user threads are represented (assigned a red and green colors), both using a single GdaThreadWrapper, so in this diagram, 3 threads are present. The communication between the threads are handled by some GAsyncQueue objects (in a transparent way for the user, presented here only for illustration purposes). The queue represented in yellow is where jobs are pushed by each user thread (step 1), and popped by the worker thread (step 2). Once the user thread has finished with a job, it stores the result along with the job and pushes it to the queue dedicated to the user thread (step 3) in this example the red queue (because the job was issued from the thread represented in red). The last step is when the user fetches the result (in its user thread), step 4.

If, when the worker thread is busy with a job, a signal is emitted, and if the user has set up a signal handler using gda_thread_wrapper_connect_raw(), then a "job as signal" is created by the worker thread and pushed to the user thread as illustrated at the bottom of the diagram.

GdaThreadWrapper's conceptual working

Details

GdaThreadWrapper

typedef struct _GdaThreadWrapper GdaThreadWrapper;


gda_thread_wrapper_new ()

GdaThreadWrapper *  gda_thread_wrapper_new              (void);

Creates a new GdaThreadWrapper object

Returns :

a new GdaThreadWrapper object, or NULL if threads are not supported/enabled

Since 4.2


GdaThreadWrapperFunc ()

gpointer            (*GdaThreadWrapperFunc)             (gpointer arg,
                                                         GError **error);

Specifies the type of function to be passed to gda_thread_wrapper_execute().

arg :

pointer to the data (which is the arg argument passed to gda_thread_wrapper_execute_void())

error :

a place to store errors

Returns :

a pointer to some data which will be returned by gda_thread_wrapper_fetch_result()

gda_thread_wrapper_execute ()

guint               gda_thread_wrapper_execute          (GdaThreadWrapper *wrapper,
                                                         GdaThreadWrapperFunc func,
                                                         gpointer arg,
                                                         GDestroyNotify arg_destroy_func,
                                                         GError **error);

Make wrapper execute the func function with the arg argument (along with a GError which is not error) in the sub thread managed by wrapper. To execute a function which does not return anything, use gda_thread_wrapper_execute_void().

This method returns immediately, and the caller then needs to use gda_thread_wrapper_fetch_result() to check if the execution has finished and get the result.

Once func's execution is finished, if it is not NULL, the arg_destroy_func destruction function is called on arg. This occurs in the thread calling gda_thread_wrapper_fetch_result().

wrapper :

a GdaThreadWrapper object

func :

the function to execute

arg :

argument to pass to func

arg_destroy_func :

function to be called when the execution has finished, to destroy arg

error :

a place to store errors, for errors occurring in this method, not errors occurring while func is executed, or NULL

Returns :

the job ID, or 0 if an error occurred

Since 4.2


GdaThreadWrapperVoidFunc ()

void                (*GdaThreadWrapperVoidFunc)         (gpointer arg,
                                                         GError **error);

Specifies the type of function to be passed to gda_thread_wrapper_execute_void().

arg :

a pointer to the data (which is the arg argument passed to gda_thread_wrapper_execute_void())

error :

a place to store errors

gda_thread_wrapper_execute_void ()

guint               gda_thread_wrapper_execute_void     (GdaThreadWrapper *wrapper,
                                                         GdaThreadWrapperVoidFunc func,
                                                         gpointer arg,
                                                         GDestroyNotify arg_destroy_func,
                                                         GError **error);

Make wrapper execute the func function with the arg argument (along with a GError which is not error) in the sub thread managed by wrapper. To execute a function which returns some pointer, use gda_thread_wrapper_execute().

This method returns immediately. Calling gda_thread_wrapper_fetch_result() is not necessary as func does not return any result. However, it may be necessary to call gda_thread_wrapper_iterate() to give wrapper a chance to execute the arg_destroy_func function if not NULL (note that gda_thread_wrapper_iterate() is called by gda_thread_wrapper_fetch_result() itself).

Once func's execution is finished, if it is not NULL, the arg_destroy_func destruction function is called on arg. This occurs in the thread calling gda_thread_wrapper_fetch_result().

wrapper :

a GdaThreadWrapper object

func :

the function to execute

arg :

argument to pass to func

arg_destroy_func :

function to be called when the execution has finished, to destroy arg

error :

a place to store errors, for errors occurring in this method, not errors occurring while func is executed, or NULL

Returns :

the job ID, or 0 if an error occurred

Since 4.2


gda_thread_wrapper_cancel ()

gboolean            gda_thread_wrapper_cancel           (GdaThreadWrapper *wrapper,
                                                         guint id);

Cancels a job not yet executed. This may fail for the following reasons:

  • the job id could not be found, either because it has already been treated or because it does not exist or because it was created in another thread

  • the job id is currently being treated by the worker thread

wrapper :

a GdaThreadWrapper object

id :

the ID of a job as returned by gda_thread_wrapper_execute() or gda_thread_wrapper_execute_void()

Returns :

TRUE if the job has been cancelled, or FALSE in any other case.

Since 4.2


gda_thread_wrapper_iterate ()

void                gda_thread_wrapper_iterate          (GdaThreadWrapper *wrapper,
                                                         gboolean may_block);

This method gives wrapper a chance to check if some functions to be executed have finished for the calling thread. It handles one function's execution result, and if may_block is TRUE, then it will block untill there is one (functions returning void are ignored).

wrapper :

a GdaThreadWrapper object

may_block :

whether the call may block

Since 4.2


gda_thread_wrapper_fetch_result ()

gpointer            gda_thread_wrapper_fetch_result     (GdaThreadWrapper *wrapper,
                                                         gboolean may_lock,
                                                         guint exp_id,
                                                         GError **error);

Use this method to check if the execution of a function is finished. The function's execution must have been requested using gda_thread_wrapper_execute().

wrapper :

a GdaThreadWrapper object

may_lock :

TRUE if this funct must lock the caller untill a result is available

exp_id :

ID of the job for which a result is expected

error :

a place to store errors, for errors which may have occurred during the execution, or NULL

Returns :

the pointer returned by the execution, or NULL if no result is available. [transfer none][allow-none]

Since 4.2


gda_thread_wrapper_get_waiting_size ()

gint                gda_thread_wrapper_get_waiting_size (GdaThreadWrapper *wrapper);

Use this method to query the number of functions which have been queued to be executed but which have not yet been executed.

wrapper :

a GdaThreadWrapper object

Returns :

the number of jobs not yet executed

Since 4.2


GdaThreadWrapperCallback ()

void                (*GdaThreadWrapperCallback)         (GdaThreadWrapper *wrapper,
                                                         gpointer instance,
                                                         const gchar *signame,
                                                         gint n_param_values,
                                                         const GValue *param_values,
                                                         gpointer gda_reserved,
                                                         gpointer data);

Specifies the type of function to be passed to gda_thread_wrapper_connect_raw().

wrapper :

the GdaThreadWrapper

instance :

a pointer to the instance which emitted the signal

signame :

the name of the signal being emitted

n_param_values :

number of GValue in param_values

param_values :

array of n_param_values GValue

gda_reserved :

reserved

data :

a pointer to the data (which is the data argument passed to gda_thread_wrapper_connect_raw())

gda_thread_wrapper_connect_raw ()

gulong              gda_thread_wrapper_connect_raw      (GdaThreadWrapper *wrapper,
                                                         gpointer instance,
                                                         const gchar *sig_name,
                                                         gboolean private_thread,
                                                         gboolean private_job,
                                                         GdaThreadWrapperCallback callback,
                                                         gpointer data);

Connects a callback function to a signal for a particular object. The difference with g_signal_connect() and similar functions are:

  • the callback argument is not a GCallback function, so the callback signature is not dependent on the signal itself

  • the signal handler must not have to return any value

  • the callback function will be called asynchronously, the caller may need to use gda_thread_wrapper_iterate() to get the notification

  • if private is set to TRUE, then the callback function will be called only if the signal has been emitted by instance while doing a job on behalf of the current calling thread. If private is set to FALSE, then callback will be called whenever instance emits the sig_name signal.

Also note that signal handling is done asynchronously: when emitted in the worker thread, it will be "queued" to be processed in the user thread when it has the chance (when gda_thread_wrapper() is called directly or indirectly). The side effect is that the callback function is usually called long after the object emitting the signal has finished emitting it.

To disconnect a signal handler, don't use any of the g_signal_handler_*() functions but the gda_thread_wrapper_disconnect() method.

wrapper :

a GdaThreadWrapper object

instance :

the instance to connect to

sig_name :

a string of the form "signal-name::detail"

private_thread :

set to TRUE if callback is to be invoked only if the signal has been emitted while in wrapper's private sub thread (ie. used when wrapper is executing some functions specified by gda_thread_wrapper_execute() or gda_thread_wrapper_execute_void()), and to FALSE if the callback is to be invoked whenever the signal is emitted, independently of th thread in which the signal is emitted.

private_job :

set to TRUE if callback is to be invoked only if the signal has been emitted when a job created for the calling thread is being executed, and to FALSE if callback has to be called whenever the sig_name signal is emitted by instance. Note that this argument is not taken into account if private_thread is set to FALSE.

callback :

a GdaThreadWrapperCallback function. [scope call]

data :

data to pass to callback's calls. [closure]

Returns :

the handler ID

Since 4.2


gda_thread_wrapper_disconnect ()

void                gda_thread_wrapper_disconnect       (GdaThreadWrapper *wrapper,
                                                         gulong id);

Disconnects the emission of a signal, does the opposite of gda_thread_wrapper_connect_raw().

As soon as this method returns, the callback function set when gda_thread_wrapper_connect_raw() was called will not be called anymore (even if the object has emitted the signal in the worker thread and this signal has not been handled in the user thread).

wrapper :

a GdaThreadWrapper object

id :

a handler ID, as returned by gda_thread_wrapper_connect_raw()

Since 4.2


gda_thread_wrapper_steal_signal ()

void                gda_thread_wrapper_steal_signal     (GdaThreadWrapper *wrapper,
                                                         gulong id);

Requests that the signal which ID is id (which has been obtained using gda_thread_wrapper_connect_raw()) be treated by the calling thread instead of by the thread in which gda_thread_wrapper_connect_raw() was called.

wrapper :

a GdaThreadWrapper object

id :

a signal ID

Since 4.2