summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Tabaka <eieio@google.com>2017-07-28 19:46:30 -0700
committerCorey Tabaka <eieio@google.com>2017-07-28 19:46:30 -0700
commitcf02372a00d4e04066e51747d6bd6636e4aae955 (patch)
treebcf18e6e08bf2517b58c9ccef4ec89ae74d3a10b
parent42d6d5c8051c2f72ea258553eaa40062c1ec15c7 (diff)
downloadnative-cf02372a00d4e04066e51747d6bd6636e4aae955.tar.gz
Fix missing check on buffer import.
Fix a missing check on the success of importing buffers into the ConsumerQueue. There is a race condition where the producer can invalidate its buffers, for example by resizing, before the consumer has a chance to import the previous buffers. The missing check causes a crash in SurfaceFlinger and VrCore, which are both consumers of application VR surface buffers. Also fix a missing lock around the consumer queues in VR surfaces found during the analysis of this bug. Bug: 64042620 Test: Ran test.apk before and after the fix. Observe stable operation after applying the fix. Change-Id: I416df3ca47978404dcdb53599ddeec9b4bd6fb1a
-rw-r--r--libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp6
-rw-r--r--libs/vr/libvrflinger/display_surface.cpp3
-rw-r--r--libs/vr/libvrflinger/display_surface.h1
3 files changed, 10 insertions, 0 deletions
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index 38603905aa..bfb9a55e93 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -613,6 +613,12 @@ Status<size_t> ConsumerQueue::ImportBuffers() {
std::unique_ptr<BufferConsumer> buffer_consumer =
BufferConsumer::Import(std::move(buffer_handle_slot.first));
+ if (!buffer_consumer) {
+ ALOGE("ConsumerQueue::ImportBuffers: Failed to import buffer: slot=%zu",
+ buffer_handle_slot.second);
+ last_error = ErrorStatus(EPIPE);
+ continue;
+ }
// Setup ignore state before adding buffer to the queue.
if (ignore_on_import_) {
diff --git a/libs/vr/libvrflinger/display_surface.cpp b/libs/vr/libvrflinger/display_surface.cpp
index 04e3d5f3c5..0d6a732a8e 100644
--- a/libs/vr/libvrflinger/display_surface.cpp
+++ b/libs/vr/libvrflinger/display_surface.cpp
@@ -194,6 +194,7 @@ std::shared_ptr<ConsumerQueue> ApplicationDisplaySurface::GetQueue(
"ApplicationDisplaySurface::GetQueue: surface_id=%d queue_id=%d",
surface_id(), queue_id);
+ std::lock_guard<std::mutex> autolock(lock_);
auto search = consumer_queues_.find(queue_id);
if (search != consumer_queues_.end())
return search->second;
@@ -202,6 +203,7 @@ std::shared_ptr<ConsumerQueue> ApplicationDisplaySurface::GetQueue(
}
std::vector<int32_t> ApplicationDisplaySurface::GetQueueIds() const {
+ std::lock_guard<std::mutex> autolock(lock_);
std::vector<int32_t> queue_ids;
for (const auto& entry : consumer_queues_)
queue_ids.push_back(entry.first);
@@ -270,6 +272,7 @@ void ApplicationDisplaySurface::OnQueueEvent(
}
std::vector<int32_t> DirectDisplaySurface::GetQueueIds() const {
+ std::lock_guard<std::mutex> autolock(lock_);
std::vector<int32_t> queue_ids;
if (direct_queue_)
queue_ids.push_back(direct_queue_->id());
diff --git a/libs/vr/libvrflinger/display_surface.h b/libs/vr/libvrflinger/display_surface.h
index 556183a4e9..5cbee57bf9 100644
--- a/libs/vr/libvrflinger/display_surface.h
+++ b/libs/vr/libvrflinger/display_surface.h
@@ -133,6 +133,7 @@ class ApplicationDisplaySurface : public DisplaySurface {
void OnQueueEvent(const std::shared_ptr<ConsumerQueue>& consumer_queue,
int events) override;
+ // Accessed by both message dispatch thread and epoll event thread.
std::unordered_map<int32_t, std::shared_ptr<ConsumerQueue>> consumer_queues_;
};