@@ -40,6 +40,12 @@ namespace internal {
40
40
// This defines the class FIRDatabasePointer, which is a C++-compatible wrapper
41
41
// around the FIRDatabase Obj-C class.
42
42
OBJ_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
43
49
44
50
// This is the iOS implementation of Database.
45
51
class DatabaseInternal {
@@ -82,9 +88,9 @@ class DatabaseInternal {
82
88
static void SetVerboseLogging (bool enable);
83
89
84
90
#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 );
88
94
89
95
bool UnregisterValueListener (const internal::QuerySpec& spec,
90
96
ValueListener* listener,
@@ -93,9 +99,9 @@ class DatabaseInternal {
93
99
void UnregisterAllValueListeners (const internal::QuerySpec& spec,
94
100
FIRDatabaseQuery* query_impl);
95
101
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 );
99
105
100
106
bool UnregisterChildListener (const internal::QuerySpec& spec,
101
107
ChildListener* listener,
@@ -105,38 +111,18 @@ class DatabaseInternal {
105
111
FIRDatabaseQuery* query_impl);
106
112
#endif // __OBJC__
107
113
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) {
111
116
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);
126
118
}
127
119
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) {
131
122
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);
140
126
}
141
127
142
128
FutureManager& future_manager () { return future_manager_; }
@@ -151,9 +137,17 @@ class DatabaseInternal {
151
137
// The url that was passed to the constructor.
152
138
const std::string& constructor_url () const { return constructor_url_; }
153
139
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
+
154
148
private:
155
149
#ifdef __OBJC__
156
- FIRDatabase* _Nonnull impl () const { return impl_->ptr ; }
150
+ FIRDatabase* impl () const { return impl_->ptr ; }
157
151
#endif // __OBJC__
158
152
159
153
// The firebase::App that this Database was created with.
@@ -162,18 +156,22 @@ class DatabaseInternal {
162
156
// Object lifetime managed by Objective C ARC.
163
157
UniquePtr<FIRDatabasePointer> impl_;
164
158
159
+ // Lock used to guard access to C++ objects referenced by FIRDatabaseQuery
160
+ // callbacks.
161
+ UniquePtr<NSRecursiveLockPointer> query_lock_;
162
+
165
163
// For registering listeners.
166
164
Mutex listener_mutex_;
167
165
168
166
// Listeners indexed by QuerySpec.
169
167
ListenerCollection<ValueListener> value_listeners_by_query_;
170
168
ListenerCollection<ChildListener> child_listeners_by_query_;
171
169
172
- std::map<ValueListener*, ValueListenerCleanupData >
170
+ std::map<ValueListener*, FIRCPPDatabaseQueryCallbackStatePointer >
173
171
cleanup_value_listener_lookup_;
174
- std::map<ChildListener*, ChildListenerCleanupData >
172
+ std::map<ChildListener*, FIRCPPDatabaseQueryCallbackStatePointer >
175
173
cleanup_child_listener_lookup_;
176
- std::set<SingleValueListener* *> single_value_listeners_;
174
+ std::set<ValueListener *> single_value_listeners_;
177
175
178
176
FutureManager future_manager_;
179
177
@@ -184,6 +182,8 @@ class DatabaseInternal {
184
182
std::string constructor_url_;
185
183
};
186
184
185
+ #pragma clang assume_nonnull end
186
+
187
187
} // namespace internal
188
188
} // namespace database
189
189
} // namespace firebase
0 commit comments