summaryrefslogtreecommitdiff
path: root/libs/gui/ConsumerBase.cpp
diff options
context:
space:
mode:
author Pablo Ceballos <pceballos@google.com> 2016-02-19 17:41:54 -0800
committer Pablo Ceballos <pceballos@google.com> 2016-02-19 17:45:51 -0800
commit22b5702b40eca423171124e69c3d4ad03a3e6900 (patch)
tree11242f3e9a067749b6e82faa7285e31ff032fcf4 /libs/gui/ConsumerBase.cpp
parent8164ce1d59f505f7e6eb5bce66864879b021f2b6 (diff)
Add a callback thread to ConsumerBase
- Add a message queue and callback thread in ConsumerBase. - This is used to prevent deadlocks when ConsumerBase calls into BufferQueueConsumer and that generates a callback. Bug 27229287 Change-Id: I45c41e5a554555511fcfa5c185a7d60b0d969b7e
Diffstat (limited to 'libs/gui/ConsumerBase.cpp')
-rw-r--r--libs/gui/ConsumerBase.cpp78
1 files changed, 77 insertions, 1 deletions
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index d01187fbbf..a22b81bd95 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -74,12 +74,26 @@ ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool c
} else {
mConsumer->setConsumerName(mName);
}
+
+ mMessageThread = new MessageThread(this);
+ mMessageThread->run();
}
ConsumerBase::~ConsumerBase() {
CB_LOGV("~ConsumerBase");
- Mutex::Autolock lock(mMutex);
+ mMessageThread->requestExit();
+ {
+ Mutex::Autolock lock(mMessageQueueLock);
+ mMessageQueue.emplace(std::piecewise_construct,
+ std::forward_as_tuple(EXIT),
+ std::forward_as_tuple());
+ mMessageAvailable.signal();
+ }
+
+ mMessageThread->join();
+
+ Mutex::Autolock lock(mMutex);
// Verify that abandon() has been called before we get here. This should
// be done by ConsumerBase::onLastStrongRef(), but it's possible for a
// derived class to override that method and not call
@@ -100,6 +114,13 @@ void ConsumerBase::freeBufferLocked(int slotIndex) {
}
void ConsumerBase::onFrameAvailable(const BufferItem& item) {
+ Mutex::Autolock lock(mMessageQueueLock);
+ mMessageQueue.emplace(std::piecewise_construct,
+ std::forward_as_tuple(ON_FRAME_AVAILABLE),
+ std::forward_as_tuple(item));
+ mMessageAvailable.signal();
+}
+void ConsumerBase::onFrameAvailableHandler(const BufferItem& item) {
CB_LOGV("onFrameAvailable");
sp<FrameAvailableListener> listener;
@@ -115,6 +136,14 @@ void ConsumerBase::onFrameAvailable(const BufferItem& item) {
}
void ConsumerBase::onFrameReplaced(const BufferItem &item) {
+ Mutex::Autolock lock(mMessageQueueLock);
+ mMessageQueue.emplace(std::piecewise_construct,
+ std::forward_as_tuple(ON_FRAME_REPLACED),
+ std::forward_as_tuple(item));
+ mMessageAvailable.signal();
+}
+
+void ConsumerBase::onFrameReplacedHandler(const BufferItem &item) {
CB_LOGV("onFrameReplaced");
sp<FrameAvailableListener> listener;
@@ -130,6 +159,14 @@ void ConsumerBase::onFrameReplaced(const BufferItem &item) {
}
void ConsumerBase::onBuffersReleased() {
+ Mutex::Autolock lock(mMessageQueueLock);
+ mMessageQueue.emplace(std::piecewise_construct,
+ std::forward_as_tuple(ON_BUFFERS_RELEASED),
+ std::forward_as_tuple());
+ mMessageAvailable.signal();
+}
+
+void ConsumerBase::onBuffersReleasedHandler() {
Mutex::Autolock lock(mMutex);
CB_LOGV("onBuffersReleased");
@@ -149,6 +186,45 @@ void ConsumerBase::onBuffersReleased() {
}
void ConsumerBase::onSidebandStreamChanged() {
+ Mutex::Autolock lock(mMessageQueueLock);
+ mMessageQueue.emplace(std::piecewise_construct,
+ std::forward_as_tuple(ON_SIDEBAND_STREAM_CHANGED),
+ std::forward_as_tuple());
+ mMessageAvailable.signal();
+}
+
+void ConsumerBase::onSidebandStreamChangedHandler() {
+}
+
+bool ConsumerBase::MessageThread::threadLoop() {
+ Mutex::Autolock lock(mConsumerBase->mMessageQueueLock);
+
+ if (mConsumerBase->mMessageQueue.empty()) {
+ mConsumerBase->mMessageAvailable.wait(mConsumerBase->mMessageQueueLock);
+ }
+
+ while (!mConsumerBase->mMessageQueue.empty()) {
+ auto nextMessage = mConsumerBase->mMessageQueue.front();
+
+ switch (nextMessage.first) {
+ case ON_FRAME_AVAILABLE:
+ mConsumerBase->onFrameAvailableHandler(nextMessage.second);
+ break;
+ case ON_FRAME_REPLACED:
+ mConsumerBase->onFrameReplacedHandler(nextMessage.second);
+ break;
+ case ON_BUFFERS_RELEASED:
+ mConsumerBase->onBuffersReleasedHandler();
+ break;
+ case ON_SIDEBAND_STREAM_CHANGED:
+ mConsumerBase->onSidebandStreamChangedHandler();
+ break;
+ case EXIT:
+ break;
+ }
+ mConsumerBase->mMessageQueue.pop();
+ }
+ return true;
}
void ConsumerBase::abandon() {