Changeset 24459 in webkit


Ignore:
Timestamp:
Jul 19, 2007 7:59:04 PM (17 years ago)
Author:
andersca
Message:

Reviewed by Adam.

<rdar://problem/5334742>
Windows Beta: Crash playing a very large QuickTime movie in Safari


<rdar://problem/5271174>
http://bugs.webkit.org/show_bug.cgi?id=14148
LEAK: Serious memory consumption and leak when loading QT movies.


Don't keep plugin stream data in memory since some plugin resources (like QT movies)
can be really big. If a plug-in wants data in a file, create a file and write data to it
as it's coming from the wire, instead of using a big buffer.


  • loader/ResourceLoader.cpp: (WebCore::ResourceLoader::ResourceLoader): (WebCore::ResourceLoader::addData): (WebCore::ResourceLoader::willStopBufferingData):
  • loader/ResourceLoader.h: (WebCore::ResourceLoader::setShouldBufferData):
  • plugins/win/PluginStreamWin.cpp: (WebCore::PluginStreamWin::PluginStreamWin): (WebCore::PluginStreamWin::start): (WebCore::PluginStreamWin::startStream): (WebCore::PluginStreamWin::destroyStream): (WebCore::PluginStreamWin::didReceiveData): (WebCore::PluginStreamWin::didFinishLoading):
  • plugins/win/PluginStreamWin.h:
Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r24456 r24459  
     12007-07-19  Anders Carlsson  <andersca@apple.com>
     2
     3        Reviewed by Adam.
     4
     5        <rdar://problem/5334742>
     6        Windows Beta: Crash playing a very large QuickTime movie in Safari
     7       
     8        <rdar://problem/5271174>
     9        http://bugs.webkit.org/show_bug.cgi?id=14148
     10        LEAK: Serious memory consumption and leak when loading QT movies.
     11       
     12        Don't keep plugin stream data in memory since some plugin resources (like QT movies)
     13        can be really big. If a plug-in wants data in a file, create a file and write data to it
     14        as it's coming from the wire, instead of using a big buffer.
     15       
     16        * loader/ResourceLoader.cpp:
     17        (WebCore::ResourceLoader::ResourceLoader):
     18        (WebCore::ResourceLoader::addData):
     19        (WebCore::ResourceLoader::willStopBufferingData):
     20        * loader/ResourceLoader.h:
     21        (WebCore::ResourceLoader::setShouldBufferData):
     22        * plugins/win/PluginStreamWin.cpp:
     23        (WebCore::PluginStreamWin::PluginStreamWin):
     24        (WebCore::PluginStreamWin::start):
     25        (WebCore::PluginStreamWin::startStream):
     26        (WebCore::PluginStreamWin::destroyStream):
     27        (WebCore::PluginStreamWin::didReceiveData):
     28        (WebCore::PluginStreamWin::didFinishLoading):
     29        * plugins/win/PluginStreamWin.h:
     30
    1312007-07-19  Geoffrey Garen  <ggaren@apple.com>
    232
  • trunk/WebCore/loader/ResourceLoader.cpp

    r24087 r24459  
    5858    , m_calledDidFinishLoad(false)
    5959    , m_sendResourceLoadCallbacks(sendResourceLoadCallbacks)
     60    , m_shouldBufferData(true)
    6061    , m_frame(frame)
    6162    , m_documentLoader(frame->loader()->activeDocumentLoader())
     
    143144void ResourceLoader::addData(const char* data, int length, bool allAtOnce)
    144145{
     146    if (!m_shouldBufferData)
     147        return;
     148
    145149    if (allAtOnce) {
    146150        m_resourceData = new SharedBuffer(data, length);
     
    222226void ResourceLoader::willStopBufferingData(const char* data, int length)
    223227{
     228    if (!m_shouldBufferData)
     229        return;
     230
    224231    ASSERT(!m_resourceData);
    225232    m_resourceData = new SharedBuffer(data, length);
  • trunk/WebCore/loader/ResourceLoader.h

    r23741 r24459  
    106106        bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
    107107
     108        void setShouldBufferData(bool shouldBufferData) { m_shouldBufferData = shouldBufferData; }
     109
    108110    protected:
    109111        ResourceLoader(Frame*, bool sendResourceLoadCallbacks);
     
    128130
    129131        bool m_sendResourceLoadCallbacks;
     132        bool m_shouldBufferData;
    130133protected:
    131134        // FIXME: Once everything is made cross platform, these can be private instead of protected
  • trunk/WebCore/plugins/win/PluginStreamWin.cpp

    r23906 r24459  
    6868    , m_delayDeliveryTimer(this, &PluginStreamWin::delayDeliveryTimerFired)
    6969    , m_deliveryData(0)
     70    , m_tempFileHandle(INVALID_HANDLE_VALUE)
    7071    , m_pluginFuncs(pluginView->plugin()->pluginFuncs())
    7172    , m_instance(pluginView->instance())
     
    9899{
    99100    m_loader = SubresourceLoader::create(m_frame, this, m_resourceRequest);
     101    m_loader->setShouldBufferData(false);
    100102}
    101103
     
    148150    if (npErr != NPERR_NO_ERROR)
    149151        cancelAndDestroyStream(npErr);
     152
     153    if (m_transferMode == NP_NORMAL)
     154        return;
     155   
     156    char tempPath[MAX_PATH];
     157
     158    int result = ::GetTempPathA(_countof(tempPath), tempPath);
     159    if (result > 0 && result <= _countof(tempPath)) {
     160        char tempFile[MAX_PATH];
     161
     162        if (::GetTempFileNameA(tempPath, "WKP", 0, tempFile) > 0) {
     163            m_tempFileHandle = ::CreateFileA(tempFile, GENERIC_READ | GENERIC_WRITE, 0, 0,
     164                CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     165
     166            if (m_tempFileHandle != INVALID_HANDLE_VALUE) {
     167                m_path = tempFile;
     168                return;
     169            }
     170        }
     171    }
     172
     173    // Something went wrong, cancel loading the stream
     174    cancelAndDestroyStream(NPRES_NETWORK_ERR);
    150175}
    151176
     
    190215
    191216            m_pluginFuncs->asfile(m_instance, &m_stream, m_path.data());
    192             DeleteFileA(m_path.data());
    193217        }
    194218
     
    210234
    211235    m_pluginView = 0;
     236
     237    if (m_tempFileHandle != INVALID_HANDLE_VALUE)
     238        ::CloseHandle(m_tempFileHandle);
     239
     240    if (!m_path.isNull())
     241        ::DeleteFileA(m_path.data());
    212242}
    213243
     
    311341    if (m_transferMode != NP_ASFILEONLY)
    312342        deliverData();
     343
     344    if (m_streamState != StreamStopped && m_tempFileHandle != INVALID_HANDLE_VALUE) {
     345        DWORD written;
     346        bool retval = true;
     347
     348        retval = WriteFile(m_tempFileHandle, data, length, &written, 0);
     349
     350        if (!retval || (int)written != length)
     351            cancelAndDestroyStream(NPRES_NETWORK_ERR);
     352    }
     353
    313354}
    314355
     
    330371    m_loader = 0;
    331372
    332     if ((m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY) && m_path.isNull()) {
    333         char tempPath[MAX_PATH];
    334 
    335         if (GetTempPathA(sizeof(tempPath), tempPath) == 0) {
    336             LOG_PLUGIN_NET_ERROR();
    337             destroyStream(NPRES_NETWORK_ERR);
    338             return;
    339         }
    340 
    341         char tempName[MAX_PATH];
    342 
    343         if (GetTempFileNameA(tempPath, "WKP", 0, tempName) == 0) {
    344             LOG_PLUGIN_NET_ERROR();
    345             destroyStream(NPRES_NETWORK_ERR);
    346             return;
    347         }
    348 
    349         HANDLE tempFile = CreateFileA(tempName, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    350 
    351         if (tempFile == INVALID_HANDLE_VALUE) {
    352             LOG_PLUGIN_NET_ERROR();
    353             destroyStream(NPRES_NETWORK_ERR);
    354             return;
    355         }
    356 
    357         DWORD written;
    358         RefPtr<SharedBuffer> resourceData = loader->resourceData();
    359         size_t dataSize = resourceData ? resourceData->size() : 0;
    360         bool retval = true;
    361 
    362         if (dataSize)
    363             retval = WriteFile(tempFile, resourceData->data(), dataSize, &written, 0);
    364         CloseHandle(tempFile);
    365 
    366         if (!retval || written != dataSize) {
    367             LOG_PLUGIN_NET_ERROR();
    368             destroyStream(NPRES_NETWORK_ERR);
    369             return;
    370         }
    371 
    372         m_path = tempName;
    373     }
    374 
    375373    destroyStream(NPRES_DONE);
    376374}
  • trunk/WebCore/plugins/win/PluginStreamWin.h

    r23745 r24459  
    8888        Vector<char>* m_deliveryData;
    8989
     90        HANDLE m_tempFileHandle;
     91
    9092        const NPPluginFuncs* m_pluginFuncs;
    9193        NPP m_instance;
Note: See TracChangeset for help on using the changeset viewer.