From: Corey Tabaka Date: Sat, 29 Jul 2017 02:46:30 +0000 (-0700) Subject: Fix missing check on buffer import. X-Git-Tag: android-x86-8.1-r1~35^2^2~11^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=cf02372a00d4e04066e51747d6bd6636e4aae955;p=android-x86%2Fframeworks-native.git 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 --- 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 ConsumerQueue::ImportBuffers() { std::unique_ptr 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 ApplicationDisplaySurface::GetQueue( "ApplicationDisplaySurface::GetQueue: surface_id=%d queue_id=%d", surface_id(), queue_id); + std::lock_guard autolock(lock_); auto search = consumer_queues_.find(queue_id); if (search != consumer_queues_.end()) return search->second; @@ -202,6 +203,7 @@ std::shared_ptr ApplicationDisplaySurface::GetQueue( } std::vector ApplicationDisplaySurface::GetQueueIds() const { + std::lock_guard autolock(lock_); std::vector queue_ids; for (const auto& entry : consumer_queues_) queue_ids.push_back(entry.first); @@ -270,6 +272,7 @@ void ApplicationDisplaySurface::OnQueueEvent( } std::vector DirectDisplaySurface::GetQueueIds() const { + std::lock_guard autolock(lock_); std::vector 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& consumer_queue, int events) override; + // Accessed by both message dispatch thread and epoll event thread. std::unordered_map> consumer_queues_; };