diff --git a/database/src/desktop/core/info_listen_provider.cc b/database/src/desktop/core/info_listen_provider.cc index 0ce1df5068..97c2b63c9c 100644 --- a/database/src/desktop/core/info_listen_provider.cc +++ b/database/src/desktop/core/info_listen_provider.cc @@ -19,14 +19,13 @@ #include "database/src/desktop/core/listen_provider.h" #include "database/src/desktop/core/tag.h" #include "database/src/desktop/util_desktop.h" -#include "database/src/desktop/view/view.h" namespace firebase { namespace database { namespace internal { void InfoListenProvider::StartListening(const QuerySpec& query_spec, - const Tag& tag, const View* view) { + const Tag& tag) { repo_->scheduler().Schedule([this, query_spec]() { const Variant& value = VariantGetChild(info_data_, query_spec.path); if (!VariantIsEmpty(value)) { diff --git a/database/src/desktop/core/info_listen_provider.h b/database/src/desktop/core/info_listen_provider.h index f183bcb612..f2c28dbc36 100644 --- a/database/src/desktop/core/info_listen_provider.h +++ b/database/src/desktop/core/info_listen_provider.h @@ -34,8 +34,7 @@ class InfoListenProvider : public ListenProvider { void set_sync_tree(SyncTree* sync_tree) { sync_tree_ = sync_tree; } - void StartListening(const QuerySpec& query_spec, const Tag& tag, - const View* view) override; + void StartListening(const QuerySpec& query_spec, const Tag& tag) override; void StopListening(const QuerySpec& query_spec, const Tag& tag) override; diff --git a/database/src/desktop/core/listen_provider.h b/database/src/desktop/core/listen_provider.h index 7772a3016e..29fc360c16 100644 --- a/database/src/desktop/core/listen_provider.h +++ b/database/src/desktop/core/listen_provider.h @@ -17,7 +17,6 @@ #include "database/src/common/query_spec.h" #include "database/src/desktop/core/tag.h" -#include "database/src/desktop/view/view.h" namespace firebase { namespace database { @@ -32,8 +31,7 @@ class ListenProvider { // Begin listening on a location with a set of parameters given by the // QuerySpec. While listening, the server will send down updates which will be // parsed and passed along to the SyncTree to be cached locally. - virtual void StartListening(const QuerySpec& query_spec, const Tag& tag, - const View* view) = 0; + virtual void StartListening(const QuerySpec& query_spec, const Tag& tag) = 0; // Stop listening on a location given by the QuerySpec. virtual void StopListening(const QuerySpec& query_spec, const Tag& tag) = 0; diff --git a/database/src/desktop/core/sync_tree.cc b/database/src/desktop/core/sync_tree.cc index db33274877..d6d4b306d9 100644 --- a/database/src/desktop/core/sync_tree.cc +++ b/database/src/desktop/core/sync_tree.cc @@ -207,8 +207,7 @@ std::vector SyncTree::AddEventRegistration( writes_cache, server_cache, persistence_manager_.get()); if (!view_already_exists && !found_ancestor_default_view) { - const View* view = sync_point->ViewForQuery(query_spec); - SetupListener(query_spec, view); + SetupListener(query_spec); } return true; }); @@ -547,11 +546,10 @@ static QuerySpec QuerySpecForListening(const QuerySpec& query_spec) { } } -void SyncTree::SetupListener(const QuerySpec& query_spec, const View* view) { +void SyncTree::SetupListener(const QuerySpec& query_spec) { const Path& path = query_spec.path; const Tag& tag = TagForQuerySpec(query_spec); - listen_provider_->StartListening(QuerySpecForListening(query_spec), tag, - view); + listen_provider_->StartListening(QuerySpecForListening(query_spec), tag); Tree* subtree = sync_point_tree_.GetChild(path); @@ -663,7 +661,7 @@ std::vector SyncTree::RemoveEventRegistration( for (const View* view : new_views) { QuerySpec new_query = view->query_spec(); listen_provider_->StartListening(QuerySpecForListening(new_query), - TagForQuerySpec(new_query), view); + TagForQuerySpec(new_query)); } } else { // There's nothing below us, so nothing we need to start listening on diff --git a/database/src/desktop/core/sync_tree.h b/database/src/desktop/core/sync_tree.h index 23f089dfe3..67f25bb541 100644 --- a/database/src/desktop/core/sync_tree.h +++ b/database/src/desktop/core/sync_tree.h @@ -148,7 +148,7 @@ class SyncTree { private: // For a given new listen, manage the de-duplication of outstanding // subscriptions. - void SetupListener(const QuerySpec& query_spec, const View* view); + void SetupListener(const QuerySpec& query_spec); // Recursive helper for ApplyOperationToSyncPoints std::vector ApplyOperationHelper(const Operation& operation, diff --git a/database/src/desktop/core/web_socket_listen_provider.cc b/database/src/desktop/core/web_socket_listen_provider.cc index 8793a842f5..fca23ee207 100644 --- a/database/src/desktop/core/web_socket_listen_provider.cc +++ b/database/src/desktop/core/web_socket_listen_provider.cc @@ -20,7 +20,6 @@ #include "database/src/desktop/connection/persistent_connection.h" #include "database/src/desktop/core/listen_provider.h" #include "database/src/desktop/core/tag.h" -#include "database/src/desktop/view/view.h" namespace firebase { namespace database { @@ -34,20 +33,18 @@ class WebSocketListenResponse : public connection::Response { WebSocketListenResponse(const Response::ResponseCallback& callback, const Repo::ThisRef& repo_ref, SyncTree* sync_tree, const QuerySpec& query_spec, const Tag& tag, - const View* view, Logger* logger) + Logger* logger) : connection::Response(callback), repo_ref_(repo_ref), sync_tree_(sync_tree), query_spec_(query_spec), tag_(tag), - view_(view), logger_(logger) {} Repo::ThisRef& repo_ref() { return repo_ref_; } SyncTree* sync_tree() { return sync_tree_; } const QuerySpec& query_spec() const { return query_spec_; } const Tag& tag() const { return tag_; } - const View* view() const { return view_; } Logger* logger() { return logger_; } private: @@ -55,12 +52,11 @@ class WebSocketListenResponse : public connection::Response { SyncTree* sync_tree_; QuerySpec query_spec_; Tag tag_; - const View* view_; Logger* logger_; }; void WebSocketListenProvider::StartListening(const QuerySpec& query_spec, - const Tag& tag, const View* view) { + const Tag& tag) { connection_->Listen( query_spec, tag, std::make_shared( @@ -79,7 +75,7 @@ void WebSocketListenProvider::StartListening(const QuerySpec& query_spec, std::vector events; if (!response->HasError()) { - const QuerySpec& query_spec = response->view()->query_spec(); + const QuerySpec& query_spec = response->query_spec(); const Tag& tag = response->tag(); if (tag.has_value()) { events = response->sync_tree()->ApplyTaggedListenComplete(tag); @@ -101,7 +97,7 @@ void WebSocketListenProvider::StartListening(const QuerySpec& query_spec, } repo->PostEvents(events); }, - repo_->this_ref(), sync_tree_, query_spec, tag, view, logger_)); + repo_->this_ref(), sync_tree_, query_spec, tag, logger_)); } void WebSocketListenProvider::StopListening(const QuerySpec& query_spec, diff --git a/database/src/desktop/core/web_socket_listen_provider.h b/database/src/desktop/core/web_socket_listen_provider.h index a3c7641a85..d83ad5169c 100644 --- a/database/src/desktop/core/web_socket_listen_provider.h +++ b/database/src/desktop/core/web_socket_listen_provider.h @@ -39,8 +39,7 @@ class WebSocketListenProvider : public ListenProvider { void set_sync_tree(SyncTree* sync_tree) { sync_tree_ = sync_tree; } - void StartListening(const QuerySpec& query_spec, const Tag& tag, - const View* view) override; + void StartListening(const QuerySpec& query_spec, const Tag& tag) override; void StopListening(const QuerySpec& query_spec, const Tag& tag) override; diff --git a/database/tests/desktop/core/sync_point_spec_test.cc b/database/tests/desktop/core/sync_point_spec_test.cc index a54854cd5b..102e5a8388 100644 --- a/database/tests/desktop/core/sync_point_spec_test.cc +++ b/database/tests/desktop/core/sync_point_spec_test.cc @@ -77,8 +77,7 @@ class FakeListenProvider : public ListenProvider { ~FakeListenProvider() override {} - void StartListening(const QuerySpec& query_spec, const Tag& tag, - const View* view) override { + void StartListening(const QuerySpec& query_spec, const Tag& tag) override { const Path& path = query_spec.path; logger_->LogDebug( "Listening at %s for Tag %s", path.c_str(), diff --git a/database/tests/desktop/test/mock_listen_provider.h b/database/tests/desktop/test/mock_listen_provider.h index 2ef6056347..6c8d41167a 100644 --- a/database/tests/desktop/test/mock_listen_provider.h +++ b/database/tests/desktop/test/mock_listen_provider.h @@ -27,8 +27,7 @@ namespace internal { class MockListenProvider : public ListenProvider { public: MOCK_METHOD(void, StartListening, - (const QuerySpec& query_spec, const Tag& tag, const View* view), - (override)); + (const QuerySpec& query_spec, const Tag& tag), (override)); MOCK_METHOD(void, StopListening, (const QuerySpec& query_spec, const Tag& tag), (override)); }; diff --git a/release_build_files/readme.md b/release_build_files/readme.md index bfb9836459..22bbebc02e 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -613,6 +613,10 @@ workflow use only during the development of your app, not for publicly shipping code. ## Release Notes +### Upcoming +- Changes + - Realtime Database (Desktop): Fixed an intermittent use-after-free crash (`ACCESS_VIOLATION`) when detaching a listener while a WebSocket listen response is pending. + ### 13.10.0 - Changes - General (Android): Update to Firebase Android BoM version 34.16.0.