Changeset 168054 in webkit


Ignore:
Timestamp:
Apr 30, 2014, 3:52:30 PM (11 years ago)
Author:
ap@apple.com
Message:

Move Blob.slice() implementation into BlobRegistryImpl
https://bugs.webkit.org/show_bug.cgi?id=132402

Reviewed by Anders Carlsson.

Source/WebCore:
Part or centralizing the responsibility for file size tracking.

  • fileapi/Blob.cpp:

(WebCore::Blob::Blob):
(WebCore::Blob::slice): Deleted.

  • fileapi/Blob.h:

(WebCore::Blob::slice):

  • fileapi/ThreadableBlobRegistry.cpp:

(WebCore::ThreadableBlobRegistry::registerBlobURL):
(WebCore::ThreadableBlobRegistry::registerBlobURLForSlice):
(WebCore::registerBlobURLTask): Deleted.
(WebCore::registerBlobURLFromTask): Deleted.

  • fileapi/ThreadableBlobRegistry.h:
  • platform/network/BlobRegistry.h:
  • platform/network/BlobRegistryImpl.cpp:

(WebCore::BlobRegistryImpl::appendStorageItems):
(WebCore::BlobRegistryImpl::registerBlobURLForSlice):
(WebCore::BlobRegistryImpl::blobSize):

  • platform/network/BlobRegistryImpl.h:

Source/WebKit2:

  • NetworkProcess/FileAPI/NetworkBlobRegistry.cpp:

(WebKit::NetworkBlobRegistry::registerBlobURLForSlice):

  • NetworkProcess/FileAPI/NetworkBlobRegistry.h:
  • NetworkProcess/NetworkConnectionToWebProcess.cpp:

(WebKit::NetworkConnectionToWebProcess::registerBlobURLForSlice):

  • NetworkProcess/NetworkConnectionToWebProcess.h:
  • NetworkProcess/NetworkConnectionToWebProcess.messages.in:
  • WebProcess/FileAPI/BlobRegistryProxy.cpp:

(WebKit::BlobRegistryProxy::registerBlobURLForSlice):

  • WebProcess/FileAPI/BlobRegistryProxy.h:
