am 1e64e52c: 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

Merge commit '1e64e52c8f25ab08605ee445d91bb745f1f3f2d7' into froyo-plus-aosp

* commit '1e64e52c8f25ab08605ee445d91bb745f1f3f2d7':
  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.
This commit is contained in:
Andreas Huber
2010-03-29 13:01:27 -07:00
committed by Android Git Automerger

View File

@@ -24,6 +24,7 @@
#include "include/TimedEventQueue.h" #include "include/TimedEventQueue.h"
#include <sys/prctl.h>
#include <sys/time.h> #include <sys/time.h>
#include <media/stagefright/MediaDebug.h> #include <media/stagefright/MediaDebug.h>
@@ -182,7 +183,7 @@ int64_t TimedEventQueue::getRealTimeUs() {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; return (int64_t)tv.tv_sec * 1000000ll + tv.tv_usec;
} }
// static // static
@@ -211,8 +212,10 @@ void *TimedEventQueue::ThreadWrapper(void *me) {
} }
void TimedEventQueue::threadEntry() { void TimedEventQueue::threadEntry() {
prctl(PR_SET_NAME, (unsigned long)"TimedEventQueue", 0, 0, 0);
for (;;) { for (;;) {
int64_t now_us; int64_t now_us = 0;
sp<Event> event; sp<Event> event;
{ {
@@ -228,6 +231,11 @@ void TimedEventQueue::threadEntry() {
List<QueueItem>::iterator it; List<QueueItem>::iterator it;
for (;;) { 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(); it = mQueue.begin();
now_us = getRealTimeUs(); now_us = getRealTimeUs();
@@ -244,10 +252,25 @@ void TimedEventQueue::threadEntry() {
break; break;
} }
status_t err = mQueueHeadChangedCondition.waitRelative( static int64_t kMaxTimeoutUs = 10000000ll; // 10 secs
mLock, delay_us * 1000); bool timeoutCapped = false;
if (delay_us > kMaxTimeoutUs) {
LOGW("delay_us exceeds max timeout: %lld us", delay_us);
if (err == -ETIMEDOUT) { // 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 * 1000ll);
if (!timeoutCapped && err == -ETIMEDOUT) {
// We finally hit the time this event is supposed to
// trigger.
now_us = getRealTimeUs(); now_us = getRealTimeUs();
break; break;
} }