Modern IDB: New database versions are never committed to SQLite.
[WebKit-https.git] / Source / WebKit2 / UIProcess / WebProcessPool.h
1 /*
2  * Copyright (C) 2010, 2011, 2012, 2013 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     UserObservablePageToken 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 private:
367     void platformInitialize();
368
369     void platformInitializeWebProcess(WebProcessCreationParameters&);
370     void platformInvalidateContext();
371
372     WebProcessProxy& createNewWebProcess();
373
374     void requestWebContentStatistics(StatisticsRequest*);
375     void requestNetworkingStatistics(StatisticsRequest*);
376
377     void platformInitializeNetworkProcess(NetworkProcessCreationParameters&);
378
379     void handleMessage(IPC::Connection&, const String& messageName, const UserData& messageBody);
380     void handleSynchronousMessage(IPC::Connection&, const String& messageName, const UserData& messageBody, UserData& returnUserData);
381
382     void didGetStatistics(const StatisticsData&, uint64_t callbackID);
383
384     // IPC::MessageReceiver.
385     // Implemented in generated WebProcessPoolMessageReceiver.cpp
386     virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override;
387     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
388
389     static void languageChanged(void* context);
390     void languageChanged();
391
392     String platformDefaultIconDatabasePath() const;
393
394 #if PLATFORM(IOS) || ENABLE(SECCOMP_FILTERS)
395     String cookieStorageDirectory() const;
396 #endif
397
398 #if PLATFORM(IOS)
399     String parentBundleDirectory() const;
400     String networkingCachesDirectory() const;
401     String webContentCachesDirectory() const;
402     String containerTemporaryDirectory() const;
403 #endif
404
405 #if PLATFORM(COCOA)
406     void registerNotificationObservers();
407     void unregisterNotificationObservers();
408 #endif
409
410     void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, WebCore::SessionID);
411     void plugInDidReceiveUserInteraction(unsigned plugInOriginHash, WebCore::SessionID);
412
413     void setAnyPageGroupMightHavePrivateBrowsingEnabled(bool);
414
415 #if ENABLE(NETSCAPE_PLUGIN_API)
416     // PluginInfoStoreClient:
417     virtual void pluginInfoStoreDidLoadPlugins(PluginInfoStore*) override;
418 #endif
419
420     Ref<API::ProcessPoolConfiguration> m_configuration;
421
422     IPC::MessageReceiverMap m_messageReceiverMap;
423
424     Vector<RefPtr<WebProcessProxy>> m_processes;
425     bool m_haveInitialEmptyProcess;
426
427     WebProcessProxy* m_processWithPageCache;
428
429     Ref<WebPageGroup> m_defaultPageGroup;
430
431     RefPtr<API::Object> m_injectedBundleInitializationUserData;
432     WebContextInjectedBundleClient m_injectedBundleClient;
433
434     WebContextClient m_client;
435     WebContextConnectionClient m_connectionClient;
436     std::unique_ptr<API::AutomationClient> m_automationClient;
437     std::unique_ptr<API::DownloadClient> m_downloadClient;
438     std::unique_ptr<API::LegacyContextHistoryClient> m_historyClient;
439
440     RefPtr<WebAutomationSession> m_automationSession;
441
442 #if ENABLE(NETSCAPE_PLUGIN_API)
443     PluginInfoStore m_pluginInfoStore;
444 #endif
445     Ref<VisitedLinkStore> m_visitedLinkStore;
446     bool m_visitedLinksPopulated;
447
448     PlugInAutoStartProvider m_plugInAutoStartProvider;
449         
450     HashSet<String> m_schemesToRegisterAsEmptyDocument;
451     HashSet<String> m_schemesToRegisterAsSecure;
452     HashSet<String> m_schemesToRegisterAsBypassingContentSecurityPolicy;
453     HashSet<String> m_schemesToSetDomainRelaxationForbiddenFor;
454     HashSet<String> m_schemesToRegisterAsLocal;
455     HashSet<String> m_schemesToRegisterAsNoAccess;
456     HashSet<String> m_schemesToRegisterAsDisplayIsolated;
457     HashSet<String> m_schemesToRegisterAsCORSEnabled;
458     HashSet<String> m_schemesToRegisterAsAlwaysRevalidated;
459 #if ENABLE(CACHE_PARTITIONING)
460     HashSet<String> m_schemesToRegisterAsCachePartitioned;
461 #endif
462
463     bool m_alwaysUsesComplexTextCodePath;
464     bool m_shouldUseFontSmoothing;
465
466     Vector<String> m_fontWhitelist;
467
468     // Messages that were posted before any pages were created.
469     // The client should use initialization messages instead, so that a restarted process would get the same state.
470     Vector<std::pair<String, RefPtr<API::Object>>> m_messagesToInjectedBundlePostedToEmptyContext;
471
472     bool m_memorySamplerEnabled;
473     double m_memorySamplerInterval;
474
475     RefPtr<WebIconDatabase> m_iconDatabase;
476
477     const RefPtr<API::WebsiteDataStore> m_websiteDataStore;
478
479     typedef HashMap<const char*, RefPtr<WebContextSupplement>, PtrHash<const char*>> WebContextSupplementMap;
480     WebContextSupplementMap m_supplements;
481
482 #if USE(SOUP)
483     HTTPCookieAcceptPolicy m_initialHTTPCookieAcceptPolicy;
484 #endif
485
486 #if PLATFORM(MAC)
487     RetainPtr<NSObject> m_enhancedAccessibilityObserver;
488     RetainPtr<NSObject> m_automaticTextReplacementNotificationObserver;
489     RetainPtr<NSObject> m_automaticSpellingCorrectionNotificationObserver;
490     RetainPtr<NSObject> m_automaticQuoteSubstitutionNotificationObserver;
491     RetainPtr<NSObject> m_automaticDashSubstitutionNotificationObserver;
492 #endif
493
494     String m_overrideIconDatabasePath;
495     String m_overrideCookieStorageDirectory;
496
497     bool m_shouldUseTestingNetworkSession;
498
499     bool m_processTerminationEnabled;
500
501     bool m_canHandleHTTPSServerTrustEvaluation;
502     bool m_didNetworkProcessCrash;
503     RefPtr<NetworkProcessProxy> m_networkProcess;
504
505 #if ENABLE(DATABASE_PROCESS)
506     RefPtr<DatabaseProcessProxy> m_databaseProcess;
507 #endif
508     
509     HashMap<uint64_t, RefPtr<DictionaryCallback>> m_dictionaryCallbacks;
510     HashMap<uint64_t, RefPtr<StatisticsRequest>> m_statisticsRequests;
511
512 #if USE(SOUP)
513     bool m_ignoreTLSErrors { true };
514 #endif
515
516     bool m_memoryCacheDisabled;
517
518     UserObservablePageCounter m_userObservablePageCounter;
519     ProcessSuppressionDisabledCounter m_processSuppressionDisabledForPageCounter;
520     HiddenPageThrottlingAutoIncreasesCounter m_hiddenPageThrottlingAutoIncreasesCounter;
521
522 #if PLATFORM(COCOA)
523     RetainPtr<NSMutableDictionary> m_bundleParameters;
524     ProcessSuppressionDisabledToken m_pluginProcessManagerProcessSuppressionDisabledToken;
525 #endif
526
527 #if ENABLE(CONTENT_EXTENSIONS)
528     HashMap<String, String> m_encodedContentExtensions;
529 #endif
530
531 #if ENABLE(NETSCAPE_PLUGIN_API)
532     HashMap<String, HashMap<String, HashMap<String, uint8_t>>> m_pluginLoadClientPolicies;
533 #endif
534 };
535
536 template<typename T>
537 void WebProcessPool::sendToNetworkingProcess(T&& message)
538 {
539     if (m_networkProcess && m_networkProcess->canSendMessage())
540         m_networkProcess->send(std::forward<T>(message), 0);
541 }
542
543 template<typename T>
544 void WebProcessPool::sendToNetworkingProcessRelaunchingIfNecessary(T&& message)
545 {
546     ensureNetworkProcess();
547     m_networkProcess->send(std::forward<T>(message), 0);
548 }
549
550 template<typename T>
551 void WebProcessPool::sendToDatabaseProcessRelaunchingIfNecessary(T&& message)
552 {
553 #if ENABLE(DATABASE_PROCESS)
554     ensureDatabaseProcess();
555     m_databaseProcess->send(std::forward<T>(message), 0);
556 #else
557     sendToAllProcessesRelaunchingThemIfNecessary(std::forward<T>(message));
558 #endif
559 }
560
561 template<typename T>
562 void WebProcessPool::sendToAllProcesses(const T& message)
563 {
564     size_t processCount = m_processes.size();
565     for (size_t i = 0; i < processCount; ++i) {
566         WebProcessProxy* process = m_processes[i].get();
567         if (process->canSendMessage())
568             process->send(T(message), 0);
569     }
570 }
571
572 template<typename T>
573 void WebProcessPool::sendToAllProcessesRelaunchingThemIfNecessary(const T& message)
574 {
575     // 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.
576     sendToAllProcesses(message);
577 }
578
579 template<typename T>
580 void WebProcessPool::sendToOneProcess(T&& message)
581 {
582     bool messageSent = false;
583     size_t processCount = m_processes.size();
584     for (size_t i = 0; i < processCount; ++i) {
585         WebProcessProxy* process = m_processes[i].get();
586         if (process->canSendMessage()) {
587             process->send(std::forward<T>(message), 0);
588             messageSent = true;
589             break;
590         }
591     }
592
593     if (!messageSent) {
594         warmInitialProcess();
595         RefPtr<WebProcessProxy> process = m_processes.last();
596         if (process->canSendMessage())
597             process->send(std::forward<T>(message), 0);
598     }
599 }
600
601 } // namespace WebKit
602
603 #endif // UIProcessPool_h