Reviewed by Adam.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Oct 2006 13:15:04 +0000 (13:15 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Oct 2006 13:15:04 +0000 (13:15 +0000)
        - changed ResourceLoader to be refcounted

        It keeps a ref on itself while loading as well. This makes
        for a much saner memory management model than the previous.

        * bridge/mac/WebCoreResourceLoaderImp.mm:
        (-[WebCoreResourceLoaderImp finishJobAndHandle:]):
        * dom/XMLTokenizer.cpp:
        (WebCore::openFunc):
        * loader/icon/IconLoader.cpp:
        (IconLoader::IconLoader):
        (IconLoader::~IconLoader):
        (IconLoader::startLoading):
        (IconLoader::stopLoading):
        (IconLoader::receivedData):
        * loader/icon/IconLoader.h:
        * loader/loader.cpp:
        (WebCore::Loader::servePendingRequests):
        * platform/ResourceLoader.cpp:
        (WebCore::ResourceLoader::create):
        (WebCore::ResourceLoader::kill):
        * platform/ResourceLoader.h:
        * platform/ResourceLoaderInternal.h:
        (WebCore::ResourceLoaderInternal::ResourceLoaderInternal):
        * platform/mac/ResourceLoaderMac.mm:
        (WebCore::ResourceLoader::start):
        * xml/XSLTProcessor.cpp:
        (WebCore::docLoaderFunc):
        * xml/xmlhttprequest.cpp:
        (WebCore::XMLHttpRequest::send):
        * xml/xmlhttprequest.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@16803 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
WebCore/ChangeLog
WebCore/bridge/mac/WebCoreResourceLoaderImp.mm
WebCore/dom/XMLTokenizer.cpp
WebCore/loader/icon/IconLoader.cpp
WebCore/loader/icon/IconLoader.h
WebCore/loader/loader.cpp
WebCore/platform/ResourceLoader.cpp
WebCore/platform/ResourceLoader.h
WebCore/platform/ResourceLoaderInternal.h
WebCore/platform/mac/ResourceLoaderMac.mm
WebCore/xml/XSLTProcessor.cpp
WebCore/xml/xmlhttprequest.cpp
WebCore/xml/xmlhttprequest.h

index 27eb0ca1aa9306442b493640eb2545b3199d9bb9..60c585e65b6f5fe415d7ad54e618f05bde0e0c86 100644 (file)
@@ -1,3 +1,39 @@
+2006-10-05  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Adam.
+
+        - changed ResourceLoader to be refcounted
+
+        It keeps a ref on itself while loading as well. This makes
+        for a much saner memory management model than the previous.
+
+        * bridge/mac/WebCoreResourceLoaderImp.mm:
+        (-[WebCoreResourceLoaderImp finishJobAndHandle:]):
+        * dom/XMLTokenizer.cpp:
+        (WebCore::openFunc):
+        * loader/icon/IconLoader.cpp:
+        (IconLoader::IconLoader):
+        (IconLoader::~IconLoader):
+        (IconLoader::startLoading):
+        (IconLoader::stopLoading):
+        (IconLoader::receivedData):
+        * loader/icon/IconLoader.h:
+        * loader/loader.cpp:
+        (WebCore::Loader::servePendingRequests):
+        * platform/ResourceLoader.cpp:
+        (WebCore::ResourceLoader::create):
+        (WebCore::ResourceLoader::kill):
+        * platform/ResourceLoader.h:
+        * platform/ResourceLoaderInternal.h:
+        (WebCore::ResourceLoaderInternal::ResourceLoaderInternal):
+        * platform/mac/ResourceLoaderMac.mm:
+        (WebCore::ResourceLoader::start):
+        * xml/XSLTProcessor.cpp:
+        (WebCore::docLoaderFunc):
+        * xml/xmlhttprequest.cpp:
+        (WebCore::XMLHttpRequest::send):
+        * xml/xmlhttprequest.h:
+
 2006-10-05  Eric Seidel  <eric@eseidel.com>
 
         Reviewed by mjs.
index a6905119415d27b9658199326309e063016a5b14..a7c5ef7935b5a824fae1c182e445163be5ab47e8 100644 (file)
@@ -97,7 +97,7 @@ using namespace WebCore;
             client->receivedAllData(job, data);
             client->receivedAllData(job);
         }
