5de186e69730ea983ae0c18006edf6b78f357a52
[WebKit.git] / Source / WebKit / UIProcess / WebBackForwardCache.cpp
1 /*
2  * Copyright (C) 2019 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 #include "config.h"
27 #include "WebBackForwardCache.h"
28
29 #include "SuspendedPageProxy.h"
30 #include "WebBackForwardListItem.h"
31 #include "WebPageProxy.h"
32 #include "WebProcessProxy.h"
33
34 namespace WebKit {
35
36 WebBackForwardCache::WebBackForwardCache() = default;
37
38 WebBackForwardCache::~WebBackForwardCache() = default;
39
40 inline void WebBackForwardCache::removeOldestEntry()
41 {
42     ASSERT(!m_itemsWithCachedPage.isEmpty());
43     removeEntry(*m_itemsWithCachedPage.first());
44 }
45
46 void WebBackForwardCache::setCapacity(unsigned capacity)
47 {
48     m_capacity = capacity;
49     while (size() > capacity)
50         removeOldestEntry();
51 }
52
53 void WebBackForwardCache::addEntry(WebBackForwardListItem& item, std::unique_ptr<SuspendedPageProxy>&& suspendedPage)
54 {
55     ASSERT(capacity());
56
57     item.setSuspendedPage(WTFMove(suspendedPage));
58     m_itemsWithCachedPage.add(&item);
59
60     if (size() > capacity())
61         removeOldestEntry();
62     ASSERT(size() <= capacity());
63 }
64
65 void WebBackForwardCache::removeEntry(WebBackForwardListItem& item)
66 {
67     ASSERT(m_itemsWithCachedPage.contains(&item));
68     m_itemsWithCachedPage.remove(&item);
69     item.setSuspendedPage(nullptr);
70 }
71
72 std::unique_ptr<SuspendedPageProxy> WebBackForwardCache::takeEntry(WebBackForwardListItem& item)
73 {
74     ASSERT(m_itemsWithCachedPage.contains(&item));
75     m_itemsWithCachedPage.remove(&item);
76     return item.takeSuspendedPage();
77 }
78
79 void WebBackForwardCache::removeEntriesForProcess(WebProcessProxy& process)
80 {
81     removeEntriesMatching([&process](auto& item) {
82         return &item.suspendedPage()->process() == &process;
83     });
84 }
85
86 void WebBackForwardCache::removeEntriesForPage(WebPageProxy& page)
87 {
88     removeEntriesMatching([pageID = page.identifier()](auto& item) {
89         return item.pageID() == pageID;
90     });
91 }
92
93 void WebBackForwardCache::removeEntriesMatching(const Function<bool(WebBackForwardListItem&)>& matches)
94 {
95     for (auto it = m_itemsWithCachedPage.begin(); it != m_itemsWithCachedPage.end();) {
96         auto current = it;
97         ++it;
98         if (matches(**current)) {
99             (*current)->setSuspendedPage(nullptr);
100             m_itemsWithCachedPage.remove(current);
101         }
102     }
103 }
104
105 void WebBackForwardCache::clear(AllowProcessCaching allowProcessCaching)
106 {
107     auto itemsWithCachedPage = WTFMove(m_itemsWithCachedPage);
108     for (auto* item : itemsWithCachedPage) {
109         auto process = makeRef(item->suspendedPage()->process());
110         item->setSuspendedPage(nullptr);
111         process->maybeShutDown(allowProcessCaching);
112     }
113 }
114
115 } // namespace WebKit.