@@ -207,41 +207,63 @@ inline FutureBase::FutureBase(const FutureBase& rhs)
207
207
: api_(NULL ) // NOLINT
208
208
{ // NOLINT
209
209
*this = rhs;
210
- detail::RegisterForCleanup (api_, this );
211
210
}
212
211
213
212
inline FutureBase& FutureBase::operator =(const FutureBase& rhs) {
214
213
Release ();
215
- api_ = rhs.api_ ;
216
- handle_ = rhs.handle_ ;
217
- if (api_ != NULL ) { // NOLINT
218
- api_->ReferenceFuture (handle_);
214
+
215
+ detail::FutureApiInterface* new_api;
216
+ FutureHandle new_handle;
217
+ {
218
+ std::lock_guard<std::mutex> lock (rhs.mutex_ );
219
+ new_api = rhs.api_ ;
220
+ new_handle = rhs.handle_ ;
219
221
}
220
- detail::RegisterForCleanup (api_, this );
222
+
223
+ {
224
+ std::lock_guard<std::mutex> lock (mutex_);
225
+ api_ = new_api;
226
+ handle_ = new_handle;
227
+
228
+ if (api_ != NULL ) { // NOLINT
229
+ api_->ReferenceFuture (handle_);
230
+ }
231
+ detail::RegisterForCleanup (api_, this );
232
+ }
233
+
221
234
return *this ;
222
235
}
223
236
224
237
#if defined(FIREBASE_USE_MOVE_OPERATORS)
225
238
inline FutureBase::FutureBase (FutureBase&& rhs) noexcept
226
239
: api_(NULL ) // NOLINT
227
240
{
228
- detail::UnregisterForCleanup (rhs.api_ , &rhs);
229
241
*this = std::move (rhs);
230
- detail::RegisterForCleanup (api_, this );
231
242
}
232
243
233
244
inline FutureBase& FutureBase::operator =(FutureBase&& rhs) noexcept {
234
245
Release ();
235
- detail::UnregisterForCleanup (rhs.api_ , &rhs);
236
- api_ = rhs.api_ ;
237
- handle_ = rhs.handle_ ;
238
- rhs.api_ = NULL ; // NOLINT
246
+
247
+ detail::FutureApiInterface* new_api;
248
+ FutureHandle new_handle;
249
+ {
250
+ std::lock_guard<std::mutex> lock (rhs.mutex_ );
251
+ detail::UnregisterForCleanup (rhs.api_ , &rhs);
252
+ new_api = rhs.api_ ;
253
+ new_handle = rhs.handle_ ;
254
+ rhs.api_ = NULL ; // NOLINT
255
+ }
256
+
257
+ std::lock_guard<std::mutex> lock (mutex_);
258
+ api_ = new_api;
259
+ handle_ = new_handle;
239
260
detail::RegisterForCleanup (api_, this );
240
261
return *this ;
241
262
}
242
263
#endif // defined(FIREBASE_USE_MOVE_OPERATORS)
243
264
244
265
inline void FutureBase::Release () {
266
+ std::lock_guard<std::mutex> lock (mutex_);
245
267
if (api_ != NULL ) { // NOLINT
246
268
detail::UnregisterForCleanup (api_, this );
247
269
api_->ReleaseFuture (handle_);
@@ -250,25 +272,30 @@ inline void FutureBase::Release() {
250
272
}
251
273
252
274
inline FutureStatus FutureBase::status () const {
275
+ std::lock_guard<std::mutex> lock (mutex_);
253
276
return api_ == NULL ? // NOLINT
254
277
kFutureStatusInvalid
255
278
: api_->GetFutureStatus (handle_);
256
279
}
257
280
258
281
inline int FutureBase::error () const {
282
+ std::lock_guard<std::mutex> lock (mutex_);
259
283
return api_ == NULL ? -1 : api_->GetFutureError (handle_); // NOLINT
260
284
}
261
285
262
286
inline const char * FutureBase::error_message () const {
287
+ std::lock_guard<std::mutex> lock (mutex_);
263
288
return api_ == NULL ? NULL : api_->GetFutureErrorMessage (handle_); // NOLINT
264
289
}
265
290
266
291
inline const void * FutureBase::result_void () const {
292
+ std::lock_guard<std::mutex> lock (mutex_);
267
293
return api_ == NULL ? NULL : api_->GetFutureResult (handle_); // NOLINT
268
294
}
269
295
270
296
inline void FutureBase::OnCompletion (CompletionCallback callback,
271
297
void * user_data) const {
298
+ std::lock_guard<std::mutex> lock (mutex_);
272
299
if (api_ != NULL ) { // NOLINT
273
300
api_->AddCompletionCallback (handle_, callback, user_data, nullptr ,
274
301
/* clear_existing_callbacks=*/ true );
@@ -278,6 +305,7 @@ inline void FutureBase::OnCompletion(CompletionCallback callback,
278
305
#if defined(INTERNAL_EXPERIMENTAL)
279
306
inline FutureBase::CompletionCallbackHandle FutureBase::AddOnCompletion (
280
307
CompletionCallback callback, void * user_data) const {
308
+ std::lock_guard<std::mutex> lock (mutex_);
281
309
if (api_ != NULL ) { // NOLINT
282
310
return api_->AddCompletionCallback (handle_, callback, user_data, nullptr ,
283
311
/* clear_existing_callbacks=*/ false );
@@ -287,6 +315,7 @@ inline FutureBase::CompletionCallbackHandle FutureBase::AddOnCompletion(
287
315
288
316
inline void FutureBase::RemoveOnCompletion (
289
317
CompletionCallbackHandle completion_handle) const {
318
+ std::lock_guard<std::mutex> lock (mutex_);
290
319
if (api_ != NULL ) { // NOLINT
291
320
api_->RemoveCompletionCallback (handle_, completion_handle);
292
321
}
@@ -296,6 +325,7 @@ inline void FutureBase::RemoveOnCompletion(
296
325
#if defined(FIREBASE_USE_STD_FUNCTION)
297
326
inline void FutureBase::OnCompletion (
298
327
std::function<void (const FutureBase&)> callback) const {
328
+ std::lock_guard<std::mutex> lock (mutex_);
299
329
if (api_ != NULL ) { // NOLINT
300
330
api_->AddCompletionCallbackLambda (handle_, callback,
301
331
/* clear_existing_callbacks=*/ true );
@@ -305,6 +335,7 @@ inline void FutureBase::OnCompletion(
305
335
#if defined(INTERNAL_EXPERIMENTAL)
306
336
inline FutureBase::CompletionCallbackHandle FutureBase::AddOnCompletion (
307
337
std::function<void (const FutureBase&)> callback) const {
338
+ std::lock_guard<std::mutex> lock (mutex_);
308
339
if (api_ != NULL ) { // NOLINT
309
340
return api_->AddCompletionCallbackLambda (
310
341
handle_, callback,
0 commit comments