summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/TimedEventQueue.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-03-29 11:52:08 -0700
committerAndreas Huber <andih@google.com>2010-03-29 12:01:25 -0700
commit03f4e14ec612d53b5e2b987555b24afcbbe319d1 (patch)
tree4d488945c8b209576af68e8375552939c455c38e /media/libstagefright/TimedEventQueue.cpp
parentf8ed70a20f8b006539af98c8ad45be9561665f82 (diff)
downloadframeworks_av-03f4e14ec612d53b5e2b987555b24afcbbe319d1.zip
frameworks_av-03f4e14ec612d53b5e2b987555b24afcbbe319d1.tar.gz
frameworks_av-03f4e14ec612d53b5e2b987555b24afcbbe319d1.tar.bz2
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.
Change-Id: I50e8976ce8d0ecc47ee0eb497296930877ce306a related-to-bug: 2549465
Diffstat (limited to 'media/libstagefright/TimedEventQueue.cpp')
-rw-r--r--media/libstagefright/TimedEventQueue.cpp31
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;
}