summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/TimedEventQueue.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-04-12 13:10:20 -0700
committerAndreas Huber <andih@google.com>2010-04-12 13:15:48 -0700
commit874b55f51c4c062c65aee043ec0f26044b504556 (patch)
tree86d4c6cd8ec51091ae4998e326dd20392e983163 /media/libstagefright/TimedEventQueue.cpp
parentb547d09ecc3da8ee300099da8ca7e2826bb6849a (diff)
downloadframeworks_av-874b55f51c4c062c65aee043ec0f26044b504556.zip
frameworks_av-874b55f51c4c062c65aee043ec0f26044b504556.tar.gz
frameworks_av-874b55f51c4c062c65aee043ec0f26044b504556.tar.bz2
Fix a race condition in TimedEventQueue, an event may be cancelled while we're waiting for its scheduled time to come in which case we'd be removing it from the queue twice.
Change-Id: I4e42e318fd5373d1f352f54027d4bf823126266d related-to-bug: 2585276
Diffstat (limited to 'media/libstagefright/TimedEventQueue.cpp')
-rw-r--r--media/libstagefright/TimedEventQueue.cpp43
1 files changed, 34 insertions, 9 deletions
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index e62d501..3de8c1d 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -19,6 +19,7 @@
#define __STDC_LIMIT_MACROS
#include <stdint.h>
+//#define LOG_NDEBUG 0
#define LOG_TAG "TimedEventQueue"
#include <utils/Log.h>
@@ -169,6 +170,8 @@ void TimedEventQueue::cancelEvents(
mQueueHeadChangedCondition.signal();
}
+ LOGV("cancelling event %d", (*it).event->eventID());
+
(*it).event->setEventID(0);
it = mQueue.erase(it);
@@ -229,14 +232,16 @@ void TimedEventQueue::threadEntry() {
mQueueNotEmptyCondition.wait(mLock);
}
- List<QueueItem>::iterator it;
+ event_id eventID = 0;
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();
+
+ List<QueueItem>::iterator it = mQueue.begin();
+ eventID = (*it).event->eventID();
now_us = getRealTimeUs();
int64_t when_us = (*it).realtime_us;
@@ -276,18 +281,38 @@ void TimedEventQueue::threadEntry() {
}
}
- if (mQueue.empty()) {
- continue;
- }
+ // The event w/ this id may have been cancelled while we're
+ // waiting for its trigger-time, in that case
+ // removeEventFromQueue_l will return NULL.
+ // Otherwise, the QueueItem will be removed
+ // from the queue and the referenced event returned.
+ event = removeEventFromQueue_l(eventID);
+ }
+
+ if (event != NULL) {
+ // Fire event with the lock NOT held.
+ event->fire(this, now_us);
+ }
+ }
+}
- event = (*it).event;
+sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l(
+ event_id id) {
+ for (List<QueueItem>::iterator it = mQueue.begin();
+ it != mQueue.end(); ++it) {
+ if ((*it).event->eventID() == id) {
+ sp<Event> event = (*it).event;
event->setEventID(0);
+
mQueue.erase(it);
- }
- // Fire event with the lock NOT held.
- event->fire(this, now_us);
+ return event;
+ }
}
+
+ LOGW("Event %d was not found in the queue, already cancelled?", id);
+
+ return NULL;
}
} // namespace android