1/*
2 * Copyright (C) 2009 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#pragma once
32
33#include "NetworkLoadMetrics.h"
34#include "ThreadableLoader.h"
35#include "ThreadableLoaderClient.h"
36#include "ThreadableLoaderClientWrapper.h"
37#include <wtf/text/WTFString.h>
38
39namespace WebCore {
40
41 class ContentSecurityPolicy;
42 class ResourceError;
43 class ResourceRequest;
44 class SecurityOrigin;
45 class WorkerGlobalScope;
46 class WorkerLoaderProxy;
47
48 class WorkerThreadableLoader : public RefCounted<WorkerThreadableLoader>, public ThreadableLoader {
49 WTF_MAKE_FAST_ALLOCATED;
50 public:
51 static void loadResourceSynchronously(WorkerGlobalScope&, ResourceRequest&&, ThreadableLoaderClient&, const ThreadableLoaderOptions&);
52 static Ref<WorkerThreadableLoader> create(WorkerGlobalScope& workerGlobalScope, ThreadableLoaderClient& client, const String& taskMode, ResourceRequest&& request, const ThreadableLoaderOptions& options, const String& referrer)
53 {
54 return adoptRef(*new WorkerThreadableLoader(workerGlobalScope, client, taskMode, WTFMove(request), options, referrer));
55 }
56
57 ~WorkerThreadableLoader();
58
59 void cancel() override;
60
61 bool done() const { return m_workerClientWrapper->done(); }
62
63 using RefCounted<WorkerThreadableLoader>::ref;
64 using RefCounted<WorkerThreadableLoader>::deref;
65
66 protected:
67 void refThreadableLoader() override { ref(); }
68 void derefThreadableLoader() override { deref(); }
69
70 private:
71 // Creates a loader on the main thread and bridges communication between
72 // the main thread and the worker context's thread where WorkerThreadableLoader runs.
73 //
74 // Regarding the bridge and lifetimes of items used in callbacks, there are a few cases:
75 //
76 // all cases. All tasks posted from the worker context's thread are ok because
77 // the last task posted always is "mainThreadDestroy", so MainThreadBridge is
78 // around for all tasks that use it on the main thread.
79 //
80 // case 1. worker.terminate is called.
81 // In this case, no more tasks are posted from the worker object's thread to the worker
82 // context's thread -- WorkerGlobalScopeProxy implementation enforces this.
83 //
84 // case 2. xhr gets aborted and the worker context continues running.
85 // The ThreadableLoaderClientWrapper has the underlying client cleared, so no more calls
86 // go through it. All tasks posted from the worker object's thread to the worker context's
87 // thread contain the RefPtr<ThreadableLoaderClientWrapper> object, so the
88 // ThreadableLoaderClientWrapper instance is there until all tasks are executed.
89 class MainThreadBridge : public ThreadableLoaderClient {
90 public:
91 // All executed on the worker context's thread.
92 MainThreadBridge(ThreadableLoaderClientWrapper&, WorkerLoaderProxy&, const String& taskMode, ResourceRequest&&, const ThreadableLoaderOptions&, const String& outgoingReferrer, WorkerGlobalScope&);
93 void cancel();
94 void destroy();
95
96 private:
97 // Executed on the worker context's thread.
98 void clearClientWrapper();
99
100 // All executed on the main thread.
101 void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
102 void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override;
103 void didReceiveData(const char*, int dataLength) override;
104 void didFinishLoading(unsigned long identifier) override;
105 void didFail(const ResourceError&) override;
106 void didFinishTiming(const ResourceTiming&) override;
107
108 // Only to be used on the main thread.
109 RefPtr<ThreadableLoader> m_mainThreadLoader;
110 bool m_loadingFinished { false };
111
112 // ThreadableLoaderClientWrapper is to be used on the worker context thread.
113 // The ref counting is done on either thread.
114 RefPtr<ThreadableLoaderClientWrapper> m_workerClientWrapper;
115
116 // May be used on either thread.
117 WorkerLoaderProxy& m_loaderProxy;
118
119 // For use on the main thread.
120 String m_taskMode;
121 unsigned long m_workerRequestIdentifier { 0 };
122 NetworkLoadMetrics m_networkLoadMetrics;
123 };
124
125 WorkerThreadableLoader(WorkerGlobalScope&, ThreadableLoaderClient&, const String& taskMode, ResourceRequest&&, const ThreadableLoaderOptions&, const String& referrer);
126
127 Ref<WorkerGlobalScope> m_workerGlobalScope;
128 Ref<ThreadableLoaderClientWrapper> m_workerClientWrapper;
129 MainThreadBridge& m_bridge;
130 };
131
132} // namespace WebCore
133