@@ -40,6 +40,12 @@ namespace internal {
4040// This defines the class FIRDatabasePointer, which is a C++-compatible wrapper
4141// around the FIRDatabase Obj-C class.
4242OBJ_C_PTR_WRAPPER (FIRDatabase);
43+ // This defines the class firebase::database::internal::NSRecursiveLockPointer,
44+ // which is a C++-compatible wrapper around the NSRecursiveLock Obj-C class,
45+ // used by observer callbacks of FIRDatabaseQuery.
46+ OBJ_C_PTR_WRAPPER (NSRecursiveLock );
47+
48+ #pragma clang assume_nonnull begin
4349
4450// This is the iOS implementation of Database.
4551class DatabaseInternal {
@@ -82,9 +88,9 @@ class DatabaseInternal {
8288 static void SetVerboseLogging (bool enable);
8389
8490#ifdef __OBJC__
85- bool RegisterValueListener (const internal::QuerySpec& spec,
86- ValueListener* listener,
87- const ValueListenerCleanupData& cleanup_data );
91+ bool RegisterValueListener (
92+ const internal::QuerySpec& spec, ValueListener* listener,
93+ FIRCPPDatabaseQueryCallbackState* callback_state );
8894
8995 bool UnregisterValueListener (const internal::QuerySpec& spec,
9096 ValueListener* listener,
@@ -93,9 +99,9 @@ class DatabaseInternal {
9399 void UnregisterAllValueListeners (const internal::QuerySpec& spec,
94100 FIRDatabaseQuery* query_impl);
95101
96- bool RegisterChildListener (const internal::QuerySpec& spec,
97- ChildListener* listener,
98- const ChildListenerCleanupData& cleanup_data );
102+ bool RegisterChildListener (
103+ const internal::QuerySpec& spec, ChildListener* listener,
104+ FIRCPPDatabaseQueryCallbackState* callback_state );
99105
100106 bool UnregisterChildListener (const internal::QuerySpec& spec,
101107 ChildListener* listener,
@@ -105,38 +111,18 @@ class DatabaseInternal {
105111 FIRDatabaseQuery* query_impl);
106112#endif // __OBJC__
107113
108- // Track a transient listener. If the database is deleted before the listener
109- // finishes, it should discard its pointers.
110- SingleValueListener** AddSingleValueListener (SingleValueListener* listener) {
114+ // Track a transient listener.
115+ void AddSingleValueListener (ValueListener* listener) {
111116 MutexLock lock (listener_mutex_);
112- // If the listener is already being tracked, just return the existing
113- // listener holder.
114- for (auto i = single_value_listeners_.begin ();
115- i != single_value_listeners_.end (); ++i) {
116- SingleValueListener** listener_holder = *i;
117- if (*listener_holder == listener) {
118- return listener_holder;
119- }
120- }
121- // If the listener was not found, register create a new holder and return
122- // it.
123- SingleValueListener** holder = new SingleValueListener*(listener);
124- single_value_listeners_.insert (holder);
125- return holder;
117+ single_value_listeners_.insert (listener);
126118 }
127119
128- // Finish tracking a transient listener. If the database is deleted before the
129- // listener finishes, it should discard its pointers.
130- void RemoveSingleValueListener (SingleValueListener* listener) {
120+ // Finish tracking a transient listener.
121+ void RemoveSingleValueListener (ValueListener* listener) {
131122 MutexLock lock (listener_mutex_);
132- for (auto i = single_value_listeners_.begin ();
133- i != single_value_listeners_.end (); ++i) {
134- SingleValueListener** listener_holder = *i;
135- if (*listener_holder == listener) {
136- single_value_listeners_.erase (i);
137- return ;
138- }
139- }
123+ auto it = single_value_listeners_.find (listener);
124+ if (it == single_value_listeners_.end ()) return ;
125+ single_value_listeners_.erase (it);
140126 }
141127
142128 FutureManager& future_manager () { return future_manager_; }
@@ -151,9 +137,17 @@ class DatabaseInternal {
151137 // The url that was passed to the constructor.
152138 const std::string& constructor_url () const { return constructor_url_; }
153139
140+ #ifdef __OBJC__
141+ // Guard access to C++ objects referenced by
142+ // FIRCPPDatabaseQueryCallbackStatePointer.
143+ NSRecursiveLock * query_lock () const {
144+ return query_lock_->ptr ;
145+ }
146+ #endif // __OBJC__
147+
154148 private:
155149#ifdef __OBJC__
156- FIRDatabase* _Nonnull impl () const { return impl_->ptr ; }
150+ FIRDatabase* impl () const { return impl_->ptr ; }
157151#endif // __OBJC__
158152
159153 // The firebase::App that this Database was created with.
@@ -162,18 +156,22 @@ class DatabaseInternal {
162156 // Object lifetime managed by Objective C ARC.
163157 UniquePtr<FIRDatabasePointer> impl_;
164158
159+ // Lock used to guard access to C++ objects referenced by FIRDatabaseQuery
160+ // callbacks.
161+ UniquePtr<NSRecursiveLockPointer> query_lock_;
162+
165163 // For registering listeners.
166164 Mutex listener_mutex_;
167165
168166 // Listeners indexed by QuerySpec.
169167 ListenerCollection<ValueListener> value_listeners_by_query_;
170168 ListenerCollection<ChildListener> child_listeners_by_query_;
171169
172- std::map<ValueListener*, ValueListenerCleanupData >
170+ std::map<ValueListener*, FIRCPPDatabaseQueryCallbackStatePointer >
173171 cleanup_value_listener_lookup_;
174- std::map<ChildListener*, ChildListenerCleanupData >
172+ std::map<ChildListener*, FIRCPPDatabaseQueryCallbackStatePointer >
175173 cleanup_child_listener_lookup_;
176- std::set<SingleValueListener* *> single_value_listeners_;
174+ std::set<ValueListener *> single_value_listeners_;
177175
178176 FutureManager future_manager_;
179177
@@ -184,6 +182,8 @@ class DatabaseInternal {
184182 std::string constructor_url_;
185183};
186184
185+ #pragma clang assume_nonnull end
186+
187187} // namespace internal
188188} // namespace database
189189} // namespace firebase
0 commit comments