<rdar://problem/5453494> Better lifetime management of WebDataSource and...
[WebKit-https.git] / WebKit / win / WebDocumentLoader.cpp
index caba735fdf315e15d1e1139686c7c2baa763bdcf..f333c67fb3cd29a1e6d652e7f56c68ae4a071aad 100644 (file)
@@ -31,18 +31,38 @@ using namespace WebCore;
 
 WebDocumentLoader::WebDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
     : DocumentLoader(request, substituteData)
+    , m_dataSource(0)
     , m_detachedDataSource(0)
 {
 }
 
+WebDocumentLoader::~WebDocumentLoader()
+{
+    if (m_dataSource) {
+        ASSERT(!m_detachedDataSource);
+        m_dataSource->Release();
+    }
+}
+
 void WebDocumentLoader::setDataSource(WebDataSource *dataSource)
 {
+    ASSERT(!m_dataSource);
     m_dataSource = dataSource;
+    if (m_dataSource)
+        m_dataSource->AddRef();
 }
 
 WebDataSource* WebDocumentLoader::dataSource() const
 {
-    return m_dataSource.get();
+    return m_dataSource;
+}
+
+void WebDocumentLoader::detachDataSource()
+{
+    // we only call detachDataSource when the WebDataSource is freed - and we won't get there if m_dataSource is not
+    // null (because that would mean the loader still has a reference to the data source)
+    ASSERT(!m_dataSource);
+    m_detachedDataSource = 0;
 }
 
 void WebDocumentLoader::attachToFrame()
@@ -50,7 +70,7 @@ void WebDocumentLoader::attachToFrame()
     DocumentLoader::attachToFrame();
     if (m_detachedDataSource) {
         ASSERT(!m_dataSource);
-        m_dataSource = m_detachedDataSource;
+        setDataSource(m_detachedDataSource);
         m_detachedDataSource = 0;
     }
 }
@@ -58,6 +78,13 @@ void WebDocumentLoader::attachToFrame()
 void WebDocumentLoader::detachFromFrame()
 {
     DocumentLoader::detachFromFrame();
-    m_detachedDataSource = m_dataSource.get();
-    m_dataSource = 0;
+    m_detachedDataSource = m_dataSource;
+    if (m_dataSource) {
+        WebDataSource* dataSourceToBeReleased = m_dataSource;
+        // It's important to null out m_dataSource before calling release on the data source.  That release can cause the data
+        // source to be deleted - which ends up calling loader->detachDataSource() which makes the assumption that the loader no 
+        // longer holds a reference to the data source.
+        m_dataSource = 0;
+        dataSourceToBeReleased->Release();
+    }
 }