-        delete job;
+        job->kill();
     }
     [handle release];
 }
index 2018646ab4af01ac3a1d8ef19ff228c05b41d5ec..1a9c33e836fda9475c79f3e954a9c8d17394f674 100644 (file)
@@ -458,9 +458,9 @@ static void* openFunc(const char* uri)
         return &globalDescriptor;
 
     KURL finalURL;
-    ResourceLoader* job = new ResourceLoader(0, "GET", uri);
+    RefPtr<ResourceLoader> loader = ResourceLoader::create(0, "GET", uri);
     DeprecatedString headers;
-    Vector<char> data = ServeSynchronousRequest(Cache::loader(), globalDocLoader, job, finalURL, headers);
+    Vector<char> data = ServeSynchronousRequest(Cache::loader(), globalDocLoader, loader.get(), finalURL, headers);
     
     return new OffsetBuffer(data);
 }
index 88e8eb8140972183197da0474bc179a591afd84e..50ebd6be06814c9e9e9fb1390c6a4a03ad77f8e8 100644 (file)
@@ -38,8 +38,7 @@
 using namespace WebCore;
 
 IconLoader::IconLoader(Frame* frame)
-    : m_resourceLoader(0)
-    , m_frame(frame)
+    : m_frame(frame)
     , m_httpStatusCode(0)
 {
 }
@@ -53,7 +52,8 @@ IconLoader* IconLoader::createForFrame(Frame* frame)
 
 IconLoader::~IconLoader()
 {
-    delete m_resourceLoader;
+    if (m_resourceLoader)
+        m_resourceLoader->kill();
 }
 
 void IconLoader::startLoading()
@@ -62,7 +62,7 @@ void IconLoader::startLoading()
         return;
     
     m_httpStatusCode = 0;
-    m_resourceLoader = new ResourceLoader(this, "GET", m_frame->iconURL());
+    m_resourceLoader = ResourceLoader::create(this, "GET", m_frame->iconURL());
     
     // A frame may be documentless - one example is viewing a PDF directly
     if (!m_frame->document()) {
@@ -71,20 +71,23 @@ void IconLoader::startLoading()
         LOG(IconDatabase, "Documentless-frame - icon won't be loaded");
     } else if (!m_resourceLoader->start(m_frame->document()->docLoader())) {
         LOG_ERROR("Failed to start load for icon at url %s", m_frame->iconURL().url().ascii());
+        if (m_resourceLoader)
+            m_resourceLoader->kill();
         m_resourceLoader = 0;
     }
 }
 
 void IconLoader::stopLoading()
 {
-    delete m_resourceLoader;
+    if (m_resourceLoader)
+        m_resourceLoader->kill();
     m_resourceLoader = 0;
     m_data.clear();
 }
 
 void IconLoader::receivedData(ResourceLoader* resourceLoader, const char* data, int size)
 {
-    ASSERT(resourceLoader = m_resourceLoader);
+    ASSERT(resourceLoader == m_resourceLoader);
     ASSERT(data);
     ASSERT(size > -1);
     
index 119da188962ed0ddadc2c7f8bd2bf35ccff22f6c..e712983ea88002cb1d22b5683157a1d596aa0ea5 100644 (file)
@@ -49,7 +49,7 @@ private:
     
     void notifyIconChanged(const KURL& iconURL);
     
-    ResourceLoader* m_resourceLoader;
+    RefPtr<ResourceLoader> m_resourceLoader;
     Frame* m_frame;
     
     static const int IconLoaderDefaultBuffer = 4096;
index 90bfb7cc334053203e63e2a2331ce17e2cde7cf5..650d444fd1f7709c12e1a48a6fd41eb0f114fd4a 100644 (file)
@@ -95,24 +95,24 @@ void Loader::servePendingRequests()
     Request* req = m_requestsPending.take(0);
 
     KURL u(req->cachedObject()->url().deprecatedString());
-    ResourceLoader* job = new ResourceLoader(this, "GET", u);
+    RefPtr<ResourceLoader> loader = ResourceLoader::create(this, "GET", u);
 
     if (!req->cachedObject()->accept().isEmpty())
-        job->addMetaData("accept", req->cachedObject()->accept());
+        loader->addMetaData("accept", req->cachedObject()->accept());
     if (req->docLoader())  {
         KURL r = req->docLoader()->doc()->URL();
         if (r.protocol().startsWith("http") && r.path().isEmpty())
             r.setPath("/");
-        job->addMetaData("referrer", r.url());
+        loader->addMetaData("referrer", r.url());
         DeprecatedString domain = r.host();
         if (req->docLoader()->doc()->isHTMLDocument())
             domain = static_cast<HTMLDocument*>(req->docLoader()->doc())->domain().deprecatedString();
         if (crossDomain(u.host(), domain))
-            job->addMetaData("cross-domain", "true");
+            loader->addMetaData("cross-domain", "true");
     }
 
-    if (job->start(req->docLoader()))
-        m_requestsLoading.add(job, req);
+    if (loader->start(req->docLoader()))
+        m_requestsLoading.add(loader.get(), req);
 }
 
 void Loader::receivedAllData(ResourceLoader* job, PlatformData allData)
