df15884d1d8e43a458c7f55f4aa6455c00058789
[WebKit-https.git] / Source / WebKit2 / UIProcess / WebProcessPool.h
1 /*
2  * Copyright (C) 2010-2016 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef WebProcessPool_h
27 #define WebProcessPool_h
28
29 #include "APIDictionary.h"
30 #include "APIObject.h"
31 #include "APIProcessPoolConfiguration.h"
32 #include "APIWebsiteDataStore.h"
33 #include "DownloadProxyMap.h"
34 #include "GenericCallback.h"
35 #include "MessageReceiver.h"
36 #include "MessageReceiverMap.h"
37 #include "NetworkProcessProxy.h"
38 #include "PlugInAutoStartProvider.h"
39 #include "PluginInfoStore.h"
40 #include "ProcessThrottler.h"
41 #include "StatisticsRequest.h"
42 #include "VisitedLinkStore.h"
43 #include "WebContextClient.h"
44 #include "WebContextConnectionClient.h"
45 #include "WebContextInjectedBundleClient.h"
46 #include "WebProcessProxy.h"
47 #include <WebCore/LinkHash.h>
48 #include <WebCore/SessionID.h>
49 #include <wtf/Forward.h>
50 #include <wtf/HashMap.h>
51 #include <wtf/HashSet.h>
52 #include <wtf/PassRefPtr.h>
53 #include <wtf/RefCounter.h>
54 #include <wtf/RefPtr.h>
55 #include <wtf/text/StringHash.h>
56 #include <wtf/text/WTFString.h>
57
58 #if ENABLE(DATABASE_PROCESS)
59 #include "DatabaseProcessProxy.h"
60 #endif
61
62 #if ENABLE(MEDIA_SESSION)
63 #include "WebMediaSessionFocusManager.h"
64 #endif
65
66 #if PLATFORM(COCOA)
67 OBJC_CLASS NSMutableDictionary;
68 OBJC_CLASS NSObject;
69 OBJC_CLASS NSString;
70 #endif
71
72 namespace API {
73 class AutomationClient;
74 class DownloadClient;
75 class LegacyContextHistoryClient;
76 class PageConfiguration;
77 }
78
79 namespace WebKit {
80
81 class DownloadProxy;
82 class WebAutomationSession;
83 class WebContextSupplement;
84 class WebIconDatabase;
85 class WebPageGroup;
86 class WebPageProxy;
87 struct NetworkProcessCreationParameters;
88 struct StatisticsData;
89 struct WebProcessCreationParameters;
90     
91 typedef GenericCallback<API::Dictionary*> DictionaryCallback;
92
93 #if PLATFORM(COCOA)
94 int networkProcessLatencyQOS();
95 int networkProcessThroughputQOS();
96 int webProcessLatencyQOS();
97 int webProcessThroughputQOS();
98 #endif
99
100 class WebProcessPool final : public API::ObjectImpl<API::Object::Type::ProcessPool>, private IPC::MessageReceiver
101 #if ENABLE(NETSCAPE_PLUGIN_API)
102     , private PluginInfoStoreClient
103 #endif
104     {
105 public:
106     static Ref<WebProcessPool> create(API::ProcessPoolConfiguration&);
107
108     explicit WebProcessPool(API::ProcessPoolConfiguration&);        
109     virtual ~WebProcessPool();
110
111     API::ProcessPoolConfiguration& configuration() { return m_configuration.get(); }
112
113     static const Vector<WebProcessPool*>& allProcessPools();
114
115     template <typename T>
116     T* supplement()
117     {
118         return static_cast<T*>(m_supplements.get(T::supplementName()));
119     }
120
121     template <typename T>
122     void addSupplement()
123     {
124         m_supplements.add(T::supplementName(), T::create(this));
125     }
126
127     void addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver&);
128     void addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver&);
129     void removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID);
130
131     bool dispatchMessage(IPC::Connection&, IPC::MessageDecoder&);
132     bool dispatchSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&);
133
134     void initializeClient(const WKContextClientBase*);
135     void initializeInjectedBundleClient(const WKContextInjectedBundleClientBase*);
136     void initializeConnectionClient(const WKContextConnectionClientBase*);
137     void setHistoryClient(std::unique_ptr<API::LegacyContextHistoryClient>);
138     void setDownloadClient(std::unique_ptr<API::DownloadClient>);
139     void setAutomationClient(std::unique_ptr<API::AutomationClient>);
140
141     void setMaximumNumberOfProcesses(unsigned); // Can only be called when there are no processes running.
142     unsigned maximumNumberOfProcesses() const { return !m_configuration->maximumProcessCount() ? UINT_MAX : m_configuration->maximumProcessCount(); }
143
144     const Vector<RefPtr<WebProcessProxy>>& processes() const { return m_processes; }
145
146     // WebProcess or NetworkProcess as approporiate for current process model. The connection must be non-null.
147     IPC::Connection* networkingProcessConnection();
148
149     template<typename T> void sendToAllProcesses(const T& message);
150     template<typename T> void sendToAllProcessesRelaunchingThemIfNecessary(const T& message);
151     template<typename T> void sendToOneProcess(T&& message);
152
153     // Sends the message to WebProcess or NetworkProcess as approporiate for current process model.
154     template<typename T> void sendToNetworkingProcess(T&& message);
155     template<typename T> void sendToNetworkingProcessRelaunchingIfNecessary(T&& message);
156
157     // Sends the message to WebProcess or DatabaseProcess as approporiate for current process model.
158     template<typename T> void sendToDatabaseProcessRelaunchingIfNecessary(T&& message);
159
160     void processDidFinishLaunching(WebProcessProxy*);
161
162     // Disconnect the process from the context.
163     void disconnectProcess(WebProcessProxy*);
164
165     API::WebsiteDataStore* websiteDataStore() const { return m_websiteDataStore.get(); }
166
167     Ref<WebPageProxy> createWebPage(PageClient&, Ref<API::PageConfiguration>&&);
168
169     const String& injectedBundlePath() const { return m_configuration->injectedBundlePath(); }
170
171     DownloadProxy* download(WebPageProxy* initiatingPage, const WebCore::ResourceRequest&);
172     DownloadProxy* resumeDownload(const API::Data* resumeData, const String& path);
173
174     void setInjectedBundleInitializationUserData(PassRefPtr<API::Object> userData) { m_injectedBundleInitializationUserData = userData; }
175
176     void postMessageToInjectedBundle(const String&, API::Object*);
177
178     void populateVisitedLinks();
179
180 #if ENABLE(NETSCAPE_PLUGIN_API)
181     void setAdditionalPluginsDirectory(const String&);
182
183     PluginInfoStore& pluginInfoStore() { return m_pluginInfoStore; }
184
185     void setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy, const String& host, const String& bundleIdentifier, const String& versionString);
186     void clearPluginClientPolicies();
187 #endif
188
189     pid_t networkProcessIdentifier();
190     pid_t databaseProcessIdentifier();
191
192     void setAlwaysUsesComplexTextCodePath(bool);
193     void setShouldUseFontSmoothing(bool);
194     
195     void registerURLSchemeAsEmptyDocument(const String&);
196     void registerURLSchemeAsSecure(const String&);
197     void registerURLSchemeAsBypassingContentSecurityPolicy(const String&);
198     void setDomainRelaxationForbiddenForURLScheme(const String&);
199     void setCanHandleHTTPSServerTrustEvaluation(bool);
200     void registerURLSchemeAsLocal(const String&);
201     void registerURLSchemeAsNoAccess(const String&);
202     void registerURLSchemeAsDisplayIsolated(const String&);
203     void registerURLSchemeAsCORSEnabled(const String&);
204 #if ENABLE(CACHE_PARTITIONING)
205     void registerURLSchemeAsCachePartitioned(const String&);
206 #endif
207
208     VisitedLinkStore& visitedLinkStore() { return m_visitedLinkStore.get(); }
209
210     void setCacheModel(CacheModel);
211     CacheModel cacheModel() const { return m_configuration->cacheModel(); }
212
213     void setDefaultRequestTimeoutInterval(double);
214
215     void startMemorySampler(const double interval);
216     void stopMemorySampler();
217
218 #if USE(SOUP)
219     void setInitialHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) { m_initialHTTPCookieAcceptPolicy = policy; }
220 #endif
221     void setEnhancedAccessibility(bool);
222     
223     // Downloads.
224     DownloadProxy* createDownloadProxy(const WebCore::ResourceRequest&);
225     API::DownloadClient& downloadClient() { return *m_downloadClient; }
226
227     API::LegacyContextHistoryClient& historyClient() { return *m_historyClient; }
228     WebContextClient& client() { return m_client; }
229
230     WebIconDatabase* iconDatabase() const { return m_iconDatabase.get(); }
231
232     struct Statistics {
233         unsigned wkViewCount;
234         unsigned wkPageCount;
235         unsigned wkFrameCount;
236     };
237     static Statistics& statistics();    
238
239     void setIconDatabasePath(const String&);
240     String iconDatabasePath() const;
241     void setCookieStorageDirectory(const String& dir) { m_overrideCookieStorageDirectory = dir; }
242
243     void useTestingNetworkSession();
244     bool isUsingTestingNetworkSession() const { return m_shouldUseTestingNetworkSession; }
245
246     void clearCachedCredentials();
247     void terminateDatabaseProcess();
248
249     void allowSpecificHTTPSCertificateForHost(const WebCertificateInfo*, const String& host);
250
251     WebProcessProxy& createNewWebProcessRespectingProcessCountLimit(); // Will return an existing one if limit is met.
252     void warmInitialProcess();
253
254     bool shouldTerminate(WebProcessProxy*);
255
256     void disableProcessTermination() { m_processTerminationEnabled = false; }
257     void enableProcessTermination();
258
259     void updateAutomationCapabilities() const;
260     void setAutomationSession(RefPtr<WebAutomationSession>&&);
261
262     // Defaults to false.
263     void setHTTPPipeliningEnabled(bool);
264     bool httpPipeliningEnabled() const;
265
266     void getStatistics(uint32_t statisticsMask, std::function<void (API::Dictionary*, CallbackBase::Error)>);
267     
268     void garbageCollectJavaScriptObjects();
269     void setJavaScriptGarbageCollectorTimerEnabled(bool flag);
270
271 #if PLATFORM(COCOA)
272     static bool omitPDFSupport();
273 #endif
274
275     void fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled);
276
277     void textCheckerStateChanged();
278
279     PassRefPtr<API::Dictionary> plugInAutoStartOriginHashes() const;
280     void setPlugInAutoStartOriginHashes(API::Dictionary&);
281     void setPlugInAutoStartOrigins(API::Array&);
282     void setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary&, double time);
283
284     // Network Process Management
285     NetworkProcessProxy& ensureNetworkProcess();
286     NetworkProcessProxy* networkProcess() { return m_networkProcess.get(); }
287     void networkProcessCrashed(NetworkProcessProxy*);
288
289     void getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>);
290
291 #if ENABLE(DATABASE_PROCESS)
292     void ensureDatabaseProcess();
293     DatabaseProcessProxy* databaseProcess() { return m_databaseProcess.get(); }
294     void getDatabaseProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>);
295     void databaseProcessCrashed(DatabaseProcessProxy*);
296 #endif
297
298 #if PLATFORM(COCOA)
299     bool processSuppressionEnabled() const;
300 #endif
301
302     void windowServerConnectionStateChanged();
303
304     static void willStartUsingPrivateBrowsing();
305     static void willStopUsingPrivateBrowsing();
306
307 #if USE(SOUP)
308     void setIgnoreTLSErrors(bool);
309     bool ignoreTLSErrors() const { return m_ignoreTLSErrors; }
310 #endif
311
312     static void setInvalidMessageCallback(void (*)(WKStringRef));
313     static void didReceiveInvalidMessage(const IPC::StringReference& messageReceiverName, const IPC::StringReference& messageName);
314
315     void processDidCachePage(WebProcessProxy*);
316
317     bool isURLKnownHSTSHost(const String& urlString, bool privateBrowsingEnabled) const;
318     void resetHSTSHosts();
319     void resetHSTSHostsAddedAfterDate(double startDateIntervalSince1970);
320
321     void registerSchemeForCustomProtocol(const String&);
322     void unregisterSchemeForCustomProtocol(const String&);
323
324     static HashSet<String, ASCIICaseInsensitiveHash>& globalURLSchemesWithCustomProtocolHandlers();
325     static void registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&);
326     static void unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&);
327
328 #if PLATFORM(COCOA)
329     void updateProcessSuppressionState();
330
331     NSMutableDictionary *ensureBundleParameters();
332     NSMutableDictionary *bundleParameters() { return m_bundleParameters.get(); }
333 #else
334     void updateProcessSuppressionState() const { }
335 #endif
336
337     void updateHiddenPageThrottlingAutoIncreaseLimit();
338
339     void setMemoryCacheDisabled(bool);
340     void setFontWhitelist(API::Array*);
341
342     UserObservablePageCounter::Token userObservablePageCount()
343     {
344         return m_userObservablePageCounter.count();
345     }
346
347     ProcessSuppressionDisabledToken processSuppressionDisabledForPageCount()
348     {
349         return m_processSuppressionDisabledForPageCounter.count();
350     }
351
352     HiddenPageThrottlingAutoIncreasesCounter::Token hiddenPageThrottlingAutoIncreasesCount()
353     {
354         return m_hiddenPageThrottlingAutoIncreasesCounter.count();
355     }
356
357     // FIXME: Move these to API::WebsiteDataStore.
358     static String legacyPlatformDefaultLocalStorageDirectory();
359     static String legacyPlatformDefaultIndexedDBDatabaseDirectory();
360     static String legacyPlatformDefaultWebSQLDatabaseDirectory();
361     static String legacyPlatformDefaultMediaKeysStorageDirectory();
362     static String legacyPlatformDefaultApplicationCacheDirectory();
363     static String legacyPlatformDefaultNetworkCacheDirectory();
364     static bool isNetworkCacheEnabled();
365
366     bool resourceLoadStatisticsEnabled() { return m_resourceLoadStatisticsEnabled; }
367     void setResourceLoadStatisticsEnabled(bool enabled) { m_resourceLoadStatisticsEnabled = enabled; }
368
369 private:
370     void platformInitialize();
371
372     void platformInitializeWebProcess(WebProcessCreationParameters&);
373     void platformInvalidateContext();
374
375     WebProcessProxy& createNewWebProcess();
376
377     void requestWebContentStatistics(StatisticsRequest*);
378     void requestNetworkingStatistics(StatisticsRequest*);
379
380     void platformInitializeNetworkProcess(NetworkProcessCreationParameters&);
381
382     void handleMessage(IPC::Connection&, const String& messageName, const UserData& messageBody);
383     void handleSynchronousMessage(IPC::Connection&, const String& messageName, const UserData& messageBody, UserData& returnUserData);
384
385     void didGetStatistics(const StatisticsData&, uint64_t callbackID);
386
387     // IPC::MessageReceiver.
388     // Implemented in generated WebProcessPoolMessageReceiver.cpp
389     void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override;
390     void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
391
392     static void languageChanged(void* context);
393     void languageChanged();
394
395     String platformDefaultIconDatabasePath() const;
396
397 #if PLATFORM(IOS) || ENABLE(SECCOMP_FILTERS)
398     String cookieStorageDirectory() const;
399 #endif
400
401 #if PLATFORM(IOS)
402     String parentBundleDirectory() const;
403     String networkingCachesDirectory() const;
404     String webContentCachesDirectory() const;
405     String containerTemporaryDirectory() const;
406 #endif
407
408 #if PLATFORM(COCOA)
409     void registerNotificationObservers();
410     void unregisterNotificationObservers();
411 #endif
412
413     void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, WebCore::SessionID);
414     void plugInDidReceiveUserInteraction(unsigned plugInOriginHash, WebCore::SessionID);
415
416     void setAnyPageGroupMightHavePrivateBrowsingEnabled(bool);
417
418 #if ENABLE(NETSCAPE_PLUGIN_API)
419     // PluginInfoStoreClient:
420     void pluginInfoStoreDidLoadPlugins(PluginInfoStore*) override;
421 #endif
422
423     Ref<API::ProcessPoolConfiguration> m_configuration;
424
425     IPC::MessageReceiverMap m_messageReceiverMap;
426
427     Vector<RefPtr<WebProcessProxy>> m_processes;
428     bool m_haveInitialEmptyProcess;
429
430     WebProcessProxy* m_processWithPageCache;
431
432     Ref<WebPageGroup> m_defaultPageGroup;
433
434     RefPtr<API::Object> m_injectedBundleInitializationUserData;
435     WebContextInjectedBundleClient m_injectedBundleClient;
436
437     WebContextClient m_client;
438     WebContextConnectionClient m_connectionClient;
439     std::unique_ptr<API::AutomationClient> m_automationClient;
440     std::unique_ptr<API::DownloadClient> m_downloadClient;
441     std::unique_ptr<API::LegacyContextHistoryClient> m_historyClient;
442
443     RefPtr<WebAutomationSession> m_automationSession;
444
445 #if ENABLE(NETSCAPE_PLUGIN_API)
446     PluginInfoStore m_pluginInfoStore;
447 #endif
448     Ref<VisitedLinkStore> m_visitedLinkStore;
449     bool m_visitedLinksPopulated;
450
451     PlugInAutoStartProvider m_plugInAutoStartProvider;
452         
453     HashSet<String> m_schemesToRegisterAsEmptyDocument;
454     HashSet<String> m_schemesToRegisterAsSecure;
455     HashSet<String> m_schemesToRegisterAsBypassingContentSecurityPolicy;
456     HashSet<String> m_schemesToSetDomainRelaxationForbiddenFor;
457     HashSet<String> m_schemesToRegisterAsLocal;
458     HashSet<String> m_schemesToRegisterAsNoAccess;
459     HashSet<String> m_schemesToRegisterAsDisplayIsolated;
460     HashSet<String> m_schemesToRegisterAsCORSEnabled;
461     HashSet<String> m_schemesToRegisterAsAlwaysRevalidated;
462 #if ENABLE(CACHE_PARTITIONING)
463     HashSet<String> m_schemesToRegisterAsCachePartitioned;
464 #endif
465
466     bool m_alwaysUsesComplexTextCodePath;
467     bool m_shouldUseFontSmoothing;
468
469     Vector<String> m_fontWhitelist;
470
471     // Messages that were posted before any pages were created.
472     // The client should use initialization messages instead, so that a restarted process would get the same state.
473     Vector<std::pair<String, RefPtr<API::Object>>> m_messagesToInjectedBundlePostedToEmptyContext;
474
475     bool m_memorySamplerEnabled;
476     double m_memorySamplerInterval;
477
478     RefPtr<WebIconDatabase> m_iconDatabase;
479
480     const RefPtr<API::WebsiteDataStore> m_websiteDataStore;
481
482     typedef HashMap<const char*, RefPtr<WebContextSupplement>, PtrHash<const char*>> WebContextSupplementMap;
483     WebContextSupplementMap m_supplements;
484
485 #if USE(SOUP)
486     HTTPCookieAcceptPolicy m_initialHTTPCookieAcceptPolicy;
487 #endif
488
489 #if PLATFORM(MAC)
490     RetainPtr<NSObject> m_enhancedAccessibilityObserver;
491     RetainPtr<NSObject> m_automaticTextReplacementNotificationObserver;
492     RetainPtr<NSObject> m_automaticSpellingCorrectionNotificationObserver;
493     RetainPtr<NSObject> m_automaticQuoteSubstitutionNotificationObserver;
494     RetainPtr<NSObject> m_automaticDashSubstitutionNotificationObserver;
495 #endif
496
497     String m_overrideIconDatabasePath;
498     String m_overrideCookieStorageDirectory;
499
500     bool m_shouldUseTestingNetworkSession;
501
502     bool m_processTerminationEnabled;
503
504     bool m_canHandleHTTPSServerTrustEvaluation;
505     bool m_didNetworkProcessCrash;
506     RefPtr<NetworkProcessProxy> m_networkProcess;
507
508 #if ENABLE(DATABASE_PROCESS)
509     RefPtr<DatabaseProcessProxy> m_databaseProcess;
510 #endif
511     
512     HashMap<uint64_t, RefPtr<DictionaryCallback>> m_dictionaryCallbacks;
513     HashMap<uint64_t, RefPtr<StatisticsRequest>> m_statisticsRequests;
514
515 #if USE(SOUP)
516     bool m_ignoreTLSErrors { true };
517 #endif
518
519     bool m_memoryCacheDisabled;
520     bool m_resourceLoadStatisticsEnabled { false };
521
522     UserObservablePageCounter m_userObservablePageCounter;
523     ProcessSuppressionDisabledCounter m_processSuppressionDisabledForPageCounter;
524     HiddenPageThrottlingAutoIncreasesCounter m_hiddenPageThrottlingAutoIncreasesCounter;
525     WebCore::Timer m_hiddenPageThrottlingTimer;
526
527 #if PLATFORM(COCOA)
528     RetainPtr<NSMutableDictionary> m_bundleParameters;
529     ProcessSuppressionDisabledToken m_pluginProcessManagerProcessSuppressionDisabledToken;
530 #endif
531
532 #if ENABLE(CONTENT_EXTENSIONS)
533     HashMap<String, String> m_encodedContentExtensions;
534 #endif
535
536 #if ENABLE(NETSCAPE_PLUGIN_API)
537     HashMap<String, HashMap<String, HashMap<String, uint8_t>>> m_pluginLoadClientPolicies;
538 #endif
539 };
540
541 template<typename T>
542 void WebProcessPool::sendToNetworkingProcess(T&& message)
543 {
544     if (m_networkProcess && m_networkProcess->canSendMessage())
545         m_networkProcess->send(std::forward<T>(message), 0);
546 }
547
548 template<typename T>
549 void WebProcessPool::sendToNetworkingProcessRelaunchingIfNecessary(T&& message)
550 {
551     ensureNetworkProcess();
552     m_networkProcess->send(std::forward<T>(message), 0);
553 }
554
555 template<typename T>
556 void WebProcessPool::sendToDatabaseProcessRelaunchingIfNecessary(T&& message)
557 {
558 #if ENABLE(DATABASE_PROCESS)
559     ensureDatabaseProcess();
560     m_databaseProcess->send(std::forward<T>(message), 0);
561 #else
562     sendToAllProcessesRelaunchingThemIfNecessary(std::forward<T>(message));
563 #endif
564 }
565
566 template<typename T>
567 void WebProcessPool::sendToAllProcesses(const T& message)
568 {
569     size_t processCount = m_processes.size();
570     for (size_t i = 0; i < processCount; ++i) {
571         WebProcessProxy* process = m_processes[i].get();
572         if (process->canSendMessage())
573             process->send(T(message), 0);
574     }
575 }
576
577 template<typename T>
578 void WebProcessPool::sendToAllProcessesRelaunchingThemIfNecessary(const T& message)
579 {
580     // FIXME (Multi-WebProcess): WebProcessPool doesn't track processes that have exited, so it cannot relaunch these. Perhaps this functionality won't be needed in this mode.
581     sendToAllProcesses(message);
582 }
583
584 template<typename T>
585 void WebProcessPool::sendToOneProcess(T&& message)
586 {
587     bool messageSent = false;
588     size_t processCount = m_processes.size();
589     for (size_t i = 0; i < processCount; ++i) {
590         WebProcessProxy* process = m_processes[i].get();
591         if (process->canSendMessage()) {
592             process->send(std::forward<T>(message), 0);
593             messageSent = true;
594             break;
595         }
596     }
597
598     if (!messageSent) {
599         warmInitialProcess();
600         RefPtr<WebProcessProxy> process = m_processes.last();
601         if (process->canSendMessage())
602             process->send(std::forward<T>(message), 0);
603     }
604 }
605
606 } // namespace WebKit
607
608 #endif // UIProcessPool_h