diff options
author | Andreas Huber <andih@google.com> | 2010-03-29 12:58:03 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-03-29 12:58:03 -0700 |
commit | fb8391bfe3f21d08add3b65ba08d4d097c2bfdb6 (patch) | |
tree | ea5403cc0b3fa9cff61a302f87b10718db3341e5 | |
parent | 8cc76ae259ad81d5a40277bbf5532696ebae8da8 (diff) | |
parent | 03f4e14ec612d53b5e2b987555b24afcbbe319d1 (diff) | |
download | frameworks_av-fb8391bfe3f21d08add3b65ba08d4d097c2bfdb6.zip frameworks_av-fb8391bfe3f21d08add3b65ba08d4d097c2bfdb6.tar.gz frameworks_av-fb8391bfe3f21d08add3b65ba08d4d097c2bfdb6.tar.bz2 |
Merge "Fix a bug where the TimedEventQueue mistakenly accesses a bogus event if the only event in the queue has been cancelled while we're waiting for its scheduled time. Avoids potential int64_t overflow when converting from us to ns." into froyo
-rw-r--r-- | media/libstagefright/TimedEventQueue.cpp | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp index 6307bc5..e62d501 100644 --- a/media/libstagefright/TimedEventQueue.cpp +++ b/media/libstagefright/TimedEventQueue.cpp @@ -24,6 +24,7 @@ #include "include/TimedEventQueue.h" +#include <sys/prctl.h> #include <sys/time.h> #include <media/stagefright/MediaDebug.h> @@ -182,7 +183,7 @@ int64_t TimedEventQueue::getRealTimeUs() { struct timeval tv; gettimeofday(&tv, NULL); - return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; + return (int64_t)tv.tv_sec * 1000000ll + tv.tv_usec; } // static @@ -211,8 +212,10 @@ void *TimedEventQueue::ThreadWrapper(void *me) { } void TimedEventQueue::threadEntry() { + prctl(PR_SET_NAME, (unsigned long)"TimedEventQueue", 0, 0, 0); + for (;;) { - int64_t now_us; + int64_t now_us = 0; sp<Event> event; { @@ -228,6 +231,11 @@ void TimedEventQueue::threadEntry() { List<QueueItem>::iterator it; for (;;) { + if (mQueue.empty()) { + // The only event in the queue could have been cancelled + // while we were waiting for its scheduled time. + break; + } it = mQueue.begin(); now_us = getRealTimeUs(); @@ -244,10 +252,25 @@ void TimedEventQueue::threadEntry() { break; } + static int64_t kMaxTimeoutUs = 10000000ll; // 10 secs + bool timeoutCapped = false; + if (delay_us > kMaxTimeoutUs) { + LOGW("delay_us exceeds max timeout: %lld us", delay_us); + + // We'll never block for more than 10 secs, instead + // we will split up the full timeout into chunks of + // 10 secs at a time. This will also avoid overflow + // when converting from us to ns. + delay_us = kMaxTimeoutUs; + timeoutCapped = true; + } + status_t err = mQueueHeadChangedCondition.waitRelative( - mLock, delay_us * 1000); + mLock, delay_us * 1000ll); - if (err == -ETIMEDOUT) { + if (!timeoutCapped && err == -ETIMEDOUT) { + // We finally hit the time this event is supposed to + // trigger. now_us = getRealTimeUs(); break; } |