Index: Source/modules/cachestorage/Cache.cpp |
diff --git a/Source/modules/cachestorage/Cache.cpp b/Source/modules/cachestorage/Cache.cpp |
index bbe9c75e7693d29c83e60a08481562561573c82e..8a6d65ea6132c018f2bb19007a4ce6b435da63f5 100644 |
--- a/Source/modules/cachestorage/Cache.cpp |
+++ b/Source/modules/cachestorage/Cache.cpp |
@@ -153,7 +153,7 @@ public: |
ScriptValue call(ScriptValue value) override |
{ |
Response* response = V8Response::toImplWithTypeCheck(scriptState()->isolate(), value.v8Value()); |
- ScriptPromise putPromise = m_cache->putImpl(scriptState(), m_request, response); |
+ ScriptPromise putPromise = m_cache->putImpl(scriptState(), HeapVector<Member<Request>>(1, m_request), HeapVector<Member<Response>>(1, response)); |
return ScriptValue(scriptState(), putPromise.v8Value()); |
} |
@@ -176,49 +176,88 @@ private: |
Member<Request> m_request; |
}; |
-class Cache::AsyncPutBatch final : public BodyStreamBuffer::BlobHandleCreatorClient { |
+class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<BarrierCallbackForPut> { |
public: |
- AsyncPutBatch(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver, Cache* cache, Request* request, Response* response) |
- : m_resolver(resolver) |
+ BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) |
+ : m_numberOfRemainingOperations(numberOfOperations) |
, m_cache(cache) |
+ , m_resolver(resolver) |
{ |
- request->populateWebServiceWorkerRequest(m_webRequest); |
- response->populateWebServiceWorkerResponse(m_webResponse); |
+ ASSERT(0 < m_numberOfRemainingOperations); |
+ m_batchOperations.resize(numberOfOperations); |
} |
- ~AsyncPutBatch() override { } |
- void didCreateBlobHandle(PassRefPtr<BlobDataHandle> handle) override |
+ |
+ void onSuccess(size_t index, const WebServiceWorkerCache::BatchOperation& batchOperation) |
{ |
- WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1)); |
- batchOperations[0].operationType = WebServiceWorkerCache::OperationTypePut; |
- batchOperations[0].request = m_webRequest; |
- batchOperations[0].response = m_webResponse; |
- batchOperations[0].response.setBlobDataHandle(handle); |
- m_cache->webCache()->dispatchBatch(new CallbackPromiseAdapter<void, CacheStorageError>(m_resolver.get()), batchOperations); |
- cleanup(); |
+ ASSERT(index < m_batchOperations.size()); |
+ if (m_completed) |
+ return; |
+ m_batchOperations[index] = batchOperation; |
+ if (--m_numberOfRemainingOperations != 0) |
+ return; |
+ m_cache->webCache()->dispatchBatch(new CallbackPromiseAdapter<void, CacheStorageError>(m_resolver), m_batchOperations); |
sof
2015/06/30 09:46:46
Where is m_resolver resolved or cleared?
nhiroki
2015/07/01 02:02:20
m_resolver is resolved in CallbackPromiseAdapter<v
|
} |
- void didFail(DOMException* exception) override |
+ |
+ void onError(DOMException* exception) |
{ |
+ if (m_completed) |
+ return; |
+ m_completed = true; |
+ |
ScriptState* state = m_resolver->scriptState(); |
ScriptState::Scope scope(state); |
m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), exception->toString())); |
- cleanup(); |
} |
DEFINE_INLINE_VIRTUAL_TRACE() |
{ |
- visitor->trace(m_resolver); |
visitor->trace(m_cache); |
- BlobHandleCreatorClient::trace(visitor); |
} |
private: |
- void cleanup() |
+ bool m_completed = false; |
+ int m_numberOfRemainingOperations; |
+ Member<Cache> m_cache; |
+ RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; |
+ Vector<WebServiceWorkerCache::BatchOperation> m_batchOperations; |
+}; |
+ |
+class Cache::BlobHandleCallbackForPut final : public BodyStreamBuffer::BlobHandleCreatorClient { |
+public: |
+ BlobHandleCallbackForPut(size_t index, BarrierCallbackForPut* barrierCallback, Request* request, Response* response) |
+ : m_index(index) |
+ , m_barrierCallback(barrierCallback) |
{ |
- m_resolver = nullptr; |
- m_cache = nullptr; |
+ request->populateWebServiceWorkerRequest(m_webRequest); |
+ response->populateWebServiceWorkerResponse(m_webResponse); |
} |
- RefPtrWillBeMember<ScriptPromiseResolver> m_resolver; |
- Member<Cache> m_cache; |
+ ~BlobHandleCallbackForPut() override { } |
+ |
+ void didCreateBlobHandle(PassRefPtr<BlobDataHandle> handle) override |
+ { |
+ WebServiceWorkerCache::BatchOperation batchOperation; |
+ batchOperation.operationType = WebServiceWorkerCache::OperationTypePut; |
+ batchOperation.request = m_webRequest; |
+ batchOperation.response = m_webResponse; |
+ batchOperation.response.setBlobDataHandle(handle); |
+ m_barrierCallback->onSuccess(m_index, batchOperation); |
+ } |
+ |
+ void didFail(DOMException* exception) override |
+ { |
+ m_barrierCallback->onError(exception); |
+ } |
+ |
+ DEFINE_INLINE_VIRTUAL_TRACE() |
+ { |
+ visitor->trace(m_barrierCallback); |
+ BlobHandleCreatorClient::trace(visitor); |
+ } |
+ |
+private: |
+ const size_t m_index; |
+ Member<BarrierCallbackForPut> m_barrierCallback; |
+ |
WebServiceWorkerRequest m_webRequest; |
WebServiceWorkerResponse m_webResponse; |
}; |
@@ -289,11 +328,11 @@ ScriptPromise Cache::put(ScriptState* scriptState, const RequestInfo& request, R |
{ |
ASSERT(!request.isNull()); |
if (request.isRequest()) |
- return putImpl(scriptState, request.getAsRequest(), response); |
+ return putImpl(scriptState, HeapVector<Member<Request>>(1, request.getAsRequest()), HeapVector<Member<Response>>(1, response)); |
Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); |
if (exceptionState.hadException()) |
return ScriptPromise(); |
- return putImpl(scriptState, newRequest, response); |
+ return putImpl(scriptState, HeapVector<Member<Request>>(1, newRequest), HeapVector<Member<Response>>(1, response)); |
} |
ScriptPromise Cache::keys(ScriptState* scriptState, ExceptionState&) |
@@ -381,39 +420,44 @@ ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request |
return promise; |
} |
-ScriptPromise Cache::putImpl(ScriptState* scriptState, Request* request, Response* response) |
+ScriptPromise Cache::putImpl(ScriptState* scriptState, const HeapVector<Member<Request>>& requests, const HeapVector<Member<Response>>& responses) |
{ |
- KURL url(KURL(), request->url()); |
- if (!url.protocolIsInHTTPFamily()) |
- return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Request scheme '" + url.protocol() + "' is unsupported")); |
- if (request->method() != "GET") |
- return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Request method '" + request->method() + "' is unsupported")); |
- if (request->hasBody() && request->bodyUsed()) |
- return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Request body is already used")); |
- if (response->hasBody() && response->bodyUsed()) |
- return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Response body is already used")); |
- |
- if (request->hasBody()) |
- request->lockBody(Body::PassBody); |
- if (response->hasBody()) |
- response->lockBody(Body::PassBody); |
- |
RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); |
const ScriptPromise promise = resolver->promise(); |
- if (BodyStreamBuffer* buffer = response->internalBuffer()) { |
- if (buffer == response->buffer() && response->isBodyConsumed()) |
- buffer = response->createDrainingStream(); |
- // If the response body type is stream, read the all data and create the |
- // blob handle and dispatch the put batch asynchronously. |
- buffer->readAllAndCreateBlobHandle(response->internalMIMEType(), new AsyncPutBatch(resolver, this, request, response)); |
- return promise; |
+ BarrierCallbackForPut* barrierCallback = new BarrierCallbackForPut(requests.size(), this, resolver.get()); |
+ |
+ for (size_t i = 0; i < requests.size(); ++i) { |
+ KURL url(KURL(), requests[i]->url()); |
+ if (!url.protocolIsInHTTPFamily()) |
+ return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Request scheme '" + url.protocol() + "' is unsupported")); |
+ if (requests[i]->method() != "GET") |
+ return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Request method '" + requests[i]->method() + "' is unsupported")); |
+ if (requests[i]->hasBody() && requests[i]->bodyUsed()) |
+ return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Request body is already used")); |
+ if (responses[i]->hasBody() && responses[i]->bodyUsed()) |
+ return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Response body is already used")); |
+ |
+ if (requests[i]->hasBody()) |
+ requests[i]->lockBody(Body::PassBody); |
+ if (responses[i]->hasBody()) |
+ responses[i]->lockBody(Body::PassBody); |
+ |
+ if (BodyStreamBuffer* buffer = responses[i]->internalBuffer()) { |
+ if (buffer == responses[i]->buffer() && responses[i]->isBodyConsumed()) |
+ buffer = responses[i]->createDrainingStream(); |
+ // If the response body type is stream, read the all data and create |
+ // the blob handle and dispatch the put batch asynchronously. |
+ buffer->readAllAndCreateBlobHandle(responses[i]->internalMIMEType(), new BlobHandleCallbackForPut(i, barrierCallback, requests[i], responses[i])); |
+ continue; |
+ } |
+ |
+ WebServiceWorkerCache::BatchOperation batchOperation; |
+ batchOperation.operationType = WebServiceWorkerCache::OperationTypePut; |
+ requests[i]->populateWebServiceWorkerRequest(batchOperation.request); |
+ responses[i]->populateWebServiceWorkerResponse(batchOperation.response); |
+ barrierCallback->onSuccess(i, batchOperation); |
} |
- WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1)); |
- batchOperations[0].operationType = WebServiceWorkerCache::OperationTypePut; |
- request->populateWebServiceWorkerRequest(batchOperations[0].request); |
- response->populateWebServiceWorkerResponse(batchOperations[0].response); |
- m_webCache->dispatchBatch(new CallbackPromiseAdapter<void, CacheStorageError>(resolver), batchOperations); |
return promise; |
} |