Merge "Track elapsed time for 'waitStreamEnd' timeout" am: 0523f70556 am: 5e991e116d am: 246e03a01b am: bfc252c825
Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1930618
Change-Id: I91564a9ca5ed6678a7671ed549017852f1061017
diff --git a/media/libaudioclient/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
index da27dc8..e3b79b2 100644
--- a/media/libaudioclient/AudioTrackShared.cpp
+++ b/media/libaudioclient/AudioTrackShared.cpp
@@ -490,6 +490,8 @@
status_t AudioTrackClientProxy::waitStreamEndDone(const struct timespec *requested)
{
struct timespec total; // total elapsed time spent waiting
+ struct timespec before;
+ bool beforeIsValid = false;
total.tv_sec = 0;
total.tv_nsec = 0;
audio_track_cblk_t* cblk = mCblk;
@@ -570,17 +572,38 @@
}
int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
if (!(old & CBLK_FUTEX_WAKE)) {
+ if (!beforeIsValid) {
+ clock_gettime(CLOCK_MONOTONIC, &before);
+ beforeIsValid = true;
+ }
errno = 0;
(void) syscall(__NR_futex, &cblk->mFutex,
mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
- switch (errno) {
+ status_t error = errno; // clock_gettime can affect errno
+ {
+ struct timespec after;
+ clock_gettime(CLOCK_MONOTONIC, &after);
+ total.tv_sec += after.tv_sec - before.tv_sec;
+ // Use auto instead of long to avoid the google-runtime-int warning.
+ auto deltaNs = after.tv_nsec - before.tv_nsec;
+ if (deltaNs < 0) {
+ deltaNs += 1000000000;
+ total.tv_sec--;
+ }
+ if ((total.tv_nsec += deltaNs) >= 1000000000) {
+ total.tv_nsec -= 1000000000;
+ total.tv_sec++;
+ }
+ before = after;
+ }
+ switch (error) {
case 0: // normal wakeup by server, or by binderDied()
case EWOULDBLOCK: // benign race condition with server
case EINTR: // wait was interrupted by signal or other spurious wakeup
case ETIMEDOUT: // time-out expired
break;
default:
- status = errno;
+ status = error;
ALOGE("%s unexpected error %s", __func__, strerror(status));
goto end;
}