From 08425ac4c2fce32d96295e3fefe31f1ddcc17db0 Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Sun, 17 Jan 1999 04:49:43 +0000 Subject: [PATCH] incremented version number to 1.1.13, bin age 0, interface age 0. Sun Jan 17 05:12:17 1999 Tim Janik * configure.in: incremented version number to 1.1.13, bin age 0, interface age 0. * glib.h: added hook_destroy member to struct _GHookList. * ghook.c (g_hook_destroy_link): if the hook_list defines a hook_destroy function, use that to marshal hook destruction notifiers. * gmain.c: removed g_source_free_func and added g_source_destroy_func, which marshalls the user_data and source_data destructors of sources outside of the main_loop lock. removed GIdleData struct since its single member callback can be passed as source_data directly. added a gboolean return value to all g_source_remove* functions, indicating whether the source could be removed, because these functions don't issue warnings upon unseccessful removals themselves. this way at least the caller gets a chance to warn upon failing removals. (g_main_iterate): set in_check_or_prepare around calls to check() or prepare(). (g_main_pending): simply return FALSE if called from within check() or prepare(). (g_main_iteration): issue a warning if called from within check() or prepare() and bail out with FALSE. (g_main_run): likewise. (g_source_remove_by_funcs_user_data): new function to remove sources by user data and function table. (g_idle_remove_by_data): new function to really remove idles only, since g_source_remove_by_user_data would remove timeouts or other sources as well. --- ChangeLog | 32 ++++++++++ ChangeLog.pre-2-0 | 32 ++++++++++ ChangeLog.pre-2-10 | 32 ++++++++++ ChangeLog.pre-2-12 | 32 ++++++++++ ChangeLog.pre-2-2 | 32 ++++++++++ ChangeLog.pre-2-4 | 32 ++++++++++ ChangeLog.pre-2-6 | 32 ++++++++++ ChangeLog.pre-2-8 | 32 ++++++++++ configure.in | 2 +- ghook.c | 8 ++- glib.h | 22 ++++--- glib/ghook.c | 8 ++- glib/glib.h | 22 ++++--- glib/gmain.c | 173 ++++++++++++++++++++++++++++++++++++++--------------- gmain.c | 173 ++++++++++++++++++++++++++++++++++++++--------------- 15 files changed, 549 insertions(+), 115 deletions(-) diff --git a/ChangeLog b/ChangeLog index 88295e5..79482cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +Sun Jan 17 05:12:17 1999 Tim Janik + + * configure.in: incremented version number to 1.1.13, bin age 0, + interface age 0. + + * glib.h: added hook_destroy member to struct _GHookList. + + * ghook.c (g_hook_destroy_link): if the hook_list defines a hook_destroy + function, use that to marshal hook destruction notifiers. + + * gmain.c: removed g_source_free_func and added g_source_destroy_func, + which marshalls the user_data and source_data destructors of sources + outside of the main_loop lock. + removed GIdleData struct since its single member callback can be passed + as source_data directly. + added a gboolean return value to all g_source_remove* functions, + indicating whether the source could be removed, because these functions + don't issue warnings upon unseccessful removals themselves. this way at + least the caller gets a chance to warn upon failing removals. + (g_main_iterate): set in_check_or_prepare around calls to check() or + prepare(). + (g_main_pending): simply return FALSE if called from within check() or + prepare(). + (g_main_iteration): issue a warning if called from within check() or + prepare() and bail out with FALSE. + (g_main_run): likewise. + (g_source_remove_by_funcs_user_data): new function to remove sources by + user data and function table. + (g_idle_remove_by_data): new function to really remove idles only, since + g_source_remove_by_user_data would remove timeouts or other sources as + well. + 1999-01-16 Tor Lillqvist * Merge in current Win32 version: diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 88295e5..79482cd 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,35 @@ +Sun Jan 17 05:12:17 1999 Tim Janik + + * configure.in: incremented version number to 1.1.13, bin age 0, + interface age 0. + + * glib.h: added hook_destroy member to struct _GHookList. + + * ghook.c (g_hook_destroy_link): if the hook_list defines a hook_destroy + function, use that to marshal hook destruction notifiers. + + * gmain.c: removed g_source_free_func and added g_source_destroy_func, + which marshalls the user_data and source_data destructors of sources + outside of the main_loop lock. + removed GIdleData struct since its single member callback can be passed + as source_data directly. + added a gboolean return value to all g_source_remove* functions, + indicating whether the source could be removed, because these functions + don't issue warnings upon unseccessful removals themselves. this way at + least the caller gets a chance to warn upon failing removals. + (g_main_iterate): set in_check_or_prepare around calls to check() or + prepare(). + (g_main_pending): simply return FALSE if called from within check() or + prepare(). + (g_main_iteration): issue a warning if called from within check() or + prepare() and bail out with FALSE. + (g_main_run): likewise. + (g_source_remove_by_funcs_user_data): new function to remove sources by + user data and function table. + (g_idle_remove_by_data): new function to really remove idles only, since + g_source_remove_by_user_data would remove timeouts or other sources as + well. + 1999-01-16 Tor Lillqvist * Merge in current Win32 version: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 88295e5..79482cd 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,35 @@ +Sun Jan 17 05:12:17 1999 Tim Janik + + * configure.in: incremented version number to 1.1.13, bin age 0, + interface age 0. + + * glib.h: added hook_destroy member to struct _GHookList. + + * ghook.c (g_hook_destroy_link): if the hook_list defines a hook_destroy + function, use that to marshal hook destruction notifiers. + + * gmain.c: removed g_source_free_func and added g_source_destroy_func, + which marshalls the user_data and source_data destructors of sources + outside of the main_loop lock. + removed GIdleData struct since its single member callback can be passed + as source_data directly. + added a gboolean return value to all g_source_remove* functions, + indicating whether the source could be removed, because these functions + don't issue warnings upon unseccessful removals themselves. this way at + least the caller gets a chance to warn upon failing removals. + (g_main_iterate): set in_check_or_prepare around calls to check() or + prepare(). + (g_main_pending): simply return FALSE if called from within check() or + prepare(). + (g_main_iteration): issue a warning if called from within check() or + prepare() and bail out with FALSE. + (g_main_run): likewise. + (g_source_remove_by_funcs_user_data): new function to remove sources by + user data and function table. + (g_idle_remove_by_data): new function to really remove idles only, since + g_source_remove_by_user_data would remove timeouts or other sources as + well. + 1999-01-16 Tor Lillqvist * Merge in current Win32 version: diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 88295e5..79482cd 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,35 @@ +Sun Jan 17 05:12:17 1999 Tim Janik + + * configure.in: incremented version number to 1.1.13, bin age 0, + interface age 0. + + * glib.h: added hook_destroy member to struct _GHookList. + + * ghook.c (g_hook_destroy_link): if the hook_list defines a hook_destroy + function, use that to marshal hook destruction notifiers. + + * gmain.c: removed g_source_free_func and added g_source_destroy_func, + which marshalls the user_data and source_data destructors of sources + outside of the main_loop lock. + removed GIdleData struct since its single member callback can be passed + as source_data directly. + added a gboolean return value to all g_source_remove* functions, + indicating whether the source could be removed, because these functions + don't issue warnings upon unseccessful removals themselves. this way at + least the caller gets a chance to warn upon failing removals. + (g_main_iterate): set in_check_or_prepare around calls to check() or + prepare(). + (g_main_pending): simply return FALSE if called from within check() or + prepare(). + (g_main_iteration): issue a warning if called from within check() or + prepare() and bail out with FALSE. + (g_main_run): likewise. + (g_source_remove_by_funcs_user_data): new function to remove sources by + user data and function table. + (g_idle_remove_by_data): new function to really remove idles only, since + g_source_remove_by_user_data would remove timeouts or other sources as + well. + 1999-01-16 Tor Lillqvist * Merge in current Win32 version: diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 88295e5..79482cd 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,35 @@ +Sun Jan 17 05:12:17 1999 Tim Janik + + * configure.in: incremented version number to 1.1.13, bin age 0, + interface age 0. + + * glib.h: added hook_destroy member to struct _GHookList. + + * ghook.c (g_hook_destroy_link): if the hook_list defines a hook_destroy + function, use that to marshal hook destruction notifiers. + + * gmain.c: removed g_source_free_func and added g_source_destroy_func, + which marshalls the user_data and source_data destructors of sources + outside of the main_loop lock. + removed GIdleData struct since its single member callback can be passed + as source_data directly. + added a gboolean return value to all g_source_remove* functions, + indicating whether the source could be removed, because these functions + don't issue warnings upon unseccessful removals themselves. this way at + least the caller gets a chance to warn upon failing removals. + (g_main_iterate): set in_check_or_prepare around calls to check() or + prepare(). + (g_main_pending): simply return FALSE if called from within check() or + prepare(). + (g_main_iteration): issue a warning if called from within check() or + prepare() and bail out with FALSE. + (g_main_run): likewise. + (g_source_remove_by_funcs_user_data): new function to remove sources by + user data and function table. + (g_idle_remove_by_data): new function to really remove idles only, since + g_source_remove_by_user_data would remove timeouts or other sources as + well. + 1999-01-16 Tor Lillqvist * Merge in current Win32 version: diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 88295e5..79482cd 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,35 @@ +Sun Jan 17 05:12:17 1999 Tim Janik + + * configure.in: incremented version number to 1.1.13, bin age 0, + interface age 0. + + * glib.h: added hook_destroy member to struct _GHookList. + + * ghook.c (g_hook_destroy_link): if the hook_list defines a hook_destroy + function, use that to marshal hook destruction notifiers. + + * gmain.c: removed g_source_free_func and added g_source_destroy_func, + which marshalls the user_data and source_data destructors of sources + outside of the main_loop lock. + removed GIdleData struct since its single member callback can be passed + as source_data directly. + added a gboolean return value to all g_source_remove* functions, + indicating whether the source could be removed, because these functions + don't issue warnings upon unseccessful removals themselves. this way at + least the caller gets a chance to warn upon failing removals. + (g_main_iterate): set in_check_or_prepare around calls to check() or + prepare(). + (g_main_pending): simply return FALSE if called from within check() or + prepare(). + (g_main_iteration): issue a warning if called from within check() or + prepare() and bail out with FALSE. + (g_main_run): likewise. + (g_source_remove_by_funcs_user_data): new function to remove sources by + user data and function table. + (g_idle_remove_by_data): new function to really remove idles only, since + g_source_remove_by_user_data would remove timeouts or other sources as + well. + 1999-01-16 Tor Lillqvist * Merge in current Win32 version: diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 88295e5..79482cd 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,35 @@ +Sun Jan 17 05:12:17 1999 Tim Janik + + * configure.in: incremented version number to 1.1.13, bin age 0, + interface age 0. + + * glib.h: added hook_destroy member to struct _GHookList. + + * ghook.c (g_hook_destroy_link): if the hook_list defines a hook_destroy + function, use that to marshal hook destruction notifiers. + + * gmain.c: removed g_source_free_func and added g_source_destroy_func, + which marshalls the user_data and source_data destructors of sources + outside of the main_loop lock. + removed GIdleData struct since its single member callback can be passed + as source_data directly. + added a gboolean return value to all g_source_remove* functions, + indicating whether the source could be removed, because these functions + don't issue warnings upon unseccessful removals themselves. this way at + least the caller gets a chance to warn upon failing removals. + (g_main_iterate): set in_check_or_prepare around calls to check() or + prepare(). + (g_main_pending): simply return FALSE if called from within check() or + prepare(). + (g_main_iteration): issue a warning if called from within check() or + prepare() and bail out with FALSE. + (g_main_run): likewise. + (g_source_remove_by_funcs_user_data): new function to remove sources by + user data and function table. + (g_idle_remove_by_data): new function to really remove idles only, since + g_source_remove_by_user_data would remove timeouts or other sources as + well. + 1999-01-16 Tor Lillqvist * Merge in current Win32 version: diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 88295e5..79482cd 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,35 @@ +Sun Jan 17 05:12:17 1999 Tim Janik + + * configure.in: incremented version number to 1.1.13, bin age 0, + interface age 0. + + * glib.h: added hook_destroy member to struct _GHookList. + + * ghook.c (g_hook_destroy_link): if the hook_list defines a hook_destroy + function, use that to marshal hook destruction notifiers. + + * gmain.c: removed g_source_free_func and added g_source_destroy_func, + which marshalls the user_data and source_data destructors of sources + outside of the main_loop lock. + removed GIdleData struct since its single member callback can be passed + as source_data directly. + added a gboolean return value to all g_source_remove* functions, + indicating whether the source could be removed, because these functions + don't issue warnings upon unseccessful removals themselves. this way at + least the caller gets a chance to warn upon failing removals. + (g_main_iterate): set in_check_or_prepare around calls to check() or + prepare(). + (g_main_pending): simply return FALSE if called from within check() or + prepare(). + (g_main_iteration): issue a warning if called from within check() or + prepare() and bail out with FALSE. + (g_main_run): likewise. + (g_source_remove_by_funcs_user_data): new function to remove sources by + user data and function table. + (g_idle_remove_by_data): new function to really remove idles only, since + g_source_remove_by_user_data would remove timeouts or other sources as + well. + 1999-01-16 Tor Lillqvist * Merge in current Win32 version: diff --git a/configure.in b/configure.in index f678b23..9e345c1 100644 --- a/configure.in +++ b/configure.in @@ -26,7 +26,7 @@ rm -f glibconfig-sysdefs.h # GLIB_MAJOR_VERSION=1 GLIB_MINOR_VERSION=1 -GLIB_MICRO_VERSION=12 +GLIB_MICRO_VERSION=13 GLIB_INTERFACE_AGE=0 GLIB_BINARY_AGE=0 GLIB_VERSION=$GLIB_MAJOR_VERSION.$GLIB_MINOR_VERSION.$GLIB_MICRO_VERSION diff --git a/ghook.c b/ghook.c index 117aa35..89c7cfb 100644 --- a/ghook.c +++ b/ghook.c @@ -48,6 +48,7 @@ g_hook_list_init (GHookList *hook_list, hook_size * G_HOOKS_PREALLOC, G_ALLOC_AND_FREE); hook_list->hook_free = NULL; + hook_list->hook_destroy = NULL; } void @@ -129,7 +130,12 @@ g_hook_destroy_link (GHookList *hook_list, { hook->hook_id = 0; hook->flags &= ~G_HOOK_FLAG_ACTIVE; - if (hook->destroy) + if (hook_list->hook_destroy) + { + hook_list->hook_destroy (hook_list, hook); + hook->destroy = NULL; + } + else if (hook->destroy) { GDestroyNotify destroy; diff --git a/glib.h b/glib.h index 0bbafe1..6848d2b 100644 --- a/glib.h +++ b/glib.h @@ -1120,6 +1120,7 @@ struct _GHookList GHook *hooks; GMemChunk *hook_memchunk; GHookFreeFunc hook_free; /* virtual function */ + GHookFreeFunc hook_destroy; /* virtual function */ }; struct _GHook @@ -2402,15 +2403,17 @@ struct _GSourceFuncs typedef gboolean (*GSourceFunc) (gpointer data); /* Hooks for adding to the main loop */ -guint g_source_add (gint priority, - gboolean can_recurse, - GSourceFuncs *funcs, - gpointer source_data, - gpointer user_data, - GDestroyNotify notify); -void g_source_remove (guint tag); -void g_source_remove_by_user_data (gpointer user_data); -void g_source_remove_by_source_data (gpointer source_data); +guint g_source_add (gint priority, + gboolean can_recurse, + GSourceFuncs *funcs, + gpointer source_data, + gpointer user_data, + GDestroyNotify notify); +gboolean g_source_remove (guint tag); +gboolean g_source_remove_by_user_data (gpointer user_data); +gboolean g_source_remove_by_source_data (gpointer source_data); +gboolean g_source_remove_by_funcs_user_data (GSourceFuncs *funcs, + gpointer user_data); void g_get_current_time (GTimeVal *result); @@ -2444,6 +2447,7 @@ guint g_idle_add_full (gint priority, GSourceFunc function, gpointer data, GDestroyNotify destroy); +gboolean g_idle_remove_by_data (gpointer data); /* GPollFD * diff --git a/glib/ghook.c b/glib/ghook.c index 117aa35..89c7cfb 100644 --- a/glib/ghook.c +++ b/glib/ghook.c @@ -48,6 +48,7 @@ g_hook_list_init (GHookList *hook_list, hook_size * G_HOOKS_PREALLOC, G_ALLOC_AND_FREE); hook_list->hook_free = NULL; + hook_list->hook_destroy = NULL; } void @@ -129,7 +130,12 @@ g_hook_destroy_link (GHookList *hook_list, { hook->hook_id = 0; hook->flags &= ~G_HOOK_FLAG_ACTIVE; - if (hook->destroy) + if (hook_list->hook_destroy) + { + hook_list->hook_destroy (hook_list, hook); + hook->destroy = NULL; + } + else if (hook->destroy) { GDestroyNotify destroy; diff --git a/glib/glib.h b/glib/glib.h index 0bbafe1..6848d2b 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -1120,6 +1120,7 @@ struct _GHookList GHook *hooks; GMemChunk *hook_memchunk; GHookFreeFunc hook_free; /* virtual function */ + GHookFreeFunc hook_destroy; /* virtual function */ }; struct _GHook @@ -2402,15 +2403,17 @@ struct _GSourceFuncs typedef gboolean (*GSourceFunc) (gpointer data); /* Hooks for adding to the main loop */ -guint g_source_add (gint priority, - gboolean can_recurse, - GSourceFuncs *funcs, - gpointer source_data, - gpointer user_data, - GDestroyNotify notify); -void g_source_remove (guint tag); -void g_source_remove_by_user_data (gpointer user_data); -void g_source_remove_by_source_data (gpointer source_data); +guint g_source_add (gint priority, + gboolean can_recurse, + GSourceFuncs *funcs, + gpointer source_data, + gpointer user_data, + GDestroyNotify notify); +gboolean g_source_remove (guint tag); +gboolean g_source_remove_by_user_data (gpointer user_data); +gboolean g_source_remove_by_source_data (gpointer source_data); +gboolean g_source_remove_by_funcs_user_data (GSourceFuncs *funcs, + gpointer user_data); void g_get_current_time (GTimeVal *result); @@ -2444,6 +2447,7 @@ guint g_idle_add_full (gint priority, GSourceFunc function, gpointer data, GDestroyNotify destroy); +gboolean g_idle_remove_by_data (gpointer data); /* GPollFD * diff --git a/glib/gmain.c b/glib/gmain.c index 7e3571b..9da4fa0 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -31,30 +31,29 @@ #include #ifdef HAVE_SYS_TIME_H #include -#endif -#ifdef GLIB_HAVE_SYS_POLL_H +#endif /* HAVE_SYS_TIME_H */ +#ifdef GLIB_HAVE_SYS_POLL_H # include # undef events /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */ # undef revents /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */ -#endif /* GLIB_HAVE_SYS_POLL_H */ +#endif /* GLIB_HAVE_SYS_POLL_H */ #ifdef HAVE_UNISTD_H #include -#endif +#endif /* HAVE_UNISTD_H */ #include #ifdef NATIVE_WIN32 #define STRICT #include -#endif +#endif /* NATIVE_WIN32 */ #ifdef _MSC_VER #include #include -#endif +#endif /* _MSC_VER */ /* Types */ -typedef struct _GIdleData GIdleData; typedef struct _GTimeoutData GTimeoutData; typedef struct _GSource GSource; typedef struct _GPollRec GPollRec; @@ -77,11 +76,6 @@ struct _GMainLoop gboolean is_running; }; -struct _GIdleData -{ - GSourceFunc callback; -}; - struct _GTimeoutData { GTimeVal expiration; @@ -100,7 +94,7 @@ struct _GPollRec static gint g_source_compare (GHook *a, GHook *b); -static void g_source_free_func (GHookList *hook_list, +static void g_source_destroy_func (GHookList *hook_list, GHook *hook); static void g_main_poll (gint timeout, gboolean use_priority, @@ -129,24 +123,27 @@ static gboolean g_idle_dispatch (gpointer source_data, static GSList *pending_dispatches = NULL; static GHookList source_list = { 0 }; +static gint in_check_or_prepare = 0; /* The following lock is used for both the list of sources * and the list of poll records */ G_LOCK_DECLARE_STATIC (main_loop); -static GSourceFuncs timeout_funcs = { +static GSourceFuncs timeout_funcs = +{ g_timeout_prepare, g_timeout_check, g_timeout_dispatch, - (GDestroyNotify)g_free + g_free, }; -static GSourceFuncs idle_funcs = { +static GSourceFuncs idle_funcs = +{ g_idle_prepare, g_idle_check, g_idle_dispatch, - (GDestroyNotify)g_free + NULL, }; static GPollRec *poll_records = NULL; @@ -159,12 +156,12 @@ static guint n_poll_records = 0; /* this pipe is used to wake up the main loop when a source is added. */ static gint wake_up_pipe[2] = { -1, -1 }; -#else +#else /* NATIVE_WIN32 */ static HANDLE wake_up_semaphore = NULL; -#endif +#endif /* NATIVE_WIN32 */ static GPollFD wake_up_rec; static gboolean poll_waiting = FALSE; -#endif +#endif /* G_THREADS_ENABLED */ #ifdef HAVE_POLL static GPollFunc poll_func = (GPollFunc) poll; @@ -321,19 +318,21 @@ g_poll (GPollFD *fds, guint nfds, gint timeout) #ifndef NO_FD_SET # define SELECT_MASK fd_set -#else /* !NO_FD_SET */ +#else /* !NO_FD_SET */ # ifndef _AIX typedef long fd_mask; -# endif -# if defined(_IBMR2) +# endif /* _AIX */ +# ifdef _IBMR2 # define SELECT_MASK void -# else +# else /* !_IBMR2 */ # define SELECT_MASK int -# endif -#endif /* !NO_FD_SET */ +# endif /* !_IBMR2 */ +#endif /* !NO_FD_SET */ static gint -g_poll (GPollFD *fds, guint nfds, gint timeout) +g_poll (GPollFD *fds, + guint nfds, + gint timeout) { struct timeval tv; SELECT_MASK rset, wset, xset; @@ -380,6 +379,7 @@ g_poll (GPollFD *fds, guint nfds, gint timeout) return ready; } + #endif /* !NATIVE_WIN32 */ static GPollFunc poll_func = g_poll; @@ -400,13 +400,25 @@ g_source_compare (GHook *a, return (source_a->priority < source_b->priority) ? -1 : 1; } +/* HOLDS: main_loop_lock */ static void -g_source_free_func (GHookList *hook_list, - GHook *hook) +g_source_destroy_func (GHookList *hook_list, + GHook *hook) { - GSource *source = (GSource *)hook; + GSource *source = (GSource*) hook; + GDestroyNotify destroy; - ((GSourceFuncs *) hook->func)->destroy (source->source_data); + G_UNLOCK (main_loop); + + destroy = hook->destroy; + if (destroy) + destroy (hook->data); + + destroy = ((GSourceFuncs*) hook->func)->destroy; + if (destroy) + destroy (source->source_data); + + G_LOCK (main_loop); } guint @@ -425,7 +437,7 @@ g_source_add (gint priority, if (!source_list.is_setup) g_hook_list_init (&source_list, sizeof(GSource)); - source_list.hook_free = g_source_free_func; + source_list.hook_destroy = g_source_destroy_func; source = (GSource *)g_hook_alloc (&source_list); source->priority = priority; @@ -461,11 +473,13 @@ g_source_add (gint priority, return return_val; } -void +gboolean g_source_remove (guint tag) { GHook *hook; + g_return_val_if_fail (tag > 0, FALSE); + G_LOCK (main_loop); hook = g_hook_get (&source_list, tag); @@ -473,9 +487,11 @@ g_source_remove (guint tag) g_hook_destroy_link (&source_list, hook); G_UNLOCK (main_loop); + + return hook != NULL; } -void +gboolean g_source_remove_by_user_data (gpointer user_data) { GHook *hook; @@ -487,6 +503,8 @@ g_source_remove_by_user_data (gpointer user_data) g_hook_destroy_link (&source_list, hook); G_UNLOCK (main_loop); + + return hook != NULL; } static gboolean @@ -498,7 +516,7 @@ g_source_find_source_data (GHook *hook, return (source->source_data == data); } -void +gboolean g_source_remove_by_source_data (gpointer source_data) { GHook *hook; @@ -511,6 +529,41 @@ g_source_remove_by_source_data (gpointer source_data) g_hook_destroy_link (&source_list, hook); G_UNLOCK (main_loop); + + return hook != NULL; +} + +static gboolean +g_source_find_funcs_user_data (GHook *hook, + gpointer data) +{ + gpointer *d = data; + + return hook->func == d[0] && hook->data == d[1]; +} + +gboolean +g_source_remove_by_funcs_user_data (GSourceFuncs *funcs, + gpointer user_data) +{ + gpointer d[2]; + GHook *hook; + + g_return_val_if_fail (funcs != NULL, FALSE); + + G_LOCK (main_loop); + + d[0] = funcs; + d[1] = user_data; + + hook = g_hook_find (&source_list, TRUE, + g_source_find_funcs_user_data, d); + if (hook) + g_hook_destroy_link (&source_list, hook); + + G_UNLOCK (main_loop); + + return hook != NULL; } void @@ -676,11 +729,13 @@ g_main_iterate (gboolean block, continue; } + in_check_or_prepare++; if (hook->flags & G_SOURCE_READY || ((GSourceFuncs *) hook->func)->prepare (source->source_data, ¤t_time, &source_timeout)) { + in_check_or_prepare--; if (!dispatch) { hook->flags |= G_SOURCE_READY; @@ -697,6 +752,8 @@ g_main_iterate (gboolean block, timeout = 0; } } + else + in_check_or_prepare--; if (source_timeout >= 0) { @@ -733,10 +790,12 @@ g_main_iterate (gboolean block, continue; } + in_check_or_prepare++; if (hook->flags & G_SOURCE_READY || ((GSourceFuncs *) hook->func)->check (source->source_data, ¤t_time)) { + in_check_or_prepare--; if (dispatch) { hook->flags &= ~G_SOURCE_READY; @@ -753,6 +812,8 @@ g_main_iterate (gboolean block, return TRUE; } } + else + in_check_or_prepare--; hook = g_hook_next_valid (&source_list, hook, TRUE); } @@ -774,9 +835,9 @@ g_main_iterate (gboolean block, /* See if any events are pending */ gboolean -g_main_pending () +g_main_pending (void) { - return g_main_iterate (FALSE, FALSE); + return in_check_or_prepare ? FALSE : g_main_iterate (FALSE, FALSE); } /* Run a single iteration of the mainloop. If block is FALSE, @@ -785,7 +846,14 @@ g_main_pending () gboolean g_main_iteration (gboolean block) { - return g_main_iterate (block, TRUE); + if (in_check_or_prepare) + { + g_warning ("g_main_iteration(): called recursively from within a source's check() or " + "prepare() member, iteration not possible"); + return FALSE; + } + else + return g_main_iterate (block, TRUE); } GMainLoop* @@ -804,6 +872,13 @@ g_main_run (GMainLoop *loop) { g_return_if_fail (loop != NULL); + if (in_check_or_prepare) + { + g_warning ("g_main_run(): called recursively from within a source's check() or " + "prepare() member, iteration not possible"); + return; + } + loop->is_running = TRUE; while (loop->is_running) g_main_iterate (TRUE, TRUE); @@ -999,9 +1074,9 @@ g_main_set_poll_func (GPollFunc func) poll_func = func; else #ifdef HAVE_POLL - poll_func = (GPollFunc)poll; + poll_func = (GPollFunc) poll; #else - poll_func = (GPollFunc)g_poll; + poll_func = (GPollFunc) g_poll; #endif } @@ -1120,22 +1195,20 @@ g_idle_dispatch (gpointer source_data, GTimeVal *current_time, gpointer user_data) { - GIdleData *data = source_data; + GSourceFunc func = source_data; - return (*data->callback)(user_data); + return func (user_data); } guint -g_idle_add_full (gint priority, +g_idle_add_full (gint priority, GSourceFunc function, gpointer data, GDestroyNotify notify) { - GIdleData *idle_data = g_new (GIdleData, 1); - - idle_data->callback = function; + g_return_val_if_fail (function != NULL, 0); - return g_source_add (priority, FALSE, &idle_funcs, idle_data, data, notify); + return g_source_add (priority, FALSE, &idle_funcs, function, data, notify); } guint @@ -1144,3 +1217,9 @@ g_idle_add (GSourceFunc function, { return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL); } + +gboolean +g_idle_remove_by_data (gpointer data) +{ + return g_source_remove_by_funcs_user_data (&idle_funcs, data); +} diff --git a/gmain.c b/gmain.c index 7e3571b..9da4fa0 100644 --- a/gmain.c +++ b/gmain.c @@ -31,30 +31,29 @@ #include #ifdef HAVE_SYS_TIME_H #include -#endif -#ifdef GLIB_HAVE_SYS_POLL_H +#endif /* HAVE_SYS_TIME_H */ +#ifdef GLIB_HAVE_SYS_POLL_H # include # undef events /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */ # undef revents /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */ -#endif /* GLIB_HAVE_SYS_POLL_H */ +#endif /* GLIB_HAVE_SYS_POLL_H */ #ifdef HAVE_UNISTD_H #include -#endif +#endif /* HAVE_UNISTD_H */ #include #ifdef NATIVE_WIN32 #define STRICT #include -#endif +#endif /* NATIVE_WIN32 */ #ifdef _MSC_VER #include #include -#endif +#endif /* _MSC_VER */ /* Types */ -typedef struct _GIdleData GIdleData; typedef struct _GTimeoutData GTimeoutData; typedef struct _GSource GSource; typedef struct _GPollRec GPollRec; @@ -77,11 +76,6 @@ struct _GMainLoop gboolean is_running; }; -struct _GIdleData -{ - GSourceFunc callback; -}; - struct _GTimeoutData { GTimeVal expiration; @@ -100,7 +94,7 @@ struct _GPollRec static gint g_source_compare (GHook *a, GHook *b); -static void g_source_free_func (GHookList *hook_list, +static void g_source_destroy_func (GHookList *hook_list, GHook *hook); static void g_main_poll (gint timeout, gboolean use_priority, @@ -129,24 +123,27 @@ static gboolean g_idle_dispatch (gpointer source_data, static GSList *pending_dispatches = NULL; static GHookList source_list = { 0 }; +static gint in_check_or_prepare = 0; /* The following lock is used for both the list of sources * and the list of poll records */ G_LOCK_DECLARE_STATIC (main_loop); -static GSourceFuncs timeout_funcs = { +static GSourceFuncs timeout_funcs = +{ g_timeout_prepare, g_timeout_check, g_timeout_dispatch, - (GDestroyNotify)g_free + g_free, }; -static GSourceFuncs idle_funcs = { +static GSourceFuncs idle_funcs = +{ g_idle_prepare, g_idle_check, g_idle_dispatch, - (GDestroyNotify)g_free + NULL, }; static GPollRec *poll_records = NULL; @@ -159,12 +156,12 @@ static guint n_poll_records = 0; /* this pipe is used to wake up the main loop when a source is added. */ static gint wake_up_pipe[2] = { -1, -1 }; -#else +#else /* NATIVE_WIN32 */ static HANDLE wake_up_semaphore = NULL; -#endif +#endif /* NATIVE_WIN32 */ static GPollFD wake_up_rec; static gboolean poll_waiting = FALSE; -#endif +#endif /* G_THREADS_ENABLED */ #ifdef HAVE_POLL static GPollFunc poll_func = (GPollFunc) poll; @@ -321,19 +318,21 @@ g_poll (GPollFD *fds, guint nfds, gint timeout) #ifndef NO_FD_SET # define SELECT_MASK fd_set -#else /* !NO_FD_SET */ +#else /* !NO_FD_SET */ # ifndef _AIX typedef long fd_mask; -# endif -# if defined(_IBMR2) +# endif /* _AIX */ +# ifdef _IBMR2 # define SELECT_MASK void -# else +# else /* !_IBMR2 */ # define SELECT_MASK int -# endif -#endif /* !NO_FD_SET */ +# endif /* !_IBMR2 */ +#endif /* !NO_FD_SET */ static gint -g_poll (GPollFD *fds, guint nfds, gint timeout) +g_poll (GPollFD *fds, + guint nfds, + gint timeout) { struct timeval tv; SELECT_MASK rset, wset, xset; @@ -380,6 +379,7 @@ g_poll (GPollFD *fds, guint nfds, gint timeout) return ready; } + #endif /* !NATIVE_WIN32 */ static GPollFunc poll_func = g_poll; @@ -400,13 +400,25 @@ g_source_compare (GHook *a, return (source_a->priority < source_b->priority) ? -1 : 1; } +/* HOLDS: main_loop_lock */ static void -g_source_free_func (GHookList *hook_list, - GHook *hook) +g_source_destroy_func (GHookList *hook_list, + GHook *hook) { - GSource *source = (GSource *)hook; + GSource *source = (GSource*) hook; + GDestroyNotify destroy; - ((GSourceFuncs *) hook->func)->destroy (source->source_data); + G_UNLOCK (main_loop); + + destroy = hook->destroy; + if (destroy) + destroy (hook->data); + + destroy = ((GSourceFuncs*) hook->func)->destroy; + if (destroy) + destroy (source->source_data); + + G_LOCK (main_loop); } guint @@ -425,7 +437,7 @@ g_source_add (gint priority, if (!source_list.is_setup) g_hook_list_init (&source_list, sizeof(GSource)); - source_list.hook_free = g_source_free_func; + source_list.hook_destroy = g_source_destroy_func; source = (GSource *)g_hook_alloc (&source_list); source->priority = priority; @@ -461,11 +473,13 @@ g_source_add (gint priority, return return_val; } -void +gboolean g_source_remove (guint tag) { GHook *hook; + g_return_val_if_fail (tag > 0, FALSE); + G_LOCK (main_loop); hook = g_hook_get (&source_list, tag); @@ -473,9 +487,11 @@ g_source_remove (guint tag) g_hook_destroy_link (&source_list, hook); G_UNLOCK (main_loop); + + return hook != NULL; } -void +gboolean g_source_remove_by_user_data (gpointer user_data) { GHook *hook; @@ -487,6 +503,8 @@ g_source_remove_by_user_data (gpointer user_data) g_hook_destroy_link (&source_list, hook); G_UNLOCK (main_loop); + + return hook != NULL; } static gboolean @@ -498,7 +516,7 @@ g_source_find_source_data (GHook *hook, return (source->source_data == data); } -void +gboolean g_source_remove_by_source_data (gpointer source_data) { GHook *hook; @@ -511,6 +529,41 @@ g_source_remove_by_source_data (gpointer source_data) g_hook_destroy_link (&source_list, hook); G_UNLOCK (main_loop); + + return hook != NULL; +} + +static gboolean +g_source_find_funcs_user_data (GHook *hook, + gpointer data) +{ + gpointer *d = data; + + return hook->func == d[0] && hook->data == d[1]; +} + +gboolean +g_source_remove_by_funcs_user_data (GSourceFuncs *funcs, + gpointer user_data) +{ + gpointer d[2]; + GHook *hook; + + g_return_val_if_fail (funcs != NULL, FALSE); + + G_LOCK (main_loop); + + d[0] = funcs; + d[1] = user_data; + + hook = g_hook_find (&source_list, TRUE, + g_source_find_funcs_user_data, d); + if (hook) + g_hook_destroy_link (&source_list, hook); + + G_UNLOCK (main_loop); + + return hook != NULL; } void @@ -676,11 +729,13 @@ g_main_iterate (gboolean block, continue; } + in_check_or_prepare++; if (hook->flags & G_SOURCE_READY || ((GSourceFuncs *) hook->func)->prepare (source->source_data, ¤t_time, &source_timeout)) { + in_check_or_prepare--; if (!dispatch) { hook->flags |= G_SOURCE_READY; @@ -697,6 +752,8 @@ g_main_iterate (gboolean block, timeout = 0; } } + else + in_check_or_prepare--; if (source_timeout >= 0) { @@ -733,10 +790,12 @@ g_main_iterate (gboolean block, continue; } + in_check_or_prepare++; if (hook->flags & G_SOURCE_READY || ((GSourceFuncs *) hook->func)->check (source->source_data, ¤t_time)) { + in_check_or_prepare--; if (dispatch) { hook->flags &= ~G_SOURCE_READY; @@ -753,6 +812,8 @@ g_main_iterate (gboolean block, return TRUE; } } + else + in_check_or_prepare--; hook = g_hook_next_valid (&source_list, hook, TRUE); } @@ -774,9 +835,9 @@ g_main_iterate (gboolean block, /* See if any events are pending */ gboolean -g_main_pending () +g_main_pending (void) { - return g_main_iterate (FALSE, FALSE); + return in_check_or_prepare ? FALSE : g_main_iterate (FALSE, FALSE); } /* Run a single iteration of the mainloop. If block is FALSE, @@ -785,7 +846,14 @@ g_main_pending () gboolean g_main_iteration (gboolean block) { - return g_main_iterate (block, TRUE); + if (in_check_or_prepare) + { + g_warning ("g_main_iteration(): called recursively from within a source's check() or " + "prepare() member, iteration not possible"); + return FALSE; + } + else + return g_main_iterate (block, TRUE); } GMainLoop* @@ -804,6 +872,13 @@ g_main_run (GMainLoop *loop) { g_return_if_fail (loop != NULL); + if (in_check_or_prepare) + { + g_warning ("g_main_run(): called recursively from within a source's check() or " + "prepare() member, iteration not possible"); + return; + } + loop->is_running = TRUE; while (loop->is_running) g_main_iterate (TRUE, TRUE); @@ -999,9 +1074,9 @@ g_main_set_poll_func (GPollFunc func) poll_func = func; else #ifdef HAVE_POLL - poll_func = (GPollFunc)poll; + poll_func = (GPollFunc) poll; #else - poll_func = (GPollFunc)g_poll; + poll_func = (GPollFunc) g_poll; #endif } @@ -1120,22 +1195,20 @@ g_idle_dispatch (gpointer source_data, GTimeVal *current_time, gpointer user_data) { - GIdleData *data = source_data; + GSourceFunc func = source_data; - return (*data->callback)(user_data); + return func (user_data); } guint -g_idle_add_full (gint priority, +g_idle_add_full (gint priority, GSourceFunc function, gpointer data, GDestroyNotify notify) { - GIdleData *idle_data = g_new (GIdleData, 1); - - idle_data->callback = function; + g_return_val_if_fail (function != NULL, 0); - return g_source_add (priority, FALSE, &idle_funcs, idle_data, data, notify); + return g_source_add (priority, FALSE, &idle_funcs, function, data, notify); } guint @@ -1144,3 +1217,9 @@ g_idle_add (GSourceFunc function, { return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL); } + +gboolean +g_idle_remove_by_data (gpointer data) +{ + return g_source_remove_by_funcs_user_data (&idle_funcs, data); +} -- 2.7.4