Avoid promoting weak reference of Layer on Binder thread.
BufferQueueLayer registers itself to ConsumerBase so it can receive callbacks about incoming frames. When doing this, ConsumerBase holds a weak reference to BufferQueueLayer. This would normally be fine except ConsumerBase promotes the weak pointer on a Binder thread. This leads to a race where the layer is ready to get destroyed in SurfaceFlinger, but ConsumerBase promotes the layer. The layer will get destroyed after the function finishes, but now it gets destroyed off the main thread. When this happens, a lot of unexpected behavior occurs since the layer destructor expects the call to only happen on the main thread and therefore, doesn't hold any locks. Instead of giving ConsumerBase a weak reference to the layer, we can give it a reference to a listener. This listener can be managed by BufferQueueLayer and will only hold a raw reference to the Layer. ConsumerBase can promote the listener, but it will not be holding a strong reference to the Layer, allowing the layer to get destroyed on the main thread. We hold a lock when accessing the raw reference to ensure it's not being destroyed. The raw reference is nulled when the layer is getting destroyed to ensure no more calls are made to the layer after it's destroyed. Fixes: 143735125 Fixes: 143200062 Test: go/wm-smoke Change-Id: I47122b0e4c6d73f23a64027fd3622b2d7fd28871
Loading
Please register or sign in to comment