@@ -121,7 +121,7 @@ Future<std::string> InstanceId::GetId() const {
121
121
if (!instance_id_internal_) return Future<std::string>();
122
122
123
123
JNIEnv* env = app ().GetJNIEnv ();
124
- SharedPtr<AsyncOperation>* operation =
124
+ SharedPtr<AsyncOperation> operation =
125
125
instance_id_internal_->AddOperation (new AsyncOperation (
126
126
env, instance_id_internal_,
127
127
instance_id_internal_
@@ -130,10 +130,18 @@ Future<std::string> InstanceId::GetId() const {
130
130
util::RunOnBackgroundThread (
131
131
env,
132
132
[](void * function_data) {
133
- SharedPtr<AsyncOperation> operation =
134
- *(static_cast <SharedPtr<AsyncOperation>*>(function_data));
133
+ // Assume that when this callback is called, AsyncOperation should still
134
+ // be in instance_id_internal->operations_ or this callback should not
135
+ // be called at all due to the lock in CppThreadDispatcherContext.
136
+ AsyncOperation* op_ptr = static_cast <AsyncOperation*>(function_data);
135
137
InstanceIdInternal* instance_id_internal =
136
- operation->instance_id_internal ();
138
+ op_ptr->instance_id_internal ();
139
+ // Hold a reference to AsyncOperation so that it will not be deleted
140
+ // during this callback.
141
+ SharedPtr<AsyncOperation> operation =
142
+ instance_id_internal->GetOperationSharedPtr (op_ptr);
143
+ if (!operation) return ;
144
+
137
145
JNIEnv* env = instance_id_internal->instance_id ()->app ().GetJNIEnv ();
138
146
jobject java_instance_id =
139
147
env->NewLocalRef (instance_id_internal->java_instance_id ());
@@ -151,16 +159,16 @@ Future<std::string> InstanceId::GetId() const {
151
159
error.c_str ());
152
160
}
153
161
},
154
- operation, InstanceIdInternal::CanceledWithResult<std::string>,
155
- &(** operation));
162
+ &(* operation) , InstanceIdInternal::CanceledWithResult<std::string>,
163
+ &(*operation));
156
164
return GetIdLastResult ();
157
165
}
158
166
159
167
Future<void > InstanceId::DeleteId () {
160
168
if (!instance_id_internal_) return Future<void >();
161
169
162
170
JNIEnv* env = app ().GetJNIEnv ();
163
- SharedPtr<AsyncOperation>* operation = instance_id_internal_->AddOperation (
171
+ SharedPtr<AsyncOperation> operation = instance_id_internal_->AddOperation (
164
172
new AsyncOperation (env, instance_id_internal_,
165
173
instance_id_internal_
166
174
->FutureAlloc <std::string>(
@@ -169,10 +177,17 @@ Future<void> InstanceId::DeleteId() {
169
177
util::RunOnBackgroundThread (
170
178
env,
171
179
[](void * function_data) {
172
- SharedPtr<AsyncOperation> operation =
173
- *(static_cast <SharedPtr<AsyncOperation>*>(function_data));
180
+ // Assume that when this callback is called, AsyncOperation should still
181
+ // be in instance_id_internal->operations_ or this callback should not
182
+ // be called at all due to the lock in CppThreadDispatcherContext.
183
+ AsyncOperation* op_ptr = static_cast <AsyncOperation*>(function_data);
174
184
InstanceIdInternal* instance_id_internal =
175
- operation->instance_id_internal ();
185
+ op_ptr->instance_id_internal ();
186
+ // Hold a reference to AsyncOperation so that it will not be deleted
187
+ // during this callback.
188
+ SharedPtr<AsyncOperation> operation =
189
+ instance_id_internal->GetOperationSharedPtr (op_ptr);
190
+ if (!operation) return ;
176
191
JNIEnv* env = instance_id_internal->instance_id ()->app ().GetJNIEnv ();
177
192
jobject java_instance_id =
178
193
env->NewLocalRef (instance_id_internal->java_instance_id ());
@@ -187,7 +202,7 @@ Future<void> InstanceId::DeleteId() {
187
202
operation, ExceptionStringToError (error.c_str ()), error.c_str ());
188
203
}
189
204
},
190
- operation, InstanceIdInternal::Canceled, &(* *operation));
205
+ &(* operation) , InstanceIdInternal::Canceled, &(*operation));
191
206
return DeleteIdLastResult ();
192
207
}
193
208
@@ -218,7 +233,7 @@ Future<std::string> InstanceId::GetToken(const char* entity,
218
233
if (!instance_id_internal_) return Future<std::string>();
219
234
220
235
JNIEnv* env = app ().GetJNIEnv ();
221
- SharedPtr<AsyncOperation>* operation = instance_id_internal_->AddOperation (
236
+ SharedPtr<AsyncOperation> operation = instance_id_internal_->AddOperation (
222
237
new AsyncTokenOperation (env, instance_id_internal_,
223
238
instance_id_internal_
224
239
->FutureAlloc <std::string>(
@@ -228,19 +243,26 @@ Future<std::string> InstanceId::GetToken(const char* entity,
228
243
util::RunOnBackgroundThread (
229
244
env,
230
245
[](void * function_data) {
231
- SharedPtr<AsyncOperation> base_operation =
232
- *(static_cast <SharedPtr<AsyncOperation>*>(function_data));
233
- AsyncTokenOperation* operation =
234
- static_cast <AsyncTokenOperation*>(base_operation->derived ());
246
+ // Assume that when this callback is called, AsyncOperation should still
247
+ // be in instance_id_internal->operations_ or this callback should not
248
+ // be called at all due to the lock in CppThreadDispatcherContext.
249
+ AsyncTokenOperation* op_ptr =
250
+ static_cast <AsyncTokenOperation*>(function_data);
235
251
InstanceIdInternal* instance_id_internal =
236
- operation->instance_id_internal ();
252
+ op_ptr->instance_id_internal ();
253
+ // Hold a reference to AsyncOperation so that it will not be deleted
254
+ // during this callback.
255
+ SharedPtr<AsyncOperation> operation =
256
+ instance_id_internal->GetOperationSharedPtr (op_ptr);
257
+ if (!operation) return ;
258
+
237
259
JNIEnv* env = instance_id_internal->instance_id ()->app ().GetJNIEnv ();
238
260
jobject java_instance_id =
239
261
env->NewLocalRef (instance_id_internal->java_instance_id ());
240
262
jmethodID java_instance_id_method =
241
263
instance_id::GetMethodId (instance_id::kGetToken );
242
- jobject entity_jstring = env->NewStringUTF (operation ->entity ().c_str ());
243
- jobject scope_jstring = env->NewStringUTF (operation ->scope ().c_str ());
264
+ jobject entity_jstring = env->NewStringUTF (op_ptr ->entity ().c_str ());
265
+ jobject scope_jstring = env->NewStringUTF (op_ptr ->scope ().c_str ());
244
266
operation->ReleaseExecuteCancelLock ();
245
267
jobject token_jstring =
246
268
env->CallObjectMethod (java_instance_id, java_instance_id_method,
@@ -252,20 +274,20 @@ Future<std::string> InstanceId::GetToken(const char* entity,
252
274
env->DeleteLocalRef (scope_jstring);
253
275
if (operation->AcquireExecuteCancelLock ()) {
254
276
instance_id_internal->CompleteOperationWithResult (
255
- base_operation , token, ExceptionStringToError (error.c_str ()),
277
+ operation , token, ExceptionStringToError (error.c_str ()),
256
278
error.c_str ());
257
279
}
258
280
},
259
- operation, InstanceIdInternal::CanceledWithResult<std::string>,
260
- &(** operation));
281
+ &(* operation) , InstanceIdInternal::CanceledWithResult<std::string>,
282
+ &(*operation));
261
283
return GetTokenLastResult ();
262
284
}
263
285
264
286
Future<void > InstanceId::DeleteToken (const char * entity, const char * scope) {
265
287
if (!instance_id_internal_) return Future<void >();
266
288
267
289
JNIEnv* env = app ().GetJNIEnv ();
268
- SharedPtr<AsyncOperation>* operation =
290
+ SharedPtr<AsyncOperation> operation =
269
291
instance_id_internal_->AddOperation (new AsyncTokenOperation (
270
292
env, instance_id_internal_,
271
293
instance_id_internal_
@@ -276,15 +298,22 @@ Future<void> InstanceId::DeleteToken(const char* entity, const char* scope) {
276
298
util::RunOnBackgroundThread (
277
299
env,
278
300
[](void * function_data) {
279
- SharedPtr<AsyncOperation> base_operation =
280
- *(static_cast <SharedPtr<AsyncOperation>*>(function_data));
281
- AsyncTokenOperation* operation =
282
- static_cast <AsyncTokenOperation*>(base_operation->derived ());
301
+ // Assume that when this callback is called, AsyncOperation should still
302
+ // be in instance_id_internal->operations_ or this callback should not
303
+ // be called at all due to the lock in CppThreadDispatcherContext.
304
+ AsyncTokenOperation* op_ptr =
305
+ static_cast <AsyncTokenOperation*>(function_data);
283
306
InstanceIdInternal* instance_id_internal =
284
- operation->instance_id_internal ();
307
+ op_ptr->instance_id_internal ();
308
+ // Hold a reference to AsyncOperation so that it will not be deleted
309
+ // during this callback.
310
+ SharedPtr<AsyncOperation> operation =
311
+ instance_id_internal->GetOperationSharedPtr (op_ptr);
312
+ if (!operation) return ;
313
+
285
314
JNIEnv* env = instance_id_internal->instance_id ()->app ().GetJNIEnv ();
286
- jobject entity_jstring = env->NewStringUTF (operation ->entity ().c_str ());
287
- jobject scope_jstring = env->NewStringUTF (operation ->scope ().c_str ());
315
+ jobject entity_jstring = env->NewStringUTF (op_ptr ->entity ().c_str ());
316
+ jobject scope_jstring = env->NewStringUTF (op_ptr ->scope ().c_str ());
288
317
jobject java_instance_id =
289
318
env->NewLocalRef (instance_id_internal->java_instance_id ());
290
319
jmethodID java_instance_id_method =
@@ -298,11 +327,10 @@ Future<void> InstanceId::DeleteToken(const char* entity, const char* scope) {
298
327
env->DeleteLocalRef (scope_jstring);
299
328
if (operation->AcquireExecuteCancelLock ()) {
300
329
instance_id_internal->CompleteOperation (
301
- base_operation, ExceptionStringToError (error.c_str ()),
302
- error.c_str ());
330
+ operation, ExceptionStringToError (error.c_str ()), error.c_str ());
303
331
}
304
332
},
305
- operation, InstanceIdInternal::Canceled, &(* *operation));
333
+ &(* operation) , InstanceIdInternal::Canceled, &(*operation));
306
334
return DeleteTokenLastResult ();
307
335
}
308
336
0 commit comments