index c11ffa6cc6276c45f6f99bcf0dfeb515f1a69917..9009b936f4a13288af99ea843f2f14d9e6b4e436 100644 (file)
@@ -42,6 +42,16 @@ ResourceLoader::ResourceLoader(ResourceLoaderClient* client, const String& metho
 {
 }
 
+PassRefPtr<ResourceLoader> ResourceLoader::create(ResourceLoaderClient* client, const String& method, const KURL& url)
+{
+    return new ResourceLoader(client, method, url);
+}
+
+PassRefPtr<ResourceLoader> ResourceLoader::create(ResourceLoaderClient* client, const String& method, const KURL& url, const FormData& postData)
+{
+    return new ResourceLoader(client, method, url, postData);
+}
+
 bool ResourceLoader::isErrorPage() const
 {
     return d->status != 0;
@@ -85,7 +95,12 @@ void ResourceLoader::addMetaData(const HashMap<String, String>& keysAndValues)
 
 void ResourceLoader::kill()
 {
-    delete this;
+    if (d->m_loading){
+        ASSERT(!d->m_cancelled);
+        d->m_loading = false;
+        d->m_cancelled = true;
+        deref();
+    }
 }
 
 KURL ResourceLoader::url() const
index d71935c514db081e727f7c941ee6999504bfc6cb..b13455d4e7a99023c02d68a896db766215e1f45a 100644 (file)
@@ -59,10 +59,15 @@ class FormData;
 class KURL;
 class ResourceLoaderInternal;
 
-class ResourceLoader {
-public:
+class ResourceLoader : public Shared<ResourceLoader> {
+private:
     ResourceLoader(ResourceLoaderClient*, const String& method, const KURL&);
     ResourceLoader(ResourceLoaderClient*, const String& method, const KURL&, const FormData& postData);
+
+public:
+    static PassRefPtr<ResourceLoader> create(ResourceLoaderClient*, const String& method, const KURL&);
+    static PassRefPtr<ResourceLoader> create(ResourceLoaderClient*, const String& method, const KURL&, const FormData& postData);    
+
     ~ResourceLoader();
 
     bool start(DocLoader*);
index 90e6209adbf3a0bdacc2facd642ba4258761cf09..ee56f4bbb97e33f71df63ff536544312bfbe8d54 100644 (file)
@@ -65,6 +65,8 @@ namespace WebCore {
             , method(method)
             , assembledResponseHeaders(true)
             , retrievedCharset(true)
+            , m_loading(false)
+            , m_cancelled(false)
 #if USE(CFNETWORK)
             , m_connection(0)
 #elif PLATFORM(MAC)
@@ -98,6 +100,8 @@ namespace WebCore {
             , postData(p)
             , assembledResponseHeaders(true)
             , retrievedCharset(true)
+            , m_loading(false)
+            , m_cancelled(false)
 #if USE(CFNETWORK)
             , m_connection(0)
 #elif PLATFORM(MAC)
@@ -136,7 +140,10 @@ namespace WebCore {
         bool assembledResponseHeaders;
         bool retrievedCharset;
         DeprecatedString responseHeaders;
-        
+    
+        bool m_loading;
+        bool m_cancelled;
+
 #if USE(CFNETWORK)
         CFURLConnectionRef m_connection;
 #elif PLATFORM(MAC)
index 5ae77e396e47926a761c1e736df116e101c50b6b..42010abd2543849b6c8df942c7f5755a076abf67 100644 (file)
@@ -57,11 +57,14 @@ ResourceLoader::~ResourceLoader()
 
 bool ResourceLoader::start(DocLoader* docLoader)
 {
+    ref();
+    d->m_loading = true;
+
     ASSERT(docLoader);
     
     FrameMac* frame = Mac(docLoader->frame());
     if (!frame) {
-        delete this;
+        kill();
         return false;
     }
 
@@ -93,7 +96,7 @@ bool ResourceLoader::start(DocLoader* docLoader)
 
     END_BLOCK_OBJC_EXCEPTIONS;
 
-    delete this;
+    kill();
     return false;
 }
 
index e737d536bd6dd390a89451d0fcc9349736d0d436..87f35984a7dacb9a6560903cc7d755a040fe0672 100644 (file)
@@ -85,12 +85,12 @@ static xmlDocPtr docLoaderFunc(const xmlChar *uri,
             KURL url((const char*)base, (const char*)uri);
             xmlFree(base);
             KURL finalURL;
-            ResourceLoader* job = new ResourceLoader(0, "GET", url);
+            RefPtr<ResourceLoader> loader = ResourceLoader::create(0, "GET", url);
             DeprecatedString headers;
             xmlGenericErrorFunc oldErrorFunc = xmlGenericError;
             void *oldErrorContext = xmlGenericErrorContext;
             
-            Vector<char> data = ServeSynchronousRequest(Cache::loader(), globalDocLoader, job, finalURL, headers);
+            Vector<char> data = ServeSynchronousRequest(Cache::loader(), globalDocLoader, loader.get(), finalURL, headers);
         
             xmlSetGenericErrorFunc(0, parseErrorFunc);
             // We don't specify an encoding here. Neither Gecko nor WinIE respects
index 458a47f6f15b425bdd9b8333f80b797ab1e48884..ef02a5b3af56a193eb2075adeb6e190c6121b11d 100644 (file)
@@ -314,12 +314,12 @@ void XMLHttpRequest::send(const String& body, ExceptionCode& ec)
         if (!m_encoding.isValid()) // FIXME: report an error?
             m_encoding = UTF8Encoding();
 
-        m_loader = new ResourceLoader(m_async ? this : 0, m_method, m_url, m_encoding.encode(body.characters(), body.length()));
+        m_loader = ResourceLoader::create(m_async ? this : 0, m_method, m_url, m_encoding.encode(body.characters(), body.length()));
     } else {
         // FIXME: HEAD requests just crash; see <rdar://4460899> and the commented out tests in http/tests/xmlhttprequest/methods.html.
         if (m_method == "HEAD")
             m_method = "GET";
-        m_loader = new ResourceLoader(m_async ? this : 0, m_method, m_url);
+        m_loader = ResourceLoader::create(m_async ? this : 0, m_method, m_url);
     }
 
     if (m_requestHeaders.length())
@@ -333,7 +333,7 @@ void XMLHttpRequest::send(const String& body, ExceptionCode& ec)
         {
             // avoid deadlock in case the loader wants to use JS on a background thread
             KJS::JSLock::DropAllLocks dropLocks;
-            data = ServeSynchronousRequest(Cache::loader(), m_doc->docLoader(), m_loader, finalURL, headers);
+            data = ServeSynchronousRequest(Cache::loader(), m_doc->docLoader(), m_loader.get(), finalURL, headers);
         }
 
         m_loader = 0;
index 7db7fe477c31fd07de8e92e0b31664f34561381f..fa932a01cf8c5813a45d33bb29d31cd8b84fdb10 100644 (file)
@@ -101,7 +101,7 @@ private:
     bool m_async;
     DeprecatedString m_requestHeaders;
 
-    ResourceLoader* m_loader;
+    RefPtr<ResourceLoader> m_loader;
 
     XMLHttpRequestState m_state;