Skip to content

Commit 26e918b

Browse files
authored
semaphore.h: handle spurious wakeups in TimedWait() on Linux (#1021)
1 parent c722ca7 commit 26e918b

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

app/src/semaphore.h

+24-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,30 @@ class Semaphore {
172172
returnWaitForSingleObject(semaphore_, milliseconds) == 0;
173173
#else// not windows and not mac - should be Linux.
174174
timespec t = internal::MsToAbsoluteTimespec(milliseconds);
175-
returnsem_timedwait(semaphore_, &t) == 0;
175+
while (true) {
176+
int result = sem_timedwait(semaphore_, &t);
177+
if (result == 0) {
178+
// Return success, since we successfully locked the semaphore.
179+
returntrue;
180+
}
181+
switch (errno) {
182+
case EINTR:
183+
// Restart the wait because we were woken up spuriously.
184+
continue;
185+
case ETIMEDOUT:
186+
// Return failure, since the timeout expired.
187+
returnfalse;
188+
case EINVAL:
189+
assert("sem_timedwait() failed with EINVAL" == 0);
190+
returnfalse;
191+
case EDEADLK:
192+
assert("sem_timedwait() failed with EDEADLK" == 0);
193+
returnfalse;
194+
default:
195+
assert("sem_timedwait() failed with an unknown error" == 0);
196+
returnfalse;
197+
}
198+
}
176199
#endif
177200
}
178201

release_build_files/readme.md

+7
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,13 @@ workflow use only during the development of your app, not for publicly shipping
634634
code.
635635

636636
## Release Notes
637+
### Upcoming Changes
638+
- Changes
639+
- General (Android,Linux): Fixed a concurrency bug where waiting for an
640+
event with a timeout could occasionally return prematurely, as if the
641+
timeout had occurred
642+
([#1021](https://github.com/firebase/firebase-cpp-sdk/pull/1021)).
643+
637644
### 9.2.0
638645
- Changes
639646
- GMA: Added the Google Mobile Ads SDK with updated support for AdMob. See

0 commit comments

Comments
 (0)
close