The patch seems ok and the gui no longer crashes. Pushed.
On Wed, Feb 20, 2013 at 18:02:40 +0100, Jakub Filak wrote: > - closes #134 > > Signed-off-by: Jakub Filak <[email protected]> > --- > src/gtk-helpers/secrets.c | 36 +++++++++++++++++++++++++++++------- > 1 file changed, 29 insertions(+), 7 deletions(-) > > diff --git a/src/gtk-helpers/secrets.c b/src/gtk-helpers/secrets.c > index 72af67d..37c0a03 100644 > --- a/src/gtk-helpers/secrets.c > +++ b/src/gtk-helpers/secrets.c > @@ -388,6 +388,7 @@ struct secrets_loop_env > { > GMainContext* gcontext; > GMainLoop *gloop; > + GSource *timeout_source; > GtkWidget *timeout_dialog; > }; > > @@ -405,6 +406,18 @@ struct prompt_call_back_args > struct secrets_loop_env *env; > }; > > +static void nuke_timeout_source(GSource *source) > +{ > + if (NULL == source) > + return; > + > + if (!g_source_is_destroyed(source)) > + /* detach it from GMainContext if it is attached */ > + g_source_destroy(source); > + > + g_source_unref(source); > +} > + > static void prompt_quit_loop(struct secrets_loop_env *env) > { > if (NULL != env->timeout_dialog) > @@ -413,6 +426,9 @@ static void prompt_quit_loop(struct secrets_loop_env *env) > env->timeout_dialog = NULL; > } > > + nuke_timeout_source(env->timeout_source); > + env->timeout_source = NULL; > + > if (g_main_loop_is_running(env->gloop)) > g_main_loop_quit(env->gloop); > } > @@ -552,15 +568,20 @@ static gboolean prompt_timeout_cb(gpointer user_data) > */ > static void prompt_timeout_start(struct secrets_loop_env *env) > { > - GSource *timeout_source= > g_timeout_source_new_seconds(PROMPT_TIMEOUT_SECONDS); > + /* Clean up the old timeout source, it can't be attached to the context > again. > + * > http://developer.gnome.org/glib/2.34/glib-The-Main-Event-Loop.html#g-source-destroy > + * > + * The old timeout source was destroyed by GMainContext because source's > + * callback (prompt_timeout_cb) returns FALSE. The callback must return > + * FALSE because neither the expiration time of timeout source can be > reset > + * nor timeout can be suspended. > + */ > + nuke_timeout_source(env->timeout_source); > > - g_source_set_callback(timeout_source, prompt_timeout_cb, /*callback > arg*/env, /*arg destroyer*/NULL); > - g_source_attach(timeout_source, env->gcontext); > + env->timeout_source= > g_timeout_source_new_seconds(PROMPT_TIMEOUT_SECONDS); > > - /* remove local reference, the source will be destroyed by the > GMainContext > - * over taken from glib2/gmain.c: g_timeout_add_full() > - */ > - g_source_unref(timeout_source); > + g_source_set_callback(env->timeout_source, prompt_timeout_cb, /*callback > arg*/env, /*arg destroyer*/NULL); > + g_source_attach(env->timeout_source, env->gcontext); > } > > /* > @@ -596,6 +617,7 @@ static GVariant *secrets_prompt(const char *prompt_path, > struct secrets_loop_env env = { > .gcontext=context, > .gloop=g_main_loop_new(context, FALSE), > + .timeout_source=NULL, > .timeout_dialog=NULL, > }; > > -- > 1.8.1.2 >
