diff options
author | Murray Cumming <murrayc@murrayc.com> | 2004-07-10 06:35:15 +0000 |
---|---|---|
committer | Murray Cumming <murrayc@src.gnome.org> | 2004-07-10 06:35:15 +0000 |
commit | c07890fdd698363e8b43ae0bf390d8c053fa390e (patch) | |
tree | 09ecbb9ed2d780a9c541a004c33ba0940109943a /glib/glibmm/signalproxy_connectionnode.cc | |
parent | 909326c10247a503d5f5e21cdb725f317da0ff75 (diff) | |
download | glibmm-c07890fdd698363e8b43ae0bf390d8c053fa390e.tar.gz |
notify(): Do not delete the connection after disconnecting it, because
2004-07-10 Murray Cumming <murrayc@murrayc.com>
* glib/glibmm/signalproxy_connectionnode.cc: notify(): Do not delete
the connection after disconnecting it, because disconnecting it
always causes disconnect_notify to be called, so just delete it there.
This prevents double deletes and reading of deleting memory, found in
bug #145571.
Diffstat (limited to 'glib/glibmm/signalproxy_connectionnode.cc')
-rw-r--r-- | glib/glibmm/signalproxy_connectionnode.cc | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/glib/glibmm/signalproxy_connectionnode.cc b/glib/glibmm/signalproxy_connectionnode.cc index 07586255..30c09c9f 100644 --- a/glib/glibmm/signalproxy_connectionnode.cc +++ b/glib/glibmm/signalproxy_connectionnode.cc @@ -34,7 +34,8 @@ SignalProxyConnectionNode::SignalProxyConnectionNode(const sigc::slot_base& slot slot_ (slot), object_ (gobject) { - slot_.set_parent(this, &SignalProxyConnectionNode::notify); + //The cleanup callback will be called when the connection is disconnected. + slot_.set_parent(this, &SignalProxyConnectionNode::notify /* cleanup callback */); } // notify is a message coming up from the slot to be passed back to Gtk+ @@ -42,23 +43,33 @@ SignalProxyConnectionNode::SignalProxyConnectionNode(const sigc::slot_base& slot //static void* SignalProxyConnectionNode::notify(void* data) { - // notification from sigc++. + // notification from libsigc++. SignalProxyConnectionNode* conn = static_cast<SignalProxyConnectionNode*>(data); - // if there is no object, this call was triggered from destroy_notify_handler(). + // If there is no object, this call was triggered from destroy_notify_handler(), + // because we set conn->object to 0 there: if(conn && conn->object_) { GObject* o = conn->object_; conn->object_ = 0; - - // this triggers execution of destroy_notify_handler(): - if(g_signal_handler_is_connected(o, conn->connection_id_)) //During destruction, GTK+ sometimes seems to disconnect them for us, before we expect it to. See bug #87912 - g_signal_handler_disconnect(o, conn->connection_id_); - - conn->connection_id_ = 0; - - delete conn; // if there are connection objects referring to slot_ they are notified during destruction of slot_ + + if(g_signal_handler_is_connected(o, conn->connection_id_)) //We check first, because during destruction, GTK+ sometimes seems to disconnect them for us, before we expect it to. See bug #87912 + { + // Disconnecting triggers execution of destroy_notify_handler(), eiter immediately or later: + // When the signal handler is currently running. (for instance, if the callback disconnects its own connection) + // In that case, destroy_notify_handler() will be called after this whole function has returned. + // Anyway. destroy_notify_handler() will always be called, so we leave that to do the deletion. + + + //Forget the connection: + gulong connection_id = conn->connection_id_; + conn->connection_id_ = 0; + + g_signal_handler_disconnect(o, connection_id); + } } + else if(conn && !conn->object_) + g_warning("SignalProxyConnectionNode::notify(): called without gobject"); return 0; // apparently unused in libsigc++ } @@ -66,11 +77,13 @@ void* SignalProxyConnectionNode::notify(void* data) //static void SignalProxyConnectionNode::destroy_notify_handler(gpointer data, GClosure*) { + //glib calls this when it has finished with a glib signal connection, + //either when the emitting object dies, or when the connection has been disconnected. + // notification from gtk+. SignalProxyConnectionNode* conn = static_cast<SignalProxyConnectionNode*>(data); - // if there is no object, this call was triggered from notify(). - if (conn && conn->object_) + if(conn) { // the object has already lost track of this object. conn->object_ = 0; |