SurfaceFlinger: fix layer removal race condition

Layer::lockPageFlip() and layer::onRemove() could be called on
different threads and race such that lockPageFlip() successfully
called mSurfaceTexture->updateTexImage() but then gets NULL back from
mSurfaceTexture->getCurrentBuffer(), leading to a crash.

This change moves Layer::onRemove() calls to
SurfaceFlinger::commitTransaction() so they happen after the Layer is
done being drawn from and only happen on the main surfaceflinger
thread.

Change-Id: I4b550caadff4cc1878d7c3bca6129193fb0c713e
This commit is contained in:
Jesse Hall 2011-12-02 10:00:00 -08:00
parent afdc18bb0c
commit 2f4b68d21c
2 changed files with 10 additions and 1 deletions

View File

@ -710,6 +710,14 @@ void SurfaceFlinger::computeVisibleRegions(
void SurfaceFlinger::commitTransaction()
{
if (!mLayersPendingRemoval.isEmpty()) {
// Notify removed layers now that they can't be drawn from
for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
mLayersPendingRemoval[i]->onRemoved();
}
mLayersPendingRemoval.clear();
}
mDrawingState = mCurrentState;
mTransationPending = false;
mTransactionCV.broadcast();
@ -1162,7 +1170,7 @@ status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
mLayerPurgatory.add(layerBase);
}
layerBase->onRemoved();
mLayersPendingRemoval.push(layerBase);
// it's possible that we don't find a layer, because it might
// have been destroyed already -- this is not technically an error

View File

@ -345,6 +345,7 @@ private:
Condition mTransactionCV;
SortedVector< sp<LayerBase> > mLayerPurgatory;
bool mTransationPending;
Vector< sp<LayerBase> > mLayersPendingRemoval;
// protected by mStateLock (but we could use another lock)
GraphicPlane mGraphicPlanes[1];