diff options
author | Darin Adler <darin@src.gnome.org> | 2001-04-03 20:59:03 +0000 |
---|---|---|
committer | Darin Adler <darin@src.gnome.org> | 2001-04-03 20:59:03 +0000 |
commit | f7ea58e25b70b3d675ad2d10a41892aa6bc12223 (patch) | |
tree | 24c45e9ff8a5d0d0c36bb3ba24c16df0b420aac6 /libnautilus | |
parent | 28b5c6daf7ca9c9d892246b96f28259da37e8e04 (diff) | |
download | nautilus-f7ea58e25b70b3d675ad2d10a41892aa6bc12223.tar.gz |
reviewed by: John Sullivan <sullivan@eazel.com>
* libnautilus/nautilus-bonobo-workarounds.c:
(nautilus_bonobo_object_force_destroy): Add new version that is
not vulnerable to the problem of an unref coming in from the other
process during the destroy phase. This version relies on Bonobo
internals, so it's a truly evil bit of code, and I should be
severely punished for even thinking of writing it.
(nautilus_bonobo_object_force_destroy_at_idle): Added some more
checks that I thought would help me in debugging.
* src/nautilus-shell-ui.xml: Improve wording of tooltip for the Up
command.
* components/notes/nautilus-notes.c: Some code cleanup.
* src/file-manager/fm-directory-view.c: Fixed a typo.
Diffstat (limited to 'libnautilus')
-rw-r--r-- | libnautilus/nautilus-bonobo-workarounds.c | 82 |
1 files changed, 78 insertions, 4 deletions
diff --git a/libnautilus/nautilus-bonobo-workarounds.c b/libnautilus/nautilus-bonobo-workarounds.c index 5655ac4ad..a2682d6ca 100644 --- a/libnautilus/nautilus-bonobo-workarounds.c +++ b/libnautilus/nautilus-bonobo-workarounds.c @@ -30,6 +30,26 @@ #include <gtk/gtkmain.h> #include <gtk/gtksignal.h> +#define RELY_ON_BONOBO_INTERNALS + +#ifdef RELY_ON_BONOBO_INTERNALS + +/* This is incredibly unsafe and relies on details of the Bonobo + * internals. I should be shot and killed for even thinking of doing + * this. + */ +typedef struct { + int ref_count; + GList *objs; +} StartOfBonoboAggregateObject; + +typedef struct { + StartOfBonoboAggregateObject *ao; + int destroy_id; +} StartOfBonoboObjectPrivate; + +#endif + /* FIXME bugzilla.eazel.com 2456: Is a hard-coded 20 seconds wait to * detect that a remote object's process is hung acceptable? Can a * component that is working still take 20 seconds to respond? @@ -89,6 +109,21 @@ nautilus_bonobo_stream_get_epv (void) return &bonobo_stream_epv; } +/* The following is the most evil function in the world. But on the + * other hand, it works and prevents us from having tons of lingering + * processes when Nautilus crashes. It's unsafe to call it if there + * are any direct references to the bonobo object, but it's OK to have + * any number of references to it through CORBA. + */ + +#ifndef RELY_ON_BONOBO_INTERNALS + +/* This version of the function doesn't rely on Bonobo internals as + * much as the other one does, but it gets screwed up by incoming + * unref calls while the object is being destroyed. This was actually + * happening, which is why I had to write the other version. + */ + static void set_gone_flag (GtkObject *object, gpointer callback_data) @@ -99,10 +134,6 @@ set_gone_flag (GtkObject *object, *gone_flag = TRUE; } -/* The following is the most evil function in the world. But on the - * other hand, it works and prevents us from having tons of lingering - * processes when Nautilus crashes. - */ void nautilus_bonobo_object_force_destroy (BonoboObject *object) { @@ -123,6 +154,46 @@ nautilus_bonobo_object_force_destroy (BonoboObject *object) } while (!gone); } +#else /* RELY_ON_BONOBO_INTERNALS */ + +void +nautilus_bonobo_object_force_destroy (BonoboObject *object) +{ + StartOfBonoboAggregateObject *aggregate; + GList *node; + GtkObject *subobject; + guint *id; + + if (object == NULL) { + return; + } + + g_return_if_fail (BONOBO_IS_OBJECT (object)); + + aggregate = ((StartOfBonoboObjectPrivate *) object->priv)->ao; + + /* Do all the destroying with a normal reference count. This + * lets us live through unrefs that happen during the destroy + * process. + */ + bonobo_object_ref (object); + for (node = aggregate->objs; node != NULL; node = node->next) { + subobject = GTK_OBJECT (node->data); + id = &((StartOfBonoboObjectPrivate *) BONOBO_OBJECT (subobject)->priv)->destroy_id; + if (*id != 0) { + gtk_signal_disconnect (subobject, *id); + *id = 0; + } + gtk_object_destroy (subobject); + } + + /* Now force a destroy by forcing the reference count to 1. */ + aggregate->ref_count = 1; + bonobo_object_unref (object); +} + +#endif /* RELY_ON_BONOBO_INTERNALS */ + static gboolean destroy_at_idle_callback (gpointer callback_data) { @@ -160,6 +231,9 @@ nautilus_bonobo_object_force_destroy_at_idle (BonoboObject *object) return; } + g_return_if_fail (BONOBO_IS_OBJECT (object)); + g_return_if_fail (!GTK_OBJECT_DESTROYED (object)); + data = g_new (IdleDestroyData, 1); data->object = object; data->idle_id = gtk_idle_add |