Add functions to allow threadsafe handling of idles and timeouts wrt. to
2006-12-22 Matthias Clasen <mclasen@redhat.com> * gdk/gdk.symbols: * gdk/gdk.h: * gdk/gdk.c: Add functions to allow threadsafe handling of idles and timeouts wrt. to the GDK lock. (#321886, Chris Wilson)
This commit is contained in:
committed by
Matthias Clasen
parent
1bed6b434c
commit
7854bd1b6e
@@ -1,3 +1,11 @@
|
|||||||
|
2006-12-22 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
* gdk/gdk.symbols:
|
||||||
|
* gdk/gdk.h:
|
||||||
|
* gdk/gdk.c: Add functions to allow threadsafe handling
|
||||||
|
of idles and timeouts wrt. to the GDK lock. (#321886,
|
||||||
|
Chris Wilson)
|
||||||
|
|
||||||
2006-12-22 Matthias Clasen <mclasen@redhat.com>
|
2006-12-22 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gdk/gdkpango.c: Use pango_cairo_show_error_underline.
|
* gdk/gdkpango.c: Use pango_cairo_show_error_underline.
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
2006-12-22 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
* gdk/gdk-sections.txt: Add new functions.
|
||||||
|
* gdk/gdk-docs.sgml: Add a "Since 2.12" index.
|
||||||
|
|
||||||
Thu Dec 14 15:48:14 2006 Tim Janik <timj@imendio.com>
|
Thu Dec 14 15:48:14 2006 Tim Janik <timj@imendio.com>
|
||||||
|
|
||||||
* gtk/gtk-sections.txt: added new docs.
|
* gtk/gtk-sections.txt: added new docs.
|
||||||
|
|||||||
@@ -107,5 +107,8 @@
|
|||||||
<index role="2.10">
|
<index role="2.10">
|
||||||
<title>Index of new symbols in 2.10</title>
|
<title>Index of new symbols in 2.10</title>
|
||||||
</index>
|
</index>
|
||||||
|
<index role="2.12">
|
||||||
|
<title>Index of new symbols in 2.12</title>
|
||||||
|
</index>
|
||||||
|
|
||||||
</book>
|
</book>
|
||||||
|
|||||||
@@ -953,6 +953,10 @@ gdk_threads_enter
|
|||||||
gdk_threads_leave
|
gdk_threads_leave
|
||||||
gdk_threads_mutex
|
gdk_threads_mutex
|
||||||
gdk_threads_set_lock_functions
|
gdk_threads_set_lock_functions
|
||||||
|
gdk_threads_add_idle
|
||||||
|
gdk_threads_add_idle_full
|
||||||
|
gdk_threads_add_timeout
|
||||||
|
gdk_threads_add_timeout_full
|
||||||
|
|
||||||
<SUBSECTION Private>
|
<SUBSECTION Private>
|
||||||
gdk_threads_lock
|
gdk_threads_lock
|
||||||
|
|||||||
235
gdk/gdk.c
235
gdk/gdk.c
@@ -46,6 +46,16 @@ struct _GdkPredicate
|
|||||||
gpointer data;
|
gpointer data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _GdkThreadsDispatch GdkThreadsDispatch;
|
||||||
|
|
||||||
|
struct _GdkThreadsDispatch
|
||||||
|
{
|
||||||
|
GSourceFunc func;
|
||||||
|
gpointer data;
|
||||||
|
GDestroyNotify destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Private variable declarations
|
/* Private variable declarations
|
||||||
*/
|
*/
|
||||||
static int gdk_initialized = 0; /* 1 if the library is initialized,
|
static int gdk_initialized = 0; /* 1 if the library is initialized,
|
||||||
@@ -448,6 +458,231 @@ gdk_threads_set_lock_functions (GCallback enter_fn,
|
|||||||
gdk_threads_unlock = leave_fn;
|
gdk_threads_unlock = leave_fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdk_threads_dispatch (gpointer data)
|
||||||
|
{
|
||||||
|
GdkThreadsDispatch *dispatch = data;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
GDK_THREADS_ENTER ();
|
||||||
|
|
||||||
|
if (!g_source_is_destroyed (g_main_current_source ()))
|
||||||
|
ret = dispatch->func (dispatch->data);
|
||||||
|
|
||||||
|
GDK_THREADS_LEAVE ();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_threads_dispatch_free (gpointer data)
|
||||||
|
{
|
||||||
|
GdkThreadsDispatch *dispatch = data;
|
||||||
|
|
||||||
|
if (dispatch->destroy && dispatch->data)
|
||||||
|
dispatch->destroy (dispatch->data);
|
||||||
|
|
||||||
|
g_slice_free (GdkThreadsDispatch, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_threads_add_idle_full:
|
||||||
|
* @priority: the priority of the idle source. Typically this will be in the
|
||||||
|
* range btweeen #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE
|
||||||
|
* @function: function to call
|
||||||
|
* @data: data to pass to @function
|
||||||
|
* @notify: function to call when the idle is removed, or %NULL
|
||||||
|
*
|
||||||
|
* Adds a function to be called whenever there are no higher priority
|
||||||
|
* events pending. If the function returns %FALSE it is automatically
|
||||||
|
* removed from the list of event sources and will not be called again.
|
||||||
|
*
|
||||||
|
* This variant of g_idle_add_full() calls @function with the GDK lock
|
||||||
|
* held. It can be thought of a MT-safe version for GTK+ widgets for the
|
||||||
|
* following use case, where you have to worry about idle_callback()
|
||||||
|
* running in thread A and accessing @self after it has been finalized
|
||||||
|
* in thread B:
|
||||||
|
*
|
||||||
|
* <informalexample><programlisting>
|
||||||
|
* static gboolean idle_callback (gpointer data)
|
||||||
|
* {
|
||||||
|
* SomeWidget *self = data;
|
||||||
|
*
|
||||||
|
* /<!-- -->* do stuff with self *<!-- -->/
|
||||||
|
*
|
||||||
|
* self->idle_id = 0;
|
||||||
|
*
|
||||||
|
* return FALSE;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* static void some_widget_do_stuff_later (SomeWidget *self)
|
||||||
|
* {
|
||||||
|
* self->idle_id = g_idle_add (idle_callback, self)
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* static void some_widget_finalize (GObject *object)
|
||||||
|
* {
|
||||||
|
* SomeWidget *self = SOME_WIDGET(object);
|
||||||
|
*
|
||||||
|
* if (self->idle_id)
|
||||||
|
* g_source_remove (self->idle_id);
|
||||||
|
*
|
||||||
|
* G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
|
* }
|
||||||
|
* </programlisting></informalexample>
|
||||||
|
*
|
||||||
|
* Return value: the ID (greater than 0) of the event source.
|
||||||
|
*
|
||||||
|
* Since: 2.12
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
gdk_threads_add_idle_full (gint priority,
|
||||||
|
GSourceFunc function,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
GdkThreadsDispatch *dispatch;
|
||||||
|
|
||||||
|
g_return_val_if_fail (function != NULL, 0);
|
||||||
|
|
||||||
|
dispatch = g_slice_new (GdkThreadsDispatch);
|
||||||
|
dispatch->func = function;
|
||||||
|
dispatch->data = data;
|
||||||
|
dispatch->destroy = notify;
|
||||||
|
|
||||||
|
return g_idle_add_full (priority,
|
||||||
|
gdk_threads_dispatch,
|
||||||
|
dispatch,
|
||||||
|
gdk_threads_dispatch_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_threads_add_idle:
|
||||||
|
* @function: function to call
|
||||||
|
* @data: data to pass to @function
|
||||||
|
*
|
||||||
|
* A wrapper for the common usage of gdk_threads_add_idle_full()
|
||||||
|
* assigning the default priority, #G_PRIORITY_DEFAULT_IDLE.
|
||||||
|
*
|
||||||
|
* See gdk_threads_add_idle_full().
|
||||||
|
*
|
||||||
|
* Since: 2.12
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
gdk_threads_add_idle (GSourceFunc function,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
return gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE,
|
||||||
|
function, data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_threads_add_timeout_full:
|
||||||
|
* @priority: the priority of the timeout source. Typically this will be in the
|
||||||
|
* range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
|
||||||
|
* @interval: the time between calls to the function, in milliseconds
|
||||||
|
* (1/1000ths of a second)
|
||||||
|
* @function: function to call
|
||||||
|
* @data: data to pass to @function
|
||||||
|
* @notify: function to call when the timeout is removed, or %NULL
|
||||||
|
*
|
||||||
|
* Sets a function to be called at regular intervals holding the GDK lock,
|
||||||
|
* with the given priority. The function is called repeatedly until it
|
||||||
|
* returns %FALSE, at which point the timeout is automatically destroyed
|
||||||
|
* and the function will not be called again. The @notify function is
|
||||||
|
* called when the timeout is destroyed. The first call to the
|
||||||
|
* function will be at the end of the first @interval.
|
||||||
|
*
|
||||||
|
* Note that timeout functions may be delayed, due to the processing of other
|
||||||
|
* event sources. Thus they should not be relied on for precise timing.
|
||||||
|
* After each call to the timeout function, the time of the next
|
||||||
|
* timeout is recalculated based on the current time and the given interval
|
||||||
|
* (it does not try to 'catch up' time lost in delays).
|
||||||
|
*
|
||||||
|
* This variant of g_timeout_add_full() can be thought of a MT-safe version
|
||||||
|
* for GTK+ widgets for the following use case:
|
||||||
|
*
|
||||||
|
* <example>
|
||||||
|
* static gboolean timeout_callback (gpointer data)
|
||||||
|
* {
|
||||||
|
* SomeWidget *self = data;
|
||||||
|
*
|
||||||
|
* /<!-- -->* do stuff with self *<!-- -->/
|
||||||
|
*
|
||||||
|
* self->timeout_id = 0;
|
||||||
|
*
|
||||||
|
* return FALSE;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* static void some_widget_do_stuff_later (SomeWidget *self)
|
||||||
|
* {
|
||||||
|
* self->timeout_id = g_timeout_add (timeout_callback, self)
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* static void some_widget_finalize (GObject *object)
|
||||||
|
* {
|
||||||
|
* SomeWidget *self = SOME_WIDGET(object);
|
||||||
|
*
|
||||||
|
* if (self->timeout_id)
|
||||||
|
* g_source_remove (self->timeout_id);
|
||||||
|
*
|
||||||
|
* G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
|
* }
|
||||||
|
* </example>
|
||||||
|
*
|
||||||
|
* Return value: the ID (greater than 0) of the event source.
|
||||||
|
*
|
||||||
|
* Since: 2.12
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
gdk_threads_add_timeout_full (gint priority,
|
||||||
|
guint interval,
|
||||||
|
GSourceFunc function,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
GdkThreadsDispatch *dispatch;
|
||||||
|
|
||||||
|
g_return_val_if_fail (function != NULL, 0);
|
||||||
|
|
||||||
|
dispatch = g_slice_new (GdkThreadsDispatch);
|
||||||
|
dispatch->func = function;
|
||||||
|
dispatch->data = data;
|
||||||
|
dispatch->destroy = notify;
|
||||||
|
|
||||||
|
return g_timeout_add_full (priority,
|
||||||
|
interval,
|
||||||
|
gdk_threads_dispatch,
|
||||||
|
dispatch,
|
||||||
|
gdk_threads_dispatch_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_threads_add_timeout:
|
||||||
|
* @interval: the time between calls to the function, in milliseconds
|
||||||
|
* (1/1000ths of a second)
|
||||||
|
* @function: function to call
|
||||||
|
* @data: data to pass to @function
|
||||||
|
*
|
||||||
|
* A wrapper for the common usage of gdk_threads_add_timeout_full()
|
||||||
|
* assigning the default priority, #G_PRIORITY_DEFAULT.
|
||||||
|
*
|
||||||
|
* See gdk_threads_add_timeout_full().
|
||||||
|
*
|
||||||
|
* Since: 2.12
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
gdk_threads_add_timeout (guint interval,
|
||||||
|
GSourceFunc function,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
return gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT,
|
||||||
|
interval, function, data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
G_CONST_RETURN char *
|
G_CONST_RETURN char *
|
||||||
gdk_get_program_class (void)
|
gdk_get_program_class (void)
|
||||||
{
|
{
|
||||||
|
|||||||
16
gdk/gdk.h
16
gdk/gdk.h
@@ -193,6 +193,22 @@ void gdk_threads_init (void);
|
|||||||
void gdk_threads_set_lock_functions (GCallback enter_fn,
|
void gdk_threads_set_lock_functions (GCallback enter_fn,
|
||||||
GCallback leave_fn);
|
GCallback leave_fn);
|
||||||
|
|
||||||
|
guint gdk_threads_add_idle_full (gint priority,
|
||||||
|
GSourceFunc function,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
guint gdk_threads_add_idle (GSourceFunc function,
|
||||||
|
gpointer data);
|
||||||
|
guint gdk_threads_add_timeout_full (gint priority,
|
||||||
|
guint interval,
|
||||||
|
GSourceFunc function,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
guint gdk_threads_add_timeout (guint interval,
|
||||||
|
GSourceFunc function,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
|
||||||
#ifdef G_THREADS_ENABLED
|
#ifdef G_THREADS_ENABLED
|
||||||
# define GDK_THREADS_ENTER() G_STMT_START { \
|
# define GDK_THREADS_ENTER() G_STMT_START { \
|
||||||
if (gdk_threads_lock) \
|
if (gdk_threads_lock) \
|
||||||
|
|||||||
@@ -133,6 +133,10 @@ gdk_threads_enter
|
|||||||
gdk_threads_init
|
gdk_threads_init
|
||||||
gdk_threads_leave
|
gdk_threads_leave
|
||||||
gdk_threads_set_lock_functions
|
gdk_threads_set_lock_functions
|
||||||
|
gdk_threads_add_idle
|
||||||
|
gdk_threads_add_idle_full
|
||||||
|
gdk_threads_add_timeout
|
||||||
|
gdk_threads_add_timeout_full
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user