Changeset 245649 in webkit
- Timestamp:
- May 22, 2019 3:03:50 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r245639 r245649 1 2019-05-22 Sihui Liu <sihui_liu@apple.com> 2 3 API Test landed in r245540 [Mac WK2] TestWebKitAPI.WKWebView.LocalStorageProcessCrashes is a flaky failure 4 https://bugs.webkit.org/show_bug.cgi?id=198090 5 <rdar://problem/51003644> 6 7 Reviewed by Youenn Fablet. 8 9 We used to dispatch StorageManager message to StorageManager's work queue, which required message handler to be 10 added to queue before receiving first StorageManager message, otherwise network process would not know how to 11 decode the message. 12 13 After r245540, when netork process crashes and dom storage is accessed from web process after that, web process 14 re-establishes its connection to network process, asks network process to add message handler, and then sends 15 StorageManager message immediately. Because work queue message receiver is added on a background thread in 16 network process, it is possible the StorageManager message is received before that. 17 18 A safe and easy resolution is to not dispatch StorageManager message to work queue, so that we don't need to 19 wait for the message receiver to be added. Handling message on the main thread also allows us to untying the 20 knot that binds StorageManager and connection, which may be a preferred design in the future. 21 22 * NetworkProcess/NetworkConnectionToWebProcess.cpp: 23 (WebKit::NetworkConnectionToWebProcess::didReceiveMessage): 24 (WebKit::NetworkConnectionToWebProcess::didReceiveSyncMessage): 25 * NetworkProcess/NetworkProcess.cpp: 26 (WebKit::NetworkProcess::webPageWasAdded): 27 * NetworkProcess/WebStorage/StorageManager.cpp: 28 (WebKit::StorageManager::processDidCloseConnection): 29 (WebKit::StorageManager::createLocalStorageMap): 30 (WebKit::StorageManager::createTransientLocalStorageMap): 31 (WebKit::StorageManager::createSessionStorageMap): 32 (WebKit::StorageManager::destroyStorageMap): 33 (WebKit::didGetValues): 34 (WebKit::StorageManager::getValues): 35 (WebKit::StorageManager::setItem): 36 (WebKit::StorageManager::setItems): 37 (WebKit::StorageManager::removeItem): 38 (WebKit::StorageManager::clear): 39 (WebKit::StorageManager::processWillOpenConnection): Deleted. 40 (WebKit::StorageManager::dispatchMessageToQueue): Deleted. 41 (WebKit::StorageManager::dispatchSyncMessageToQueue): Deleted. 42 * NetworkProcess/WebStorage/StorageManager.h: 43 1 44 2019-05-22 Antoine Quint <graouts@apple.com> 2 45 -
trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
r245540 r245649 228 228 if (decoder.messageReceiverName() == Messages::StorageManager::messageReceiverName()) { 229 229 if (auto* session = m_networkProcess->networkSessionByConnection(connection)) { 230 session->storageManager().di spatchMessageToQueue(connection, decoder);230 session->storageManager().didReceiveMessage(connection, decoder); 231 231 return; 232 232 } … … 274 274 if (decoder.messageReceiverName() == Messages::StorageManager::messageReceiverName()) { 275 275 if (auto* session = m_networkProcess->networkSessionByConnection(connection)) { 276 session->storageManager().di spatchSyncMessageToQueue(connection, decoder, reply);276 session->storageManager().didReceiveSyncMessage(connection, decoder, reply); 277 277 return; 278 278 } -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp
r245540 r245649 2636 2636 auto connectionID = connection.uniqueID(); 2637 2637 m_sessionByConnection.ensure(connectionID, [&]() { 2638 storageManager.processWillOpenConnection(connection);2639 2638 return sessionID; 2640 2639 }); -
trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp
r245540 r245649 552 552 } 553 553 554 void StorageManager::processWillOpenConnection(IPC::Connection& connection)555 {556 connection.addWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName(), m_queue.get(), this);557 }558 559 554 void StorageManager::processDidCloseConnection(IPC::Connection& connection) 560 555 { 561 connection.removeWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName());562 563 556 m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID()]() mutable { 564 557 Vector<std::pair<IPC::Connection::UniqueID, uint64_t>> connectionAndStorageMapIDPairsToRemove; … … 719 712 void StorageManager::createLocalStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData) 720 713 { 721 // FIXME: Replace this check if https://bugs.webkit.org/show_bug.cgi?id=198048 is done.722 ASSERT(!RunLoop::isMain());723 ASSERT(!m_isEphemeral);724 std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connection.uniqueID(), storageMapID); 725 726 // FIXME: This should be a message check.727 ASSERT((HashMap<std::pair<IPC::Connection::UniqueID, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair))); 728 729 auto result = m_storageAreasByConnection.add(connectionAndStorageMapIDPair, nullptr); 730 731 // FIXME: These should be a message checks.732 ASSERT(result.isNewEntry);733 ASSERT((HashMap<uint64_t, RefPtr<LocalStorageNamespace>>::isValidKey(storageNamespaceID))); 734 735 LocalStorageNamespace* localStorageNamespace = getOrCreateLocalStorageNamespace(storageNamespaceID); 736 737 // FIXME: This should be a message check.738 ASSERT(localStorageNamespace); 739 740 auto storageArea = localStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData));741 storageArea->addListener(connection.uniqueID(), storageMapID); 742 743 result.iterator->value = WTFMove(storageArea);714 m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID, storageNamespaceID, securityOriginData = securityOriginData.isolatedCopy()]() mutable { 715 ASSERT(!m_isEphemeral); 716 std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connectionID, storageMapID); 717 718 // FIXME: This should be a message check. 719 ASSERT((HashMap<std::pair<IPC::Connection::UniqueID, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair))); 720 721 auto result = m_storageAreasByConnection.add(connectionAndStorageMapIDPair, nullptr); 722 723 // FIXME: These should be a message checks. 724 ASSERT(result.isNewEntry); 725 ASSERT((HashMap<uint64_t, RefPtr<LocalStorageNamespace>>::isValidKey(storageNamespaceID))); 726 727 LocalStorageNamespace* localStorageNamespace = getOrCreateLocalStorageNamespace(storageNamespaceID); 728 729 // FIXME: This should be a message check. 730 ASSERT(localStorageNamespace); 731 732 auto storageArea = localStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData)); 733 storageArea->addListener(connectionID, storageMapID); 734 735 result.iterator->value = WTFMove(storageArea); 736 }); 744 737 } 745 738 746 739 void StorageManager::createTransientLocalStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& topLevelOriginData, SecurityOriginData&& origin) 747 740 { 748 ASSERT(!RunLoop::isMain());749 750 // FIXME: This should be a message check.751 ASSERT(m_storageAreasByConnection.isValidKey({ connection.uniqueID(), storageMapID })); 752 753 // See if we already have session storage for this connection/origin combo.754 // If so, update the map with the new ID, otherwise keep on trucking.755 for (auto it = m_storageAreasByConnection.begin(), end = m_storageAreasByConnection.end(); it != end; ++it) {756 if (it->key.first != connection.uniqueID())757 continue;758 Ref<StorageArea> area = *it->value;759 if (!area->isSessionStorage())760 continue;761 if (!origin.securityOrigin()->isSameSchemeHostPort(area->securityOrigin().securityOrigin().get()))762 continue;763 area->addListener(connection.uniqueID(), storageMapID);764 // If the storageMapID used as key in m_storageAreasByConnection is no longer one of the StorageArea's listeners, then this means765 // that destroyStorageMap() was already called for that storageMapID but it decided not to remove it from m_storageAreasByConnection766 // so that we could reuse it later on for the same connection/origin combo. In this case, it is safe to remove the previous767 // storageMapID from m_storageAreasByConnection.768 if (!area->hasListener(connection.uniqueID(), it->key.second))769 m_storageAreasByConnection. remove(it);770 m_storageAreasByConnection.add({ connection.uniqueID(), storageMapID }, WTFMove(area));771 return;772 } 773 774 auto& slot = m_storageAreasByConnection.add({ connection.uniqueID(), storageMapID }, nullptr).iterator->value; 775 776 // FIXME: This should be a message check.777 ASSERT(!slot); 778 779 auto* transientLocalStorageNamespace = getOrCreateTransientLocalStorageNamespace(storageNamespaceID, WTFMove(topLevelOriginData)); 780 781 auto storageArea = transientLocalStorageNamespace->getOrCreateStorageArea(WTFMove(origin));782 storageArea->addListener(connection.uniqueID(), storageMapID); 783 784 slot = WTFMove(storageArea);741 m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID, storageNamespaceID, topLevelOriginData = topLevelOriginData.isolatedCopy(), origin = origin.isolatedCopy()]() mutable { 742 // FIXME: This should be a message check. 743 ASSERT(m_storageAreasByConnection.isValidKey({ connectionID, storageMapID })); 744 745 // See if we already have session storage for this connection/origin combo. 746 // If so, update the map with the new ID, otherwise keep on trucking. 747 for (auto it = m_storageAreasByConnection.begin(), end = m_storageAreasByConnection.end(); it != end; ++it) { 748 if (it->key.first != connectionID) 749 continue; 750 Ref<StorageArea> area = *it->value; 751 if (!area->isSessionStorage()) 752 continue; 753 if (!origin.securityOrigin()->isSameSchemeHostPort(area->securityOrigin().securityOrigin().get())) 754 continue; 755 area->addListener(connectionID, storageMapID); 756 // If the storageMapID used as key in m_storageAreasByConnection is no longer one of the StorageArea's listeners, then this means 757 // that destroyStorageMap() was already called for that storageMapID but it decided not to remove it from m_storageAreasByConnection 758 // so that we could reuse it later on for the same connection/origin combo. In this case, it is safe to remove the previous 759 // storageMapID from m_storageAreasByConnection. 760 if (!area->hasListener(connectionID, it->key.second)) 761 m_storageAreasByConnection.remove(it); 762 m_storageAreasByConnection.add({ connectionID, storageMapID }, WTFMove(area)); 763 return; 764 } 765 766 auto& slot = m_storageAreasByConnection.add({ connectionID, storageMapID }, nullptr).iterator->value; 767 768 // FIXME: This should be a message check. 769 ASSERT(!slot); 770 771 auto* transientLocalStorageNamespace = getOrCreateTransientLocalStorageNamespace(storageNamespaceID, WTFMove(topLevelOriginData)); 772 773 auto storageArea = transientLocalStorageNamespace->getOrCreateStorageArea(WTFMove(origin)); 774 storageArea->addListener(connectionID, storageMapID); 775 776 slot = WTFMove(storageArea); 777 }); 785 778 } 786 779 787 780 void StorageManager::createSessionStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData) 788 781 { 789 ASSERT(!RunLoop::isMain());790 791 if (m_isEphemeral) {792 m_ephemeralStorage.add(securityOriginData, WebCore::StorageMap::create(localStorageDatabaseQuotaInBytes));793 return;794 }795 // FIXME: This should be a message check.796 ASSERT(m_sessionStorageNamespaces.isValidKey(storageNamespaceID)); 797 798 SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID);799 if (!sessionStorageNamespace) {800 // We're getting an incoming message from the web process that's for session storage for a web page801 // that has already been closed, just ignore it.802 return;803 } 804 805 // FIXME: This should be a message check.806 ASSERT(m_storageAreasByConnection.isValidKey({ connection.uniqueID(), storageMapID })); 807 808 auto& slot = m_storageAreasByConnection.add({ connection.uniqueID(), storageMapID }, nullptr).iterator->value; 809 810 // FIXME: This should be a message check.811 ASSERT(!slot); 812 813 // FIXME: This should be a message check.814 ASSERT(sessionStorageNamespace->allowedConnections().contains(connection.uniqueID())); 815 816 auto storageArea = sessionStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData));817 storageArea->addListener(connection.uniqueID(), storageMapID); 818 819 slot = WTFMove(storageArea);782 m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID, storageNamespaceID, securityOriginData = securityOriginData.isolatedCopy()]() mutable { 783 if (m_isEphemeral) { 784 m_ephemeralStorage.add(securityOriginData, WebCore::StorageMap::create(localStorageDatabaseQuotaInBytes)); 785 return; 786 } 787 // FIXME: This should be a message check. 788 ASSERT(m_sessionStorageNamespaces.isValidKey(storageNamespaceID)); 789 790 SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID); 791 if (!sessionStorageNamespace) { 792 // We're getting an incoming message from the web process that's for session storage for a web page 793 // that has already been closed, just ignore it. 794 return; 795 } 796 797 // FIXME: This should be a message check. 798 ASSERT(m_storageAreasByConnection.isValidKey({ connectionID, storageMapID })); 799 800 auto& slot = m_storageAreasByConnection.add({ connectionID, storageMapID }, nullptr).iterator->value; 801 802 // FIXME: This should be a message check. 803 ASSERT(!slot); 804 805 // FIXME: This should be a message check. 806 ASSERT(sessionStorageNamespace->allowedConnections().contains(connectionID)); 807 808 auto storageArea = sessionStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData)); 809 storageArea->addListener(connectionID, storageMapID); 810 811 slot = WTFMove(storageArea); 812 }); 820 813 } 821 814 822 815 void StorageManager::destroyStorageMap(IPC::Connection& connection, uint64_t storageMapID) 823 816 { 824 ASSERT(!RunLoop::isMain()); 825 826 std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connection.uniqueID(), storageMapID); 827 828 // FIXME: This should be a message check. 829 ASSERT(m_storageAreasByConnection.isValidKey(connectionAndStorageMapIDPair)); 830 831 auto it = m_storageAreasByConnection.find(connectionAndStorageMapIDPair); 832 if (it == m_storageAreasByConnection.end()) { 833 // The connection has been removed because the last page was closed. 834 return; 835 } 836 837 it->value->removeListener(connection.uniqueID(), storageMapID); 838 839 // Don't remove session storage maps. The web process may reconnect and expect the data to still be around. 840 if (it->value->isSessionStorage()) 841 return; 842 843 m_storageAreasByConnection.remove(connectionAndStorageMapIDPair); 844 } 845 846 void StorageManager::getValues(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t storageMapSeed, CompletionHandler<void(const HashMap<String, String>&)>&& completionHandler) 847 { 848 ASSERT(!RunLoop::isMain()); 849 850 auto* storageArea = findStorageArea(connection, storageMapID); 851 if (!storageArea) { 852 if (m_isEphemeral) { 853 if (auto storageMap = m_ephemeralStorage.get(securityOriginData)) 854 return completionHandler(storageMap->items()); 855 } 856 // This is a session storage area for a page that has already been closed. Ignore it. 857 return completionHandler({ }); 858 } 859 860 completionHandler(storageArea->items()); 861 connection.send(Messages::StorageAreaMap::DidGetValues(storageMapSeed), storageMapID); 817 m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID]() mutable { 818 std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connectionID, storageMapID); 819 820 // FIXME: This should be a message check. 821 ASSERT(m_storageAreasByConnection.isValidKey(connectionAndStorageMapIDPair)); 822 823 auto it = m_storageAreasByConnection.find(connectionAndStorageMapIDPair); 824 if (it == m_storageAreasByConnection.end()) { 825 // The connection has been removed because the last page was closed. 826 return; 827 } 828 829 it->value->removeListener(connectionID, storageMapID); 830 831 // Don't remove session storage maps. The web process may reconnect and expect the data to still be around. 832 if (it->value->isSessionStorage()) 833 return; 834 835 m_storageAreasByConnection.remove(connectionAndStorageMapIDPair); 836 }); 837 } 838 839 static void didGetValues(IPC::Connection& connection, uint64_t storageMapID, const HashMap<String, String>& items, GetValuesCallback&& completionHandler) 840 { 841 RunLoop::main().dispatch([items = crossThreadCopy(items), completionHandler = WTFMove(completionHandler)]() mutable { 842 completionHandler(items); 843 }); 844 } 845 846 void StorageManager::getValues(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t storageMapSeed, GetValuesCallback&& completionHandler) 847 { 848 m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, storageMapSeed, completionHandler = WTFMove(completionHandler)]() mutable { 849 auto* storageArea = findStorageArea(connection.get(), storageMapID); 850 if (!storageArea) { 851 if (m_isEphemeral) { 852 if (auto storageMap = m_ephemeralStorage.get(securityOriginData)) 853 return didGetValues(connection.get(), storageMapID, storageMap->items(), WTFMove(completionHandler)); 854 } 855 // This is a session storage area for a page that has already been closed. Ignore it. 856 return didGetValues(connection.get(), storageMapID, { }, WTFMove(completionHandler)); 857 } 858 didGetValues(connection.get(), storageMapID, storageArea->items(), WTFMove(completionHandler)); 859 connection->send(Messages::StorageAreaMap::DidGetValues(storageMapSeed), storageMapID); 860 }); 862 861 } 863 862 864 863 void StorageManager::setItem(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString) 865 864 { 866 ASSERT(!RunLoop::isMain());867 868 auto* storageArea = findStorageArea(connection, storageMapID);869 if (!storageArea) {870 if (m_isEphemeral) {871 if (auto storageMap = m_ephemeralStorage.get(securityOriginData)) {872 String oldValue;873 bool quotaException;874 storageMap->setItem(key, value, oldValue, quotaException);865 m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, sourceStorageAreaID, storageMapSeed, key = key.isolatedCopy(), value = value.isolatedCopy(), urlString = urlString.isolatedCopy()]() mutable { 866 auto* storageArea = findStorageArea(connection.get(), storageMapID); 867 if (!storageArea) { 868 if (m_isEphemeral) { 869 if (auto storageMap = m_ephemeralStorage.get(securityOriginData)) { 870 String oldValue; 871 bool quotaException; 872 storageMap->setItem(key, value, oldValue, quotaException); 873 } 875 874 } 876 }877 // This is a session storage area for a page that has already been closed. Ignore it.878 return;879 } 880 881 bool quotaError;882 storageArea->setItem(connection.uniqueID(), sourceStorageAreaID, key, value, urlString, quotaError);883 connection.send(Messages::StorageAreaMap::DidSetItem(storageMapSeed, key, quotaError), storageMapID);875 // This is a session storage area for a page that has already been closed. Ignore it. 876 return; 877 } 878 879 bool quotaError; 880 storageArea->setItem(connection->uniqueID(), sourceStorageAreaID, key, value, urlString, quotaError); 881 connection->send(Messages::StorageAreaMap::DidSetItem(storageMapSeed, key, quotaError), storageMapID); 882 }); 884 883 } 885 884 886 885 void StorageManager::setItems(IPC::Connection& connection, uint64_t storageMapID, const HashMap<String, String>& items) 887 886 { 888 ASSERT(!RunLoop::isMain());889 890 if (auto* storageArea = findStorageArea(connection, storageMapID))891 storageArea->setItems(items);887 m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), storageMapID, items = crossThreadCopy(items)]() mutable { 888 if (auto* storageArea = findStorageArea(connection.get(), storageMapID)) 889 storageArea->setItems(items); 890 }); 892 891 } 893 892 894 893 void StorageManager::removeItem(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString) 895 894 { 896 ASSERT(!RunLoop::isMain());897 898 auto* storageArea = findStorageArea(connection, storageMapID);899 if (!storageArea) {900 if (m_isEphemeral) {901 if (auto storageMap = m_ephemeralStorage.get(securityOriginData)) {902 String oldValue;903 storageMap->removeItem(key, oldValue);895 m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, sourceStorageAreaID, storageMapSeed, key = key.isolatedCopy(), urlString = urlString.isolatedCopy()]() mutable { 896 auto* storageArea = findStorageArea(connection.get(), storageMapID); 897 if (!storageArea) { 898 if (m_isEphemeral) { 899 if (auto storageMap = m_ephemeralStorage.get(securityOriginData)) { 900 String oldValue; 901 storageMap->removeItem(key, oldValue); 902 } 904 903 } 905 }906 // This is a session storage area for a page that has already been closed. Ignore it.907 return;908 } 909 910 storageArea->removeItem(connection.uniqueID(), sourceStorageAreaID, key, urlString);911 connection.send(Messages::StorageAreaMap::DidRemoveItem(storageMapSeed, key), storageMapID);904 // This is a session storage area for a page that has already been closed. Ignore it. 905 return; 906 } 907 908 storageArea->removeItem(connection->uniqueID(), sourceStorageAreaID, key, urlString); 909 connection->send(Messages::StorageAreaMap::DidRemoveItem(storageMapSeed, key), storageMapID); 910 }); 912 911 } 913 912 914 913 void StorageManager::clear(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString) 915 914 { 916 ASSERT(!RunLoop::isMain());917 918 auto* storageArea = findStorageArea(connection, storageMapID);919 if (!storageArea) {920 if (m_isEphemeral)921 m_ephemeralStorage.remove(securityOriginData);922 // This is a session storage area for a page that has already been closed. Ignore it.923 return;924 } 925 926 storageArea->clear(connection.uniqueID(), sourceStorageAreaID, urlString);927 connection.send(Messages::StorageAreaMap::DidClear(storageMapSeed), storageMapID);915 m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, sourceStorageAreaID, storageMapSeed, urlString = urlString.isolatedCopy()]() mutable { 916 auto* storageArea = findStorageArea(connection.get(), storageMapID); 917 if (!storageArea) { 918 if (m_isEphemeral) 919 m_ephemeralStorage.remove(securityOriginData); 920 // This is a session storage area for a page that has already been closed. Ignore it. 921 return; 922 } 923 924 storageArea->clear(connection->uniqueID(), sourceStorageAreaID, urlString); 925 connection->send(Messages::StorageAreaMap::DidClear(storageMapSeed), storageMapID); 926 }); 928 927 } 929 928 … … 976 975 } 977 976 978 void StorageManager::dispatchMessageToQueue(IPC::Connection& connection, IPC::Decoder& decoder)979 {980 m_queue->dispatch([this, protectedThis = makeRef(*this), &connection, &decoder] {981 didReceiveMessage(connection, decoder);982 });983 }984 985 void StorageManager::dispatchSyncMessageToQueue(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)986 {987 m_queue->dispatch([this, protectedThis = makeRef(*this), &connection, &decoder, replyEncoder = WTFMove(replyEncoder)] () mutable {988 didReceiveSyncMessage(connection, decoder, replyEncoder);989 });990 }991 992 977 } // namespace WebKit -
trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h
r245540 r245649 44 44 class WebProcessProxy; 45 45 46 using GetValuesCallback = CompletionHandler<void(const HashMap<String, String>&)>; 47 46 48 class StorageManager : public IPC::Connection::WorkQueueMessageReceiver { 47 49 public: … … 55 57 void cloneSessionStorageNamespace(uint64_t storageNamespaceID, uint64_t newStorageNamespaceID); 56 58 57 void processWillOpenConnection(IPC::Connection&);58 59 void processDidCloseConnection(IPC::Connection&); 59 60 void waitUntilWritesFinished(); … … 71 72 void getLocalStorageOriginDetails(Function<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&& completionHandler); 72 73 73 void dispatchMessageToQueue(IPC::Connection&, IPC::Decoder&); 74 void dispatchSyncMessageToQueue(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>& replyEncoder); 74 // IPC::Connection::WorkQueueMessageReceiver. 75 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; 76 void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>& replyEncoder) override; 75 77 76 78 private: 77 79 explicit StorageManager(const String& localStorageDirectory); 78 79 // IPC::Connection::WorkQueueMessageReceiver.80 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;81 void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>& replyEncoder) override;82 80 83 81 // Message handlers. … … 87 85 void destroyStorageMap(IPC::Connection&, uint64_t storageMapID); 88 86 89 void getValues(IPC::Connection&, WebCore::SecurityOriginData&&, uint64_t storageMapID, uint64_t storageMapSeed, CompletionHandler<void(const HashMap<String, String>&)>&&);87 void getValues(IPC::Connection&, WebCore::SecurityOriginData&&, uint64_t storageMapID, uint64_t storageMapSeed, GetValuesCallback&&); 90 88 void setItem(IPC::Connection&, WebCore::SecurityOriginData&&, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString); 91 89 void setItems(IPC::Connection&, uint64_t storageMapID, const HashMap<String, String>& items); … … 116 114 HashMap<WebCore::SecurityOriginData, Ref<WebCore::StorageMap>> m_ephemeralStorage; 117 115 bool m_isEphemeral { false }; 118 119 116 }; 120 117 -
trunk/Tools/ChangeLog
r245638 r245649 1 2019-05-22 Sihui Liu <sihui_liu@apple.com> 2 3 API Test landed in r245540 [Mac WK2] TestWebKitAPI.WKWebView.LocalStorageProcessCrashes is a flaky failure 4 https://bugs.webkit.org/show_bug.cgi?id=198090 5 <rdar://problem/51003644> 6 7 Reviewed by Youenn Fablet. 8 9 WebView was wrongly loaded multiple times. 10 11 * TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm: 12 (TEST): 13 1 14 2019-05-22 Jiewen Tan <jiewen_tan@apple.com> 2 15 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm
r245540 r245649 69 69 NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"local-storage-process-crashes" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]; 70 70 [webView loadRequest:request]; 71 71 72 72 receivedScriptMessage = false; 73 [webView loadRequest:request];74 73 TestWebKitAPI::Util::run(&receivedScriptMessage); 75 74 EXPECT_WK_STREQ(@"local:storage", [lastScriptMessage body]); 76 75 77 76 receivedScriptMessage = false; 78 [webView loadRequest:request];79 77 TestWebKitAPI::Util::run(&receivedScriptMessage); 80 78 EXPECT_WK_STREQ(@"session:storage", [lastScriptMessage body]); 81 79 82 80 [configuration.get().processPool _terminateNetworkProcess]; 83 81 84 82 receivedScriptMessage = false; 85 [webView loadRequest:request];86 83 TestWebKitAPI::Util::run(&receivedScriptMessage); 87 84 EXPECT_WK_STREQ(@"Network Process Crashed", [lastScriptMessage body]);
Note: See TracChangeset
for help on using the changeset viewer.