[evolution-patches] Re: rework of EComponentListener
- From: Rodrigo Moya <rodrigo ximian com>
- To: Michael Meeks <michael ximian com>
- Cc: Evolution Patches <evolution-patches ximian com>
- Subject: [evolution-patches] Re: rework of EComponentListener
- Date: 28 May 2003 13:32:35 +0200
On Tue, 2003-05-27 at 10:22, Michael Meeks wrote:
> > Michael, please could you have a look at the e-util patch?
> ...
> > I'll hold on this patch (if approved) a few days to make sure there are
> > no additional problems. So far, it seems to work ok for me.
>
> So - just a few comments; firstly there are (unfortunately) a few
> Gotchas with the 'listen_for_broken' API - inasmuch that the connection
> is shared between all CORBA_Objects talking to the same process; which
> is fine - but it makes the 'unlisten' totally useless [ unfortunately ]
> - since you can only unlisten on a callback [ which cocks up all the
> other listeners ;-].
>
> Thus - as you have done, it is by far the best to have a list of
> servers; and to do the ORBit_small_get_connection_status on them
> iteratively. However (it seems) you also put the EComponentListener
> pointer into the closure for the callback - whence it cannot be removed
> safely.
>
> So - I would suggest two things:
>
> * don't pass the *cl closure in,
> * simply iterate over the watched_connections list on broken,
> checking for DISCONNECTED, and removing the connection
> * don't forget to use the:
>
> GList *l, *next;
> for (l = start; l; l = next) {
> next = l->next;
> if (foo)
> start = g_list_delete (start, l);
> }
>
> type pattern or you'll wander onto the free'd list node heap ;-)
>
ok, updated patch attached.
cheers
? e-component-listener-orbit-small.c
? e-component-listener-orbit-small.h
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/e-util/ChangeLog,v
retrieving revision 1.390
diff -u -p -r1.390 ChangeLog
--- ChangeLog 16 May 2003 19:20:34 -0000 1.390
+++ ChangeLog 28 May 2003 11:28:05 -0000
@@ -1,3 +1,8 @@
+2003-05-26 Rodrigo Moya <rodrigo ximian com>
+
+ * e-component-listener.[ch]: use ORBit_small_listen/_unlisten instead
+ of Bonobo_Unknown_ping'ing the components.
+
2003-05-16 Dan Winship <danw ximian com>
* e-proxy.c (e_proxy_init): Removing trailing / in key name passed
Index: e-component-listener.c
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-component-listener.c,v
retrieving revision 1.4
diff -u -p -r1.4 e-component-listener.c
--- e-component-listener.c 5 Nov 2002 11:37:58 -0000 1.4
+++ e-component-listener.c 28 May 2003 11:28:05 -0000
@@ -14,12 +14,9 @@
#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);
@@ -27,6 +24,7 @@ static void e_component_listener_init
static void e_component_listener_finalize (GObject *object);
static GObjectClass *parent_class = NULL;
+static GList *watched_connections = NULL;
enum {
COMPONENT_DIED,
@@ -36,6 +34,30 @@ enum {
static guint comp_listener_signals[LAST_SIGNAL];
static void
+connection_listen_cb (gpointer object, gpointer user_data)
+{
+ GList *l, *next = NULL;
+ EComponentListener *cl;
+
+ for (l = watched_connections; l != NULL; l = next) {
+ next = l->next;
+ cl = l->data;
+
+ switch (ORBit_small_get_connection_status (cl->priv->component)) {
+ case ORBIT_CONNECTION_DISCONNECTED :
+ watched_connections = g_list_remove (watched_connections, cl);
+
+ g_object_ref (cl);
+ g_signal_emit (cl, comp_listener_signals[COMPONENT_DIED], 0);
+ cl->priv->component = CORBA_OBJECT_NIL;
+ g_object_unref (cl);
+ break;
+ default :
+ }
+ }
+}
+
+static void
e_component_listener_class_init (EComponentListenerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -61,8 +83,6 @@ e_component_listener_init (EComponentLis
/* 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
@@ -72,12 +92,10 @@ e_component_listener_finalize (GObject *
g_return_if_fail (E_IS_COMPONENT_LISTENER (cl));
- cl->priv->component = CORBA_OBJECT_NIL;
+ watched_connections = g_list_remove (watched_connections, cl);
- if (cl->priv->ping_timeout_id != -1) {
- g_source_remove (cl->priv->ping_timeout_id);
- cl->priv->ping_timeout_id = -1;
- }
+ if (cl->priv->component != CORBA_OBJECT_NIL)
+ cl->priv->component = CORBA_OBJECT_NIL;
/* free memory */
g_free (cl->priv);
@@ -109,67 +127,9 @@ e_component_listener_get_type (void)
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;
- }
-
- if (is_nil)
- goto out;
-
- alive = bonobo_unknown_ping (cl->priv->component, &ev);
- if (alive) {
- CORBA_exception_free (&ev);
- return TRUE;
- }
-
- out:
- /* the component has died, so we notify and close the timeout */
- CORBA_exception_free (&ev);
-
- /* we ref the object just in case it gets destroyed in the callbacks */
- g_object_ref (G_OBJECT (cl));
- g_signal_emit (G_OBJECT (cl), comp_listener_signals[COMPONENT_DIED], 0);
-
- cl->priv->component = CORBA_OBJECT_NIL;
- cl->priv->ping_timeout_id = -1;
-
- g_object_unref (G_OBJECT (cl));
-
- 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.
@@ -177,43 +137,22 @@ setup_ping_timeout (EComponentListener *
* Returns: a component listener object.
*/
EComponentListener *
-e_component_listener_new (Bonobo_Unknown comp, int ping_delay)
+e_component_listener_new (Bonobo_Unknown comp)
{
EComponentListener *cl;
+ g_return_val_if_fail (comp != NULL, NULL);
+
cl = g_object_new (E_COMPONENT_LISTENER_TYPE, NULL);
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);
+ /* watch the connection */
+ ORBit_small_listen_for_broken (comp, G_CALLBACK (connection_listen_cb), cl);
+ watched_connections = g_list_append (watched_connections, 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)
{
@@ -227,5 +166,5 @@ e_component_listener_set_component (ECom
g_return_if_fail (E_IS_COMPONENT_LISTENER (cl));
cl->priv->component = comp;
- setup_ping_timeout (cl);
+ ORBit_small_listen_for_broken (comp, G_CALLBACK (connection_listen_cb), cl);
}
Index: e-component-listener.h
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-component-listener.h,v
retrieving revision 1.4
diff -u -p -r1.4 e-component-listener.h
--- e-component-listener.h 5 Nov 2002 11:37:58 -0000 1.4
+++ e-component-listener.h 28 May 2003 11:28:05 -0000
@@ -36,10 +36,8 @@ typedef struct {
} EComponentListenerClass;
GType e_component_listener_get_type (void);
-EComponentListener *e_component_listener_new (Bonobo_Unknown comp, int ping_delay);
+EComponentListener *e_component_listener_new (Bonobo_Unknown comp);
-int e_component_listener_get_ping_delay (EComponentListener *cl);
-void e_component_listener_set_ping_delay (EComponentListener *cl, int ping_delay);
Bonobo_Unknown e_component_listener_get_component (EComponentListener *cl);
void e_component_listener_set_component (EComponentListener *cl,
Bonobo_Unknown comp);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]