summaryrefslogtreecommitdiff
path: root/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/fileapi/ThreadableBlobRegistry.cpp')
-rw-r--r--Source/WebCore/fileapi/ThreadableBlobRegistry.cpp144
1 files changed, 78 insertions, 66 deletions
diff --git a/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp b/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp
index 19844412e..b6c57a31d 100644
--- a/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp
+++ b/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,49 +32,25 @@
#include "config.h"
#include "ThreadableBlobRegistry.h"
-#include "BlobData.h"
+#include "BlobDataFileReference.h"
+#include "BlobPart.h"
#include "BlobRegistry.h"
#include "BlobURL.h"
#include "SecurityOrigin.h"
#include <mutex>
+#include <wtf/CrossThreadQueue.h>
+#include <wtf/CrossThreadTask.h>
#include <wtf/HashMap.h>
#include <wtf/MainThread.h>
#include <wtf/RefPtr.h>
#include <wtf/ThreadSpecific.h>
#include <wtf/text/StringHash.h>
+#include <wtf/threads/BinarySemaphore.h>
using WTF::ThreadSpecific;
namespace WebCore {
-struct BlobRegistryContext {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- BlobRegistryContext(const URL& url, std::unique_ptr<BlobData> blobData)
- : url(url.copy())
- , blobData(std::move(blobData))
- {
- this->blobData->detachFromCurrentThread();
- }
-
- BlobRegistryContext(const URL& url, const URL& srcURL)
- : url(url.copy())
- , srcURL(srcURL.copy())
- {
- }
-
- BlobRegistryContext(const URL& url)
- : url(url.copy())
- {
- }
-
- URL url;
- URL srcURL;
- std::unique_ptr<BlobData> blobData;
-};
-
-#if ENABLE(BLOB)
-
typedef HashMap<String, RefPtr<SecurityOrigin>> BlobUrlOriginMap;
static ThreadSpecific<BlobUrlOriginMap>& originMap()
@@ -87,24 +64,45 @@ static ThreadSpecific<BlobUrlOriginMap>& originMap()
return *map;
}
-static void registerBlobURLTask(void* context)
+static void postToMainThread(CrossThreadTask&& task)
{
- std::unique_ptr<BlobRegistryContext> blobRegistryContext(static_cast<BlobRegistryContext*>(context));
- blobRegistry().registerBlobURL(blobRegistryContext->url, std::move(blobRegistryContext->blobData));
+ static std::once_flag onceFlag;
+ static CrossThreadQueue<CrossThreadTask>* queue;
+ std::call_once(onceFlag, [] {
+ queue = new CrossThreadQueue<CrossThreadTask>;
+ });
+
+ queue->append(WTFMove(task));
+
+ callOnMainThread([] {
+ auto task = queue->tryGetMessage();
+ ASSERT(task);
+ task->performTask();
+ });
}
-void ThreadableBlobRegistry::registerBlobURL(const URL& url, std::unique_ptr<BlobData> blobData)
+void ThreadableBlobRegistry::registerFileBlobURL(const URL& url, const String& path, const String& contentType)
{
if (isMainThread())
- blobRegistry().registerBlobURL(url, std::move(blobData));
- else
- callOnMainThread(&registerBlobURLTask, new BlobRegistryContext(url, std::move(blobData)));
+ blobRegistry().registerFileBlobURL(url, BlobDataFileReference::create(path), contentType);
+ else {
+ callOnMainThread([url = url.isolatedCopy(), path = path.isolatedCopy(), contentType = contentType.isolatedCopy()] {
+ blobRegistry().registerFileBlobURL(url, BlobDataFileReference::create(path), contentType);
+ });
+ }
}
-static void registerBlobURLFromTask(void* context)
+void ThreadableBlobRegistry::registerBlobURL(const URL& url, Vector<BlobPart>&& blobParts, const String& contentType)
{
- std::unique_ptr<BlobRegistryContext> blobRegistryContext(static_cast<BlobRegistryContext*>(context));
- blobRegistry().registerBlobURL(blobRegistryContext->url, blobRegistryContext->srcURL);
+ if (isMainThread())
+ blobRegistry().registerBlobURL(url, WTFMove(blobParts), contentType);
+ else {
+ for (auto& part : blobParts)
+ part.detachFromCurrentThread();
+ callOnMainThread([url = url.isolatedCopy(), blobParts = WTFMove(blobParts), contentType = contentType.isolatedCopy()]() mutable {
+ blobRegistry().registerBlobURL(url, WTFMove(blobParts), contentType);
+ });
+ }
}
void ThreadableBlobRegistry::registerBlobURL(SecurityOrigin* origin, const URL& url, const URL& srcURL)
@@ -115,51 +113,65 @@ void ThreadableBlobRegistry::registerBlobURL(SecurityOrigin* origin, const URL&
if (isMainThread())
blobRegistry().registerBlobURL(url, srcURL);
- else
- callOnMainThread(&registerBlobURLFromTask, new BlobRegistryContext(url, srcURL));
+ else {
+ callOnMainThread([url = url.isolatedCopy(), srcURL = srcURL.isolatedCopy()] {
+ blobRegistry().registerBlobURL(url, srcURL);
+ });
+ }
}
-static void unregisterBlobURLTask(void* context)
+void ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked(const URL& url, const URL& srcURL, const String& fileBackedPath, const String& contentType)
{
- std::unique_ptr<BlobRegistryContext> blobRegistryContext(static_cast<BlobRegistryContext*>(context));
- blobRegistry().unregisterBlobURL(blobRegistryContext->url);
-}
-
-void ThreadableBlobRegistry::unregisterBlobURL(const URL& url)
-{
- if (BlobURL::getOrigin(url) == "null")
- originMap()->remove(url.string());
-
if (isMainThread())
- blobRegistry().unregisterBlobURL(url);
+ blobRegistry().registerBlobURLOptionallyFileBacked(url, srcURL, BlobDataFileReference::create(fileBackedPath), contentType);
else
- callOnMainThread(&unregisterBlobURLTask, new BlobRegistryContext(url));
+ postToMainThread(createCrossThreadTask(ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked, url, srcURL, fileBackedPath, contentType));
}
-PassRefPtr<SecurityOrigin> ThreadableBlobRegistry::getCachedOrigin(const URL& url)
+void ThreadableBlobRegistry::registerBlobURLForSlice(const URL& newURL, const URL& srcURL, long long start, long long end)
{
- return originMap()->get(url.string());
+ if (isMainThread())
+ blobRegistry().registerBlobURLForSlice(newURL, srcURL, start, end);
+ else {
+ callOnMainThread([newURL = newURL.isolatedCopy(), srcURL = srcURL.isolatedCopy(), start, end] {
+ blobRegistry().registerBlobURLForSlice(newURL, srcURL, start, end);
+ });
+ }
}
-#else
-
-void ThreadableBlobRegistry::registerBlobURL(const URL&, std::unique_ptr<BlobData>)
+unsigned long long ThreadableBlobRegistry::blobSize(const URL& url)
{
+ unsigned long long resultSize;
+ if (isMainThread())
+ resultSize = blobRegistry().blobSize(url);
+ else {
+ BinarySemaphore semaphore;
+ callOnMainThread([url = url.isolatedCopy(), &semaphore, &resultSize] {
+ resultSize = blobRegistry().blobSize(url);
+ semaphore.signal();
+ });
+ semaphore.wait(WallTime::infinity());
+ }
+ return resultSize;
}
-void ThreadableBlobRegistry::registerBlobURL(SecurityOrigin*, const URL&, const URL&)
+void ThreadableBlobRegistry::unregisterBlobURL(const URL& url)
{
-}
+ if (BlobURL::getOrigin(url) == "null")
+ originMap()->remove(url.string());
-void ThreadableBlobRegistry::unregisterBlobURL(const URL&)
-{
+ if (isMainThread())
+ blobRegistry().unregisterBlobURL(url);
+ else {
+ callOnMainThread([url = url.isolatedCopy()] {
+ blobRegistry().unregisterBlobURL(url);
+ });
+ }
}
-PassRefPtr<SecurityOrigin> ThreadableBlobRegistry::getCachedOrigin(const URL&)
+RefPtr<SecurityOrigin> ThreadableBlobRegistry::getCachedOrigin(const URL& url)
{
- return 0;
+ return originMap()->get(url.string());
}
-#endif // ENABL(BLOB)
-
} // namespace WebCore