stagefright: fix TimedEventQueue wakelock
If an event is taking a wakelock, the wakelock must be
released after the event is fired.
If the wakelock is released before and the event execution
implies some sleeps or I/O the system can go idle as
no wakelock is held anymore.
Bug: 11976087.
Change-Id: Ie7df8ed4834952ff818ff27d6be415c0b1794a9f
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index 1a9a26b..da23fea 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -127,7 +127,6 @@
QueueItem item;
item.event = event;
item.realtime_us = realtime_us;
- item.has_wakelock = false;
if (it == mQueue.begin()) {
mQueueHeadChangedCondition.signal();
@@ -135,7 +134,7 @@
if (realtime_us > ALooper::GetNowUs() + kWakelockMinDelay) {
acquireWakeLock_l();
- item.has_wakelock = true;
+ event->setWakeLock();
}
mQueue.insert(it, item);
@@ -191,7 +190,7 @@
ALOGV("cancelling event %d", (*it).event->eventID());
(*it).event->setEventID(0);
- if ((*it).has_wakelock) {
+ if ((*it).event->hasWakeLock()) {
releaseWakeLock_l();
}
it = mQueue.erase(it);
@@ -289,6 +288,9 @@
if (event != NULL) {
// Fire event with the lock NOT held.
event->fire(this, now_us);
+ if (event->hasWakeLock()) {
+ releaseWakeLock_l();
+ }
}
}
}
@@ -300,9 +302,6 @@
if ((*it).event->eventID() == id) {
sp<Event> event = (*it).event;
event->setEventID(0);
- if ((*it).has_wakelock) {
- releaseWakeLock_l();
- }
mQueue.erase(it);
return event;
}
diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h
index 38a08b1..4e8912d 100644
--- a/media/libstagefright/include/TimedEventQueue.h
+++ b/media/libstagefright/include/TimedEventQueue.h
@@ -33,7 +33,7 @@
struct Event : public RefBase {
Event()
- : mEventID(0) {
+ : mEventID(0), mHasWakeLock(false) {
}
virtual ~Event() {}
@@ -42,6 +42,14 @@
return mEventID;
}
+ void setWakeLock() {
+ mHasWakeLock = true;
+ }
+
+ bool hasWakeLock() {
+ return mHasWakeLock;
+ }
+
protected:
virtual void fire(TimedEventQueue *queue, int64_t now_us) = 0;
@@ -49,6 +57,7 @@
friend class TimedEventQueue;
event_id mEventID;
+ bool mHasWakeLock;
void setEventID(event_id id) {
mEventID = id;
@@ -118,7 +127,6 @@
struct QueueItem {
sp<Event> event;
int64_t realtime_us;
- bool has_wakelock;
};
struct StopEvent : public TimedEventQueue::Event {