Location:
trunk/Source
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r168052 r168054  
     12014-04-30  Alexey Proskuryakov  <ap@apple.com>
     2
     3        Move Blob.slice() implementation into BlobRegistryImpl
     4        https://bugs.webkit.org/show_bug.cgi?id=132402
     5
     6        Reviewed by Anders Carlsson.
     7
     8        Part or centralizing the responsibility for file size tracking.
     9
     10        * fileapi/Blob.cpp:
     11        (WebCore::Blob::Blob):
     12        (WebCore::Blob::slice): Deleted.
     13        * fileapi/Blob.h:
     14        (WebCore::Blob::slice):
     15        * fileapi/ThreadableBlobRegistry.cpp:
     16        (WebCore::ThreadableBlobRegistry::registerBlobURL):
     17        (WebCore::ThreadableBlobRegistry::registerBlobURLForSlice):
     18        (WebCore::registerBlobURLTask): Deleted.
     19        (WebCore::registerBlobURLFromTask): Deleted.
     20        * fileapi/ThreadableBlobRegistry.h:
     21        * platform/network/BlobRegistry.h:
     22        * platform/network/BlobRegistryImpl.cpp:
     23        (WebCore::BlobRegistryImpl::appendStorageItems):
     24        (WebCore::BlobRegistryImpl::registerBlobURLForSlice):
     25        (WebCore::BlobRegistryImpl::blobSize):
     26        * platform/network/BlobRegistryImpl.h:
     27
    1282014-04-30  Brent Fulgham  <bfulgham@apple.com>
    229
  • trunk/Source/WebCore/fileapi/Blob.cpp

    r168032 r168054  
    9898}
    9999
     100#if ENABLE(BLOB)
     101Blob::Blob(const URL& srcURL, long long start, long long end, const String& type)
     102    : m_type(Blob::normalizedContentType(type))
     103{
     104    // Create a new internal URL and register it with the same blob data as the source URL.
     105    m_internalURL = BlobURL::createInternalURL();
     106    m_size = ThreadableBlobRegistry::registerBlobURLForSlice(m_internalURL, srcURL, start, end);
     107}
     108#endif
     109
    100110Blob::~Blob()
    101111{
     
    171181}
    172182
    173 #if ENABLE(BLOB)
    174 PassRefPtr<Blob> Blob::slice(long long start, long long end, const String& contentType) const
    175 {
    176     // When we slice a file for the first time, we obtain a snapshot of the file by capturing its current size and modification time.
    177     // The modification time will be used to verify if the file has been changed or not, when the underlying data are accessed.
    178     long long size;
    179     double modificationTime;
    180     if (isFile()) {
    181         // FIXME: This involves synchronous file operation. We need to figure out how to make it asynchronous.
    182         toFile(this)->captureSnapshot(size, modificationTime);
    183     } else {
    184         ASSERT(m_size != -1);
    185         size = m_size;
    186     }
    187 
    188     // Convert the negative value that is used to select from the end.
    189     if (start < 0)
    190         start = start + size;
    191     if (end < 0)
    192         end = end + size;
    193 
    194     // Clamp the range if it exceeds the size limit.
    195     if (start < 0)
    196         start = 0;
    197     if (end < 0)
    198         end = 0;
    199     if (start >= size) {
    200         start = 0;
    201         end = 0;
    202     } else if (end < start)
    203         end = start;
    204     else if (end > size)
    205         end = size;
    206 
    207     long long length = end - start;
    208     auto blobData = std::make_unique<BlobData>();
    209     blobData->setContentType(Blob::normalizedContentType(contentType));
    210     if (isFile())
    211         blobData->appendFile(toFile(this)->path(), start, length, modificationTime);
    212     else
    213         blobData->appendBlob(m_internalURL, start, length);
    214 
    215     return Blob::create(std::move(blobData), length);
    216 }
    217 #endif
    218 
    219183URLRegistry& Blob::registry() const
    220184{
  • trunk/Source/WebCore/fileapi/Blob.h

    r162139 r168054  
    8383
    8484#if ENABLE(BLOB)
    85     PassRefPtr<Blob> slice(long long start = 0, long long end = std::numeric_limits<long long>::max(), const String& contentType = String()) const;
     85    PassRefPtr<Blob> slice(long long start = 0, long long end = std::numeric_limits<long long>::max(), const String& contentType = String()) const
     86    {
     87        return adoptRef(new Blob(m_internalURL, start, end, contentType));
     88    }
    8689#endif
    8790
     
    9295    // For deserialization.
    9396    Blob(const URL& srcURL, const String& type, long long size);
     97
     98#if ENABLE(BLOB)
     99    // For slicing.
     100    Blob(const URL& srcURL, long long start, long long end, const String& contentType);
     101#endif
    94102
    95103    // This is an internal URL referring to the blob data associated with this object. It serves
  • trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp

    r161847 r168054  
    4242#include <wtf/ThreadSpecific.h>
    4343#include <wtf/text/StringHash.h>
     44#include <wtf/threads/BinarySemaphore.h>
    4445
    4546using WTF::ThreadSpecific;
     
    8889}
    8990
    90 static void registerBlobURLTask(void* context)
    91 {
    92     std::unique_ptr<BlobRegistryContext> blobRegistryContext(static_cast<BlobRegistryContext*>(context));
    93     blobRegistry().registerBlobURL(blobRegistryContext->url, std::move(blobRegistryContext->blobData));
    94 }
    95 
    9691void ThreadableBlobRegistry::registerBlobURL(const URL& url, std::unique_ptr<BlobData> blobData)
    9792{
    9893    if (isMainThread())
    9994        blobRegistry().registerBlobURL(url, std::move(blobData));
    100     else
    101         callOnMainThread(&registerBlobURLTask, new BlobRegistryContext(url, std::move(blobData)));
    102 }
    103 
    104 static void registerBlobURLFromTask(void* context)
    105 {
    106     std::unique_ptr<BlobRegistryContext> blobRegistryContext(static_cast<BlobRegistryContext*>(context));
    107     blobRegistry().registerBlobURL(blobRegistryContext->url, blobRegistryContext->srcURL);
     95    else {
     96        // BlobRegistryContext performs an isolated copy of data.
     97        BlobRegistryContext* context = new BlobRegistryContext(url, std::move(blobData));
     98        callOnMainThread([context] {
     99            std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
     100            blobRegistry().registerBlobURL(blobRegistryContext->url, std::move(blobRegistryContext->blobData));
     101        });
     102    }
    108103}
    109104
     
    116111    if (isMainThread())
    117112        blobRegistry().registerBlobURL(url, srcURL);
    118     else
    119         callOnMainThread(&registerBlobURLFromTask, new BlobRegistryContext(url, srcURL));
     113    else {
     114        // BlobRegistryContext performs an isolated copy of data.
     115        BlobRegistryContext* context = new BlobRegistryContext(url, srcURL);
     116        callOnMainThread([context] {
     117            std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
     118            blobRegistry().registerBlobURL(blobRegistryContext->url, blobRegistryContext->srcURL);
     119        });
     120    }
     121}
     122
     123unsigned long long ThreadableBlobRegistry::registerBlobURLForSlice(const URL& newURL, const URL& srcURL, long long start, long long end)
     124{
     125    unsigned long long resultSize;
     126    if (isMainThread())
     127        resultSize = blobRegistry().registerBlobURLForSlice(newURL, srcURL, start, end);
     128    else {
     129        // BlobRegistryContext performs an isolated copy of data.
     130        BlobRegistryContext* context = new BlobRegistryContext(newURL, srcURL);
     131        BinarySemaphore semaphore;
     132        callOnMainThread([context, start, end, &semaphore, &resultSize] {
     133            std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
     134            resultSize = blobRegistry().registerBlobURLForSlice(blobRegistryContext->url, blobRegistryContext->srcURL, start, end);
     135            semaphore.signal();
     136        });
     137        semaphore.wait(std::numeric_limits<double>::max());
     138    }
     139    return resultSize;
    120140}
    121141
  • trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h

    r156688 r168054  
    4646    static void unregisterBlobURL(const URL&);
    4747
     48    static unsigned long long registerBlobURLForSlice(const URL& newURL, const URL& srcURL, long long start, long long end);
     49
    4850    // Returns the origin for the given blob URL. This is because we are not able to embed the unique security origin or the origin of file URL
    4951    // in the blob URL.
  • trunk/Source/WebCore/platform/network/BlobRegistry.h

    r156688 r168054  
    5252    virtual void registerBlobURL(const URL&, const URL& srcURL) = 0;
    5353
     54    // Negative start and end values select from the end.
     55    virtual unsigned long long registerBlobURLForSlice(const URL&, const URL& srcURL, long long start, long long end) = 0;
     56
    5457    virtual void unregisterBlobURL(const URL&) = 0;
    5558
  • trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp

    r167979 r168054  
    3737#include "BlobResourceHandle.h"
    3838#include "BlobStorageData.h"
     39#include "FileMetadata.h"
     40#include "FileSystem.h"
    3941#include "ResourceError.h"
    4042#include "ResourceHandle.h"
     
    100102
    101103    for (; iter != items.end() && length > 0; ++iter) {
     104        ASSERT(iter->length != BlobDataItem::toEndOfFile);
    102105        long long currentLength = iter->length - offset;
    103106        long long newLength = currentLength > length ? length : currentLength;
     
    157160}
    158161
     162unsigned long long BlobRegistryImpl::registerBlobURLForSlice(const URL& url, const URL& srcURL, long long start, long long end)
     163{
     164    ASSERT(isMainThread());
     165    BlobStorageData* originalStorageData = m_blobs.get(srcURL.string());
     166    if (!originalStorageData)
     167        return 0;
     168
     169    unsigned long long originalSize = blobSize(srcURL);
     170
     171    // Convert the negative value that is used to select from the end.
     172    if (start < 0)
     173        start = start + originalSize;
     174    if (end < 0)
     175        end = end + originalSize;
     176
     177    // Clamp the range if it exceeds the size limit.
     178    if (start < 0)
     179        start = 0;
     180    if (end < 0)
     181        end = 0;
     182    if (static_cast<unsigned long long>(start) >= originalSize) {
     183        start = 0;
     184        end = 0;
     185    } else if (end < start)
     186        end = start;
     187    else if (static_cast<unsigned long long>(end) > originalSize)
     188        end = originalSize;
     189
     190    unsigned long long newLength = end - start;
     191    RefPtr<BlobStorageData> newStorageData = BlobStorageData::create(originalStorageData->contentType(), originalStorageData->contentDisposition());
     192
     193    appendStorageItems(newStorageData.get(), originalStorageData->items(), start, newLength);
     194
     195    m_blobs.set(url.string(), newStorageData.release());
     196    return newLength;
     197}
     198
    159199void BlobRegistryImpl::unregisterBlobURL(const URL& url)
    160200{
     
    169209}
    170210
     211unsigned long long BlobRegistryImpl::blobSize(const URL& url)
     212{
     213    ASSERT(isMainThread());
     214    BlobStorageData* storageData = m_blobs.get(url.string());
     215    if (!storageData)
     216        return 0;
     217
     218    unsigned long long result = 0;
     219    for (const BlobDataItem& item : storageData->items()) {
     220        if (item.length == BlobDataItem::toEndOfFile) {
     221            FileMetadata metadata;
     222            if (!getFileMetadata(item.path, metadata))
     223                return 0;
     224
     225            // FIXME: Factor out size and modification tracking for a cleaner implementation.
     226            const_cast<BlobDataItem&>(item).length = metadata.length;
     227            const_cast<BlobDataItem&>(item).expectedModificationTime = metadata.modificationTime;
     228        }
     229        result += item.length;
     230    }
     231    return result;
     232}
     233
    171234} // namespace WebCore
    172235
  • trunk/Source/WebCore/platform/network/BlobRegistryImpl.h

    r167979 r168054  
    6060    virtual void registerBlobURL(const URL&, std::unique_ptr<BlobData>) override;
    6161    virtual void registerBlobURL(const URL&, const URL& srcURL) override;
     62    virtual unsigned long long registerBlobURLForSlice(const URL&, const URL& srcURL, long long start, long long end) override;
    6263    virtual void unregisterBlobURL(const URL&) override;
    6364    virtual bool isBlobRegistryImpl() const override { return true; }
     65
     66    unsigned long long blobSize(const URL&);
    6467
    6568    HashMap<String, RefPtr<BlobStorageData>> m_blobs;
  • trunk/Source/WebKit2/ChangeLog

    r168053 r168054  
     12014-04-30  Alexey Proskuryakov  <ap@apple.com>
     2
     3        Move Blob.slice() implementation into BlobRegistryImpl
     4        https://bugs.webkit.org/show_bug.cgi?id=132402
     5
     6        Reviewed by Anders Carlsson.
     7
     8        * NetworkProcess/FileAPI/NetworkBlobRegistry.cpp:
     9        (WebKit::NetworkBlobRegistry::registerBlobURLForSlice):
     10        * NetworkProcess/FileAPI/NetworkBlobRegistry.h:
     11        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     12        (WebKit::NetworkConnectionToWebProcess::registerBlobURLForSlice):
     13        * NetworkProcess/NetworkConnectionToWebProcess.h:
     14        * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
     15        * WebProcess/FileAPI/BlobRegistryProxy.cpp:
     16        (WebKit::BlobRegistryProxy::registerBlobURLForSlice):
     17        * WebProcess/FileAPI/BlobRegistryProxy.h:
     18
    1192014-04-30  Beth Dakin  <bdakin@apple.com>
    220
  • trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp

    r164255 r168054  
    8585}
    8686
     87uint64_t NetworkBlobRegistry::registerBlobURLForSlice(NetworkConnectionToWebProcess* connection, const WebCore::URL& url, const WebCore::URL& srcURL, int64_t start, int64_t end)
     88{
     89    uint64_t resultSize = blobRegistry().registerBlobURLForSlice(url, srcURL, start, end);
     90
     91    // FIXME: Only store extensions for files that the slice actually contains, not for all the files in original blob.
     92    SandboxExtensionMap::iterator iter = m_sandboxExtensions.find(srcURL.string());
     93    if (iter != m_sandboxExtensions.end())
     94        m_sandboxExtensions.add(url.string(), iter->value);
     95
     96    ASSERT(m_blobsForConnection.contains(connection));
     97    ASSERT(m_blobsForConnection.find(connection)->value.contains(srcURL));
     98    m_blobsForConnection.find(connection)->value.add(url);
     99
     100    return resultSize;
     101}
     102
    87103void NetworkBlobRegistry::unregisterBlobURL(NetworkConnectionToWebProcess* connection, const WebCore::URL& url)
    88104{
  • trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h

    r156688 r168054  
    5050    void registerBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&, std::unique_ptr<WebCore::BlobData>, const Vector<RefPtr<SandboxExtension>>&);
    5151    void registerBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&, const WebCore::URL& srcURL);
     52    uint64_t registerBlobURLForSlice(NetworkConnectionToWebProcess*, const WebCore::URL&, const WebCore::URL& srcURL, int64_t start, int64_t end);
    5253    void unregisterBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&);
    5354
  • trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp

    r167866 r168054  
    242242}
    243243
     244void NetworkConnectionToWebProcess::registerBlobURLForSlice(const URL& url, const URL& srcURL, int64_t start, int64_t end, uint64_t& resultSize)
     245{
     246    resultSize = NetworkBlobRegistry::shared().registerBlobURLForSlice(this, url, srcURL, start, end);
     247}
     248
    244249void NetworkConnectionToWebProcess::unregisterBlobURL(const URL& url)
    245250{
  • trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h

    r167635 r168054  
    9191    void registerBlobURL(const WebCore::URL&, const BlobRegistrationData&);
    9292    void registerBlobURLFromURL(const WebCore::URL&, const WebCore::URL& srcURL);
     93    void registerBlobURLForSlice(const WebCore::URL&, const WebCore::URL& srcURL, int64_t start, int64_t end, uint64_t& resultSize);
    9394    void unregisterBlobURL(const WebCore::URL&);
    9495#endif
  • trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in

    r167635 r168054  
    4747    RegisterBlobURL(WebCore::URL url, WebKit::BlobRegistrationData data)
    4848    RegisterBlobURLFromURL(WebCore::URL url, WebCore::URL srcURL)
     49    RegisterBlobURLForSlice(WebCore::URL url, WebCore::URL srcURL, int64_t start, int64_t end) -> (uint64_t resultSize)
    4950    UnregisterBlobURL(WebCore::URL url)
    5051#endif
  • trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.cpp

    r156688 r168054  
    6161}
    6262
     63unsigned long long BlobRegistryProxy::registerBlobURLForSlice(const URL& url, const URL& srcURL, long long start, long long end)
     64{
     65    ASSERT(WebProcess::shared().usesNetworkProcess());
     66
     67    uint64_t resultSize;
     68    if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::RegisterBlobURLForSlice(url, srcURL, start, end), Messages::NetworkConnectionToWebProcess::RegisterBlobURLForSlice::Reply(resultSize), 0))
     69        return 0;
     70    return resultSize;
     71}
     72
    6373}
    6474
  • trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.h

    r162139 r168054  
    3838    virtual void registerBlobURL(const WebCore::URL&, const WebCore::URL& srcURL) override;
    3939    virtual void unregisterBlobURL(const WebCore::URL&) override;
     40    virtual unsigned long long registerBlobURLForSlice(const WebCore::URL&, const WebCore::URL& srcURL, long long start, long long end) override;
    4041};
    4142
Note: See TracChangeset for help on using the changeset viewer.