firebase / firebase/firebase-cpp-sdk
[Bug] Deadlock in firebase::auth::IdTokenRefreshThread
- Dominant language
- C++
- Stars
- 326
- Forks
- 137
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 5
Description
### [REQUIRED] Please fill in the following fields:
* Pre-built SDK from the [website](https://firebase.google.com/download/cpp) or open-source from this repo: open-source from this repo
* Firebase C++ SDK version: 11.4.0
* Problematic Firebase Component: auth
* Other Firebase Components in use: database
* Platform you are using the C++ SDK on: Mac, Windows
* Platform you are targeting: desktop
### [REQUIRED] Please describe the issue here:
Deadlock in IdTokenRefreshThread which causes the entire app to hang, e.g., Database cannot be safely deleted since it is deadlocked on destruction by waiting IdTokenRefreshThread to finish
1. IdTokenRefreshThread holds `refresh_thread->ref_count_mutex_` and `auth->auth_data_->future_impl.mutex()`. Then it accesses `refresh_thread->token_refresh_listener_.GetTokenTimestamp()` which has its own mutex
```
#0 firebase::auth::IdTokenRefreshThread::Initialize(firebase::auth::AuthData*)::$_4::operator()(firebase::auth::IdTokenRefreshThread*) const at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/auth_desktop.cc:818
#1 firebase::auth::IdTokenRefreshThread::Initialize(firebase::auth::AuthData*)::$_4::__invoke(firebase::auth::IdTokenRefreshThread*) at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/auth_desktop.cc:805
```
2. Another worker thread fires an event about token change. `IdTokenRefreshListener::OnIdTokenChanged` locks its own mutex first and then `auth->auth_data_->future_impl.mutex()`
```
#0 firebase::auth::IdTokenRefreshListener::OnIdTokenChanged(firebase::auth::Auth*) at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/auth_desktop.cc:135
#1 firebase::auth::NotifyIdTokenListeners(firebase::auth::AuthData*) at /Users/venhe/tmp/Firebase/Firebase/auth/src/auth.cc:362
#2 0firebase::auth::AuthenticationResult::SetAsCurrentUser(firebase::auth::AuthData*) const at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/authentication_result.cc:64
#3 void firebase::auth::PerformSignInFlow(firebase::auth::AuthDataHandle*) at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/sign_in_flow.h:125
```
Deadlock happens if IdTokenRefreshThread just about to call `GetTokenTimestamp` and if IdTokenRefreshListener::OnIdTokenChanged successfully acquired its mutex.
#### Steps to reproduce:
Hard to reproduce, but happens quite often.
What happened? How can we make the problem occur?
Simulate it, e.g., call IdTokenRefreshListener::OnIdTokenChanged in a loop, and it will definitely deadlock at some point
If you have a downloadable sample project that reproduces the bug you're reporting, you will
likely receive a faster response on your issue.
Contributor guide
Assessment
This issue has not been assessed yet.