[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
mrobinson at webkit.org
mrobinson at webkit.org
Wed Dec 22 15:34:10 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit e5ad7392a5b5ee1730015a763a84df5f8a7672b6
Author: mrobinson at webkit.org <mrobinson at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Nov 8 16:42:48 2010 +0000
2010-11-08 Martin Robinson <mrobinson at igalia.com>
Reviewed by Xan Lopez.
[GTK] Wrapped DOM bindings GObjects do not disconnect event listeners when they die
https://bugs.webkit.org/show_bug.cgi?id=49136
When GObjects are finalized and freed, disconnect their event listeners, so that
WebCore does not try to fire signals on dead GObjects. We do this by holding a weak
reference to the GObject in the signal listener. When the weak reference notification
callback is executed, we disconnect the event listener.
No new tests; this fix is proved by prevention of crashes in soon to be
landed editing delegate signals, which are covered by the layout tests.
* bindings/gobject/GObjectEventListener.cpp:
(WebCore::GObjectEventListener::GObjectEventListener): Updated the constructor.
(WebCore::GObjectEventListener::~GObjectEventListener): Disconnect the weak reference
if the GObject is still alive.
(WebCore::GObjectEventListener::gobjectDestroyed): When the GObject is destroyed,
disconnect the appropriate event listener.
(WebCore::GObjectEventListener::handleEvent): Changes to reflect use of CString
instead of WebCore string.
* bindings/gobject/GObjectEventListener.h:
(WebCore::GObjectEventListener::addEventListener): Changed create to addEventListener,
so that the connection and disconnection is an internal contract to the class.
(WebCore::GObjectEventListener::gobjectDestroyedCallback): Added.
* bindings/scripts/CodeGeneratorGObject.pm: Modified the code generate to use
GObjectEventListener::addEventListener and no longer call addEventListener on
its own.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71528 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1e48643..efcb2ee 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,34 @@
+2010-11-08 Martin Robinson <mrobinson at igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Wrapped DOM bindings GObjects do not disconnect event listeners when they die
+ https://bugs.webkit.org/show_bug.cgi?id=49136
+
+ When GObjects are finalized and freed, disconnect their event listeners, so that
+ WebCore does not try to fire signals on dead GObjects. We do this by holding a weak
+ reference to the GObject in the signal listener. When the weak reference notification
+ callback is executed, we disconnect the event listener.
+
+ No new tests; this fix is proved by prevention of crashes in soon to be
+ landed editing delegate signals, which are covered by the layout tests.
+
+ * bindings/gobject/GObjectEventListener.cpp:
+ (WebCore::GObjectEventListener::GObjectEventListener): Updated the constructor.
+ (WebCore::GObjectEventListener::~GObjectEventListener): Disconnect the weak reference
+ if the GObject is still alive.
+ (WebCore::GObjectEventListener::gobjectDestroyed): When the GObject is destroyed,
+ disconnect the appropriate event listener.
+ (WebCore::GObjectEventListener::handleEvent): Changes to reflect use of CString
+ instead of WebCore string.
+ * bindings/gobject/GObjectEventListener.h:
+ (WebCore::GObjectEventListener::addEventListener): Changed create to addEventListener,
+ so that the connection and disconnection is an internal contract to the class.
+ (WebCore::GObjectEventListener::gobjectDestroyedCallback): Added.
+ * bindings/scripts/CodeGeneratorGObject.pm: Modified the code generate to use
+ GObjectEventListener::addEventListener and no longer call addEventListener on
+ its own.
+
2010-11-08 Adam Roben <aroben at apple.com>
Windows Release build fix after r71514
diff --git a/WebCore/bindings/gobject/GObjectEventListener.cpp b/WebCore/bindings/gobject/GObjectEventListener.cpp
index 3ce8461..553d717 100644
--- a/WebCore/bindings/gobject/GObjectEventListener.cpp
+++ b/WebCore/bindings/gobject/GObjectEventListener.cpp
@@ -19,20 +19,63 @@
#include "config.h"
#include "GObjectEventListener.h"
+#include "DOMWindow.h"
#include "Event.h"
#include "EventListener.h"
+#include "Node.h"
#include "webkit/WebKitDOMEvent.h"
#include "webkit/WebKitDOMEventPrivate.h"
+#include <glib-object.h>
+#include <glib.h>
#include <wtf/HashMap.h>
-#include <wtf/text/CString.h>
namespace WebCore {
+GObjectEventListener::GObjectEventListener(GObject* object, DOMWindow* window, Node* node, const char* domEventName, const char* signalName)
+ : EventListener(GObjectEventListenerType)
+ , m_object(object)
+ , m_coreNode(node)
+ , m_coreWindow(window)
+ , m_domEventName(domEventName)
+ , m_signalName(signalName)
+{
+ ASSERT(!m_coreWindow || !m_coreNode);
+ if (m_coreWindow)
+ m_coreWindow->addEventListener(domEventName, this, false);
+ if (m_coreNode)
+ m_coreNode->addEventListener(domEventName, this, false);
+ g_object_weak_ref(object, reinterpret_cast<GWeakNotify>(GObjectEventListener::gobjectDestroyedCallback), this);
+}
+
+GObjectEventListener::~GObjectEventListener()
+{
+ if (!m_coreWindow && !m_coreNode)
+ return;
+ g_object_weak_unref(m_object, reinterpret_cast<GWeakNotify>(GObjectEventListener::gobjectDestroyedCallback), this);
+}
+
+void GObjectEventListener::gobjectDestroyed()
+{
+ ASSERT(!m_coreWindow || !m_coreNode);
+
+ // We must set m_coreWindow and m_coreNode to null, because removeEventListener may call the
+ // destructor as a side effect and we must be in the proper state to prevent g_object_weak_unref.
+ if (DOMWindow* window = m_coreWindow) {
+ m_coreWindow = 0;
+ window->removeEventListener(m_domEventName.data(), this, false);
+ return;
+ }
+
+ Node* node = m_coreNode;
+ m_coreNode = 0; // See above.
+ node->removeEventListener(m_domEventName.data(), this, false);
+}
+
void GObjectEventListener::handleEvent(ScriptExecutionContext*, Event* event)
{
gboolean handled = FALSE;
WebKitDOMEvent* gobjectEvent = WEBKIT_DOM_EVENT(WebKit::kit(event));
- g_signal_emit_by_name(m_object, m_signalName.utf8().data(), gobjectEvent, &handled);
+ g_signal_emit_by_name(m_object, m_signalName.data(), gobjectEvent, &handled);
}
bool GObjectEventListener::operator==(const EventListener& listener)
diff --git a/WebCore/bindings/gobject/GObjectEventListener.h b/WebCore/bindings/gobject/GObjectEventListener.h
index 7ca2cc7..e5ad2e5 100644
--- a/WebCore/bindings/gobject/GObjectEventListener.h
+++ b/WebCore/bindings/gobject/GObjectEventListener.h
@@ -21,15 +21,34 @@
#include "EventListener.h"
-#include "PlatformString.h"
-#include <glib-object.h>
-#include <glib.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/CString.h>
+
+typedef struct _GObject GObject;
namespace WebCore {
+
+class DOMWindow;
+class Node;
+
class GObjectEventListener : public EventListener {
public:
- static PassRefPtr<GObjectEventListener> create(GObject* object, const char* signalName) { return adoptRef(new GObjectEventListener(object, signalName)); }
+
+ static void addEventListener(GObject* object, DOMWindow* window, const char* domEventName, const char* signalName)
+ {
+ RefPtr<GObjectEventListener> listener(adoptRef(new GObjectEventListener(object, window, 0, domEventName, signalName)));
+ }
+
+ static void addEventListener(GObject* object, Node* node, const char* domEventName, const char* signalName)
+ {
+ RefPtr<GObjectEventListener> listener(adoptRef(new GObjectEventListener(object, 0, node, domEventName, signalName)));
+ }
+
+ static void gobjectDestroyedCallback(GObjectEventListener* listener, GObject*)
+ {
+ listener->gobjectDestroyed();
+ }
+
static const GObjectEventListener* cast(const EventListener* listener)
{
return listener->type() == GObjectEventListenerType
@@ -40,17 +59,20 @@ public:
virtual bool operator==(const EventListener& other);
private:
- GObjectEventListener(GObject* object, const char* signalName)
- : EventListener(GObjectEventListenerType)
- , m_object(object)
- , m_signalName(signalName)
- {
- }
+ GObjectEventListener(GObject*, DOMWindow*, Node*, const char* domEventName, const char* signalName);
+ ~GObjectEventListener();
+ void gobjectDestroyed();
virtual void handleEvent(ScriptExecutionContext*, Event*);
GObject* m_object;
- String m_signalName;
+
+ // We do not need to keep a reference to these WebCore objects, because
+ // we only use them when the GObject and thus the WebCore object is alive.
+ Node* m_coreNode;
+ DOMWindow* m_coreWindow;
+ CString m_domEventName;
+ CString m_signalName;
};
} // namespace WebCore
diff --git a/WebCore/bindings/scripts/CodeGeneratorGObject.pm b/WebCore/bindings/scripts/CodeGeneratorGObject.pm
index dd9e3c7..6c450ad 100644
--- a/WebCore/bindings/scripts/CodeGeneratorGObject.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorGObject.pm
@@ -501,8 +501,7 @@ EOF
my ${listenerName} = $name . "Listener";
my $txtInstallEventListener = << "EOF";
- RefPtr<WebCore::GObjectEventListener> ${listenerName} = WebCore::GObjectEventListener::create(reinterpret_cast<GObject*>(object), "${gobjectSignalName}");
- coreObject->addEventListener("${name}", ${listenerName}, false);
+ WebCore::GObjectEventListener::addEventListener(object, coreObject, "${name}", "${gobjectSignalName}");
EOF
push(@txtInstallEventListeners, $txtInstallEventListener);
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list