diff options
author | Rodrigo Moya <rodrigo@ximian.com> | 2002-08-16 20:45:59 +0800 |
---|---|---|
committer | Rodrigo Moya <rodrigo@src.gnome.org> | 2002-08-16 20:45:59 +0800 |
commit | 83c35905a8146b88be28545604ec96c4358270d2 (patch) | |
tree | 418291d692ecd26e8ef8c7f3da69f81dbebf7559 /e-util/e-component-listener.c | |
parent | 1bfd78df264242ae90dce917d43f06436949cd3c (diff) | |
download | gsoc2013-evolution-83c35905a8146b88be28545604ec96c4358270d2.tar.gz gsoc2013-evolution-83c35905a8146b88be28545604ec96c4358270d2.tar.zst gsoc2013-evolution-83c35905a8146b88be28545604ec96c4358270d2.zip |
new class for controlling a component, to detect when it dies.
2002-08-14 Rodrigo Moya <rodrigo@ximian.com>
* e-component-listener.[ch]: new class for controlling a component,
to detect when it dies.
svn path=/trunk/; revision=17786
Diffstat (limited to 'e-util/e-component-listener.c')
-rw-r--r-- | e-util/e-component-listener.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/e-util/e-component-listener.c b/e-util/e-component-listener.c new file mode 100644 index 0000000000..d58f44e577 --- /dev/null +++ b/e-util/e-component-listener.c @@ -0,0 +1,227 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Component listener. + * + * Author: + * Rodrigo Moya <rodrigo@ximian.com> + * + * Copyright 2002, Ximian, Inc. + */ + +#include <gtk/gtksignal.h> +#include <bonobo/bonobo-exception.h> +#include <bonobo/bonobo-object.h> +#include <gal/util/e-util.h> +#include "e-component-listener.h" +#include <libgnome/gnome-i18n.h> + +#define PARENT_TYPE GTK_TYPE_OBJECT +#define DEFAULT_PING_DELAY 10000 + +struct _EComponentListenerPrivate { + Bonobo_Unknown component; + int ping_delay; + int ping_timeout_id; +}; + +static void e_component_listener_class_init (EComponentListenerClass *klass); +static void e_component_listener_init (EComponentListener *cl); +static void e_component_listener_destroy (GtkObject *object); + +static GtkObjectClass *parent_class = NULL; + +enum { + COMPONENT_DIED, + LAST_SIGNAL +}; + +static guint comp_listener_signals[LAST_SIGNAL]; + +static void +e_component_listener_class_init (EComponentListenerClass *klass) +{ + GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); + + parent_class = gtk_type_class (PARENT_TYPE); + + object_class->destroy = e_component_listener_destroy; + klass->component_died = NULL; + + comp_listener_signals[COMPONENT_DIED] = + gtk_signal_new ("component_died", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (EComponentListenerClass, component_died), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + gtk_object_class_add_signals (object_class, comp_listener_signals, LAST_SIGNAL); +} + +static void +e_component_listener_init (EComponentListener *cl) +{ + /* allocate internal structure */ + cl->priv = g_new (EComponentListenerPrivate, 1); + cl->priv->component = CORBA_OBJECT_NIL; + cl->priv->ping_delay = DEFAULT_PING_DELAY; + cl->priv->ping_timeout_id = -1; +} + +static void +e_component_listener_destroy (GtkObject *object) +{ + EComponentListener *cl = (EComponentListener *) object; + + g_return_if_fail (E_IS_COMPONENT_LISTENER (cl)); + + cl->priv->component = CORBA_OBJECT_NIL; + + if (cl->priv->ping_timeout_id != -1) { + g_source_remove (cl->priv->ping_timeout_id); + cl->priv->ping_timeout_id = -1; + } + + /* free memory */ + g_free (cl->priv); + cl->priv = NULL; + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +GtkType +e_component_listener_get_type (void) +{ + static GtkType type = 0; + + if (!type) { + static const GtkTypeInfo info = { + "EComponentListener", + sizeof (EComponentListener), + sizeof (EComponentListenerClass), + (GtkClassInitFunc) e_component_listener_class_init, + (GtkObjectInitFunc) e_component_listener_init, + NULL, /* reserved_1 */ + NULL, /* reserved_2 */ + (GtkClassInitFunc) NULL + }; + + type = gtk_type_unique (PARENT_TYPE, &info); + } + + return type; +} + +static gboolean +ping_component_callback (gpointer user_data) +{ + gboolean alive; + int is_nil; + CORBA_Environment ev; + EComponentListener *cl = (EComponentListener *) user_data; + + g_return_val_if_fail (E_IS_COMPONENT_LISTENER (cl), FALSE); + + if (cl->priv->component == CORBA_OBJECT_NIL) + return FALSE; + + CORBA_exception_init (&ev); + is_nil = CORBA_Object_is_nil (cl->priv->component, &ev); + if (BONOBO_EX (&ev)) { + g_message (_("ping_timeout_callback: could not determine if the " + "CORBA object is nil or not")); + goto out; + } + CORBA_exception_free (&ev); + + if (is_nil) + goto out; + + alive = bonobo_unknown_ping (cl->priv->component); + if (alive) + return TRUE; + + out: + /* the component has died, so we notify and close the timeout */ + gtk_signal_emit (GTK_OBJECT (cl), comp_listener_signals[COMPONENT_DIED]); + + cl->priv->component = CORBA_OBJECT_NIL; + cl->priv->ping_timeout_id = -1; + + return FALSE; +} + +static void +setup_ping_timeout (EComponentListener *cl) +{ + if (cl->priv->ping_timeout_id != -1) + g_source_remove (cl->priv->ping_timeout_id); + + cl->priv->ping_timeout_id = g_timeout_add (cl->priv->ping_delay, + ping_component_callback, + cl); +} + +/** + * e_component_listener_new + * @comp: Component to listen for. + * @ping_delay: Delay (in ms) for pinging the component. + * + * Create a new #EComponentListener object, which allows to listen + * for a given component and get notified when that component dies. + * + * Returns: a component listener object. + */ +EComponentListener * +e_component_listener_new (Bonobo_Unknown comp, int ping_delay) +{ + EComponentListener *cl; + + cl = gtk_type_new (E_COMPONENT_LISTENER_TYPE); + cl->priv->component = comp; + + /* set up the timeout function */ + cl->priv->ping_delay = ping_delay > 0 ? ping_delay : DEFAULT_PING_DELAY; + setup_ping_timeout (cl); + + return cl; +} + +/** + * e_component_listener_get_ping_delay + * @cl: A #EComponentListener object. + * + * Get the ping delay being used to listen for an object. + */ +int +e_component_listener_get_ping_delay (EComponentListener *cl) +{ + g_return_val_if_fail (E_IS_COMPONENT_LISTENER (cl), -1); + return cl->priv->ping_delay; +} + +void +e_component_listener_set_ping_delay (EComponentListener *cl, int ping_delay) +{ + g_return_if_fail (E_IS_COMPONENT_LISTENER (cl)); + g_return_if_fail (ping_delay > 0); + + cl->priv->ping_delay = ping_delay; + setup_ping_timeout (cl); +} + +Bonobo_Unknown +e_component_listener_get_component (EComponentListener *cl) +{ + g_return_val_if_fail (E_IS_COMPONENT_LISTENER (cl), CORBA_OBJECT_NIL); + return cl->priv->component; +} + +void +e_component_listener_set_component (EComponentListener *cl, Bonobo_Unknown comp) +{ + g_return_if_fail (E_IS_COMPONENT_LISTENER (cl)); + + cl->priv->component = comp; + setup_ping_timeout (cl); +} |