From 869c9f9d4f660bc1fd21441a070d0df80edd7b1d Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Sat, 9 Jul 2022 01:06:13 -0400 Subject: [PATCH 1/4] semaphore.h: handle spurious wakeups in TimedWait() on Linux --- app/src/semaphore.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/app/src/semaphore.h b/app/src/semaphore.h index 23a77305e9..7903091932 100644 --- a/app/src/semaphore.h +++ b/app/src/semaphore.h @@ -172,7 +172,33 @@ class Semaphore { return WaitForSingleObject(semaphore_, milliseconds) == 0; #else // not windows and not mac - should be Linux. timespec t = internal::MsToAbsoluteTimespec(milliseconds); - return sem_timedwait(semaphore_, &t) == 0; + while (true) { + int result = sem_timedwait(semaphore_, &t); + if (result == 0) { + // Return success, since we successfully locked the semaphore. + return true; + } + switch (errno) { + case EINTR: + // Restart the wait because we were woken up spuriously. + continue; + case ETIMEDOUT: + // Return failure, since the timeout expired. + return false; + case EINVAL: + assert("sem_timedwait() failed with EINVAL" == 0); + case EDEADLK: + assert("sem_timedwait() failed with EDEADLK" == 0); + default: + assert("sem_timedwait() failed with an unknown error" == 0); + } + } else if (errno == EINTR) { + continue; + } else { + assert(errno == ETIMEDOUT); + return false; + } + } #endif } From 59884b222ce9a6c6cfe11247c1ca7ff54d5952ac Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Sat, 9 Jul 2022 01:14:13 -0400 Subject: [PATCH 2/4] semaphore.h: fix typo --- app/src/semaphore.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/src/semaphore.h b/app/src/semaphore.h index 7903091932..e1606d9103 100644 --- a/app/src/semaphore.h +++ b/app/src/semaphore.h @@ -192,12 +192,6 @@ class Semaphore { default: assert("sem_timedwait() failed with an unknown error" == 0); } - } else if (errno == EINTR) { - continue; - } else { - assert(errno == ETIMEDOUT); - return false; - } } #endif } From 37c9f6ed05d780a263a3606e4c9af6567fe71d61 Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Mon, 11 Jul 2022 08:05:38 -0400 Subject: [PATCH 3/4] semaphore.h: return false after assert in case assertions are disabled --- app/src/semaphore.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/semaphore.h b/app/src/semaphore.h index e1606d9103..316373d8a0 100644 --- a/app/src/semaphore.h +++ b/app/src/semaphore.h @@ -187,10 +187,13 @@ class Semaphore { return false; case EINVAL: assert("sem_timedwait() failed with EINVAL" == 0); + return false; case EDEADLK: assert("sem_timedwait() failed with EDEADLK" == 0); + return false; default: assert("sem_timedwait() failed with an unknown error" == 0); + return false; } } #endif From bc697b5d6cde89f57833e79c638cee322b5624bc Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Mon, 11 Jul 2022 08:31:15 -0400 Subject: [PATCH 4/4] Add release notes entry --- release_build_files/readme.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/release_build_files/readme.md b/release_build_files/readme.md index a746e46a2f..380f543d1d 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -634,6 +634,13 @@ workflow use only during the development of your app, not for publicly shipping code. ## Release Notes +### Upcoming Changes +- Changes + - General (Android,Linux): Fixed a concurrency bug where waiting for an + event with a timeout could occasionally return prematurely, as if the + timeout had occurred + ([#1021](https://github.com/firebase/firebase-cpp-sdk/pull/1021)). + ### 9.2.0 - Changes - GMA: Added the Google Mobile Ads SDK with updated support for AdMob. See