summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/TimedEventQueue.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2009-11-17 10:25:01 -0800
committerAndreas Huber <andih@google.com>2009-11-17 10:29:32 -0800
commitbe11f392a8b8ff1006cf536350cc8a85f8788ff4 (patch)
treeb01deb5339fb3b15db63fa6d021cce441dfe1be1 /media/libstagefright/TimedEventQueue.cpp
parent057eacf4578ac6b90ee18c524670e01445bf2732 (diff)
downloadframeworks_av-be11f392a8b8ff1006cf536350cc8a85f8788ff4.zip
frameworks_av-be11f392a8b8ff1006cf536350cc8a85f8788ff4.tar.gz
frameworks_av-be11f392a8b8ff1006cf536350cc8a85f8788ff4.tar.bz2
Improvements to TimedEventQueue.
Events are now cancelled given their "unique" event_id instead of the event pointer itself (which may be reallocated in place if we're unlucky). Also the ability to cancel multiple events matching a predicate has been added.
Diffstat (limited to 'media/libstagefright/TimedEventQueue.cpp')
-rw-r--r--media/libstagefright/TimedEventQueue.cpp77
1 files changed, 56 insertions, 21 deletions
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index dd8005c..fa68771 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -31,7 +31,8 @@
namespace android {
TimedEventQueue::TimedEventQueue()
- : mRunning(false),
+ : mNextEventID(1),
+ mRunning(false),
mStopped(false) {
}
@@ -76,26 +77,29 @@ void TimedEventQueue::stop(bool flush) {
mRunning = false;
}
-void TimedEventQueue::postEvent(const sp<Event> &event) {
+TimedEventQueue::event_id TimedEventQueue::postEvent(const sp<Event> &event) {
// Reserve an earlier timeslot an INT64_MIN to be able to post
// the StopEvent to the absolute head of the queue.
- postTimedEvent(event, INT64_MIN + 1);
+ return postTimedEvent(event, INT64_MIN + 1);
}
-void TimedEventQueue::postEventToBack(const sp<Event> &event) {
- postTimedEvent(event, INT64_MAX);
+TimedEventQueue::event_id TimedEventQueue::postEventToBack(
+ const sp<Event> &event) {
+ return postTimedEvent(event, INT64_MAX);
}
-void TimedEventQueue::postEventWithDelay(
+TimedEventQueue::event_id TimedEventQueue::postEventWithDelay(
const sp<Event> &event, int64_t delay_us) {
CHECK(delay_us >= 0);
- postTimedEvent(event, getRealTimeUs() + delay_us);
+ return postTimedEvent(event, getRealTimeUs() + delay_us);
}
-void TimedEventQueue::postTimedEvent(
+TimedEventQueue::event_id TimedEventQueue::postTimedEvent(
const sp<Event> &event, int64_t realtime_us) {
Mutex::Autolock autoLock(mLock);
+ event->setEventID(mNextEventID++);
+
List<QueueItem>::iterator it = mQueue.begin();
while (it != mQueue.end() && realtime_us >= (*it).realtime_us) {
++it;
@@ -112,29 +116,60 @@ void TimedEventQueue::postTimedEvent(
mQueue.insert(it, item);
mQueueNotEmptyCondition.signal();
-}
-bool TimedEventQueue::cancelEvent(const sp<Event> &event) {
- Mutex::Autolock autoLock(mLock);
+ return event->eventID();
+}
- List<QueueItem>::iterator it = mQueue.begin();
- while (it != mQueue.end() && (*it).event != event) {
- ++it;
- }
+static bool MatchesEventID(
+ void *cookie, const sp<TimedEventQueue::Event> &event) {
+ TimedEventQueue::event_id *id =
+ static_cast<TimedEventQueue::event_id *>(cookie);
- if (it == mQueue.end()) {
+ if (event->eventID() != *id) {
return false;
}
- if (it == mQueue.begin()) {
- mQueueHeadChangedCondition.signal();
- }
-
- mQueue.erase(it);
+ *id = 0;
return true;
}
+bool TimedEventQueue::cancelEvent(event_id id) {
+ CHECK(id != 0);
+
+ cancelEvents(&MatchesEventID, &id, true /* stopAfterFirstMatch */);
+
+ // if MatchesEventID found a match, it will have set id to 0
+ // (which is not a valid event_id).
+
+ return id == 0;
+}
+
+void TimedEventQueue::cancelEvents(
+ bool (*predicate)(void *cookie, const sp<Event> &event),
+ void *cookie,
+ bool stopAfterFirstMatch) {
+ Mutex::Autolock autoLock(mLock);
+
+ List<QueueItem>::iterator it = mQueue.begin();
+ while (it != mQueue.end()) {
+ if (!(*predicate)(cookie, (*it).event)) {
+ ++it;
+ continue;
+ }
+
+ if (it == mQueue.begin()) {
+ mQueueHeadChangedCondition.signal();
+ }
+
+ it = mQueue.erase(it);
+
+ if (stopAfterFirstMatch) {
+ return;
+ }
+ }
+}
+
// static
int64_t TimedEventQueue::getRealTimeUs() {
struct timeval tv;