Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / fileapi / ThreadableBlobRegistry.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "ThreadableBlobRegistry.h"
33
34 #include "BlobDataFileReference.h"
35 #include "BlobPart.h"
36 #include "BlobRegistry.h"
37 #include "BlobURL.h"
38 #include "SecurityOrigin.h"
39 #include <mutex>
40 #include <wtf/HashMap.h>
41 #include <wtf/MainThread.h>
42 #include <wtf/RefPtr.h>
43 #include <wtf/ThreadSpecific.h>
44 #include <wtf/text/StringHash.h>
45 #include <wtf/threads/BinarySemaphore.h>
46
47 using WTF::ThreadSpecific;
48
49 namespace WebCore {
50
51 struct BlobRegistryContext {
52     WTF_MAKE_FAST_ALLOCATED;
53 public:
54     BlobRegistryContext(const URL& url, Vector<BlobPart> blobParts, const String& contentType)
55         : url(url.isolatedCopy())
56         , contentType(contentType.isolatedCopy())
57         , blobParts(WTFMove(blobParts))
58     {
59         for (BlobPart& part : blobParts)
60             part.detachFromCurrentThread();
61     }
62
63     BlobRegistryContext(const URL& url, const URL& srcURL)
64         : url(url.isolatedCopy())
65         , srcURL(srcURL.isolatedCopy())
66     {
67     }
68
69     BlobRegistryContext(const URL& url)
70         : url(url.isolatedCopy())
71     {
72     }
73
74     BlobRegistryContext(const URL& url, const String& path, const String& contentType)
75         : url(url.isolatedCopy())
76         , path(path.isolatedCopy())
77         , contentType(contentType.isolatedCopy())
78     {
79     }
80
81     URL url;
82     URL srcURL;
83     String path;
84     String contentType;
85     Vector<BlobPart> blobParts;
86 };
87
88 typedef HashMap<String, RefPtr<SecurityOrigin>> BlobUrlOriginMap;
89
90 static ThreadSpecific<BlobUrlOriginMap>& originMap()
91 {
92     static std::once_flag onceFlag;
93     static ThreadSpecific<BlobUrlOriginMap>* map;
94     std::call_once(onceFlag, []{
95         map = new ThreadSpecific<BlobUrlOriginMap>;
96     });
97
98     return *map;
99 }
100
101 void ThreadableBlobRegistry::registerFileBlobURL(const URL& url, const String& path, const String& contentType)
102 {
103     if (isMainThread())
104         blobRegistry().registerFileBlobURL(url, BlobDataFileReference::create(path), contentType);
105     else {
106         // BlobRegistryContext performs an isolated copy of data.
107         BlobRegistryContext* context = new BlobRegistryContext(url, path, contentType);
108         callOnMainThread([context] {
109             std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
110             blobRegistry().registerFileBlobURL(blobRegistryContext->url, BlobDataFileReference::create(blobRegistryContext->path), blobRegistryContext->contentType);
111         });
112     }
113 }
114
115 void ThreadableBlobRegistry::registerBlobURL(const URL& url, Vector<BlobPart> blobParts, const String& contentType)
116 {
117     if (isMainThread())
118         blobRegistry().registerBlobURL(url, WTFMove(blobParts), contentType);
119     else {
120         // BlobRegistryContext performs an isolated copy of data.
121         BlobRegistryContext* context = new BlobRegistryContext(url, WTFMove(blobParts), contentType);
122         callOnMainThread([context] {
123             std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
124             blobRegistry().registerBlobURL(blobRegistryContext->url, WTFMove(blobRegistryContext->blobParts), blobRegistryContext->contentType);
125         });
126     }
127 }
128
129 void ThreadableBlobRegistry::registerBlobURL(SecurityOrigin* origin, const URL& url, const URL& srcURL)
130 {
131     // If the blob URL contains null origin, as in the context with unique security origin or file URL, save the mapping between url and origin so that the origin can be retrived when doing security origin check.
132     if (origin && BlobURL::getOrigin(url) == "null")
133         originMap()->add(url.string(), origin);
134
135     if (isMainThread())
136         blobRegistry().registerBlobURL(url, srcURL);
137     else {
138         // BlobRegistryContext performs an isolated copy of data.
139         BlobRegistryContext* context = new BlobRegistryContext(url, srcURL);
140         callOnMainThread([context] {
141             std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
142             blobRegistry().registerBlobURL(blobRegistryContext->url, blobRegistryContext->srcURL);
143         });
144     }
145 }
146
147 void ThreadableBlobRegistry::registerBlobURLForSlice(const URL& newURL, const URL& srcURL, long long start, long long end)
148 {
149     if (isMainThread())
150         blobRegistry().registerBlobURLForSlice(newURL, srcURL, start, end);
151     else {
152         // BlobRegistryContext performs an isolated copy of data.
153         BlobRegistryContext* context = new BlobRegistryContext(newURL, srcURL);
154         callOnMainThread([context, start, end] {
155             std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
156             blobRegistry().registerBlobURLForSlice(blobRegistryContext->url, blobRegistryContext->srcURL, start, end);
157         });
158     }
159 }
160
161 unsigned long long ThreadableBlobRegistry::blobSize(const URL& url)
162 {
163     unsigned long long resultSize;
164     if (isMainThread())
165         resultSize = blobRegistry().blobSize(url);
166     else {
167         // BlobRegistryContext performs an isolated copy of data.
168         BlobRegistryContext* context = new BlobRegistryContext(url);
169         BinarySemaphore semaphore;
170         callOnMainThread([context, &semaphore, &resultSize] {
171             std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
172             resultSize = blobRegistry().blobSize(blobRegistryContext->url);
173             semaphore.signal();
174         });
175         semaphore.wait(std::numeric_limits<double>::max());
176     }
177     return resultSize;
178 }
179
180 void ThreadableBlobRegistry::unregisterBlobURL(const URL& url)
181 {
182     if (BlobURL::getOrigin(url) == "null")
183         originMap()->remove(url.string());
184
185     if (isMainThread())
186         blobRegistry().unregisterBlobURL(url);
187     else {
188         // BlobRegistryContext performs an isolated copy of data.
189         BlobRegistryContext* context = new BlobRegistryContext(url);
190         callOnMainThread([context] {
191             std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
192             blobRegistry().unregisterBlobURL(blobRegistryContext->url);
193         });
194     }
195 }
196
197 RefPtr<SecurityOrigin> ThreadableBlobRegistry::getCachedOrigin(const URL& url)
198 {
199     return originMap()->get(url.string());
200 }
201
202 } // namespace WebCore