Merge "Fix a race-condtion in SurfaceFlinger that could lead to a crash."

This commit is contained in:
Mathias Agopian 2011-05-03 16:34:06 -07:00 committed by Android (Google) Code Review
commit e4b117ad45
2 changed files with 21 additions and 11 deletions

View File

@ -1094,15 +1094,15 @@ status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
const sp<LayerBaseClient>& lbc) const sp<LayerBaseClient>& lbc)
{ {
Mutex::Autolock _l(mStateLock);
// attach this layer to the client // attach this layer to the client
ssize_t name = client->attachLayer(lbc); size_t name = client->attachLayer(lbc);
Mutex::Autolock _l(mStateLock);
// add this layer to the current state list // add this layer to the current state list
addLayer_l(lbc); addLayer_l(lbc);
return name; return ssize_t(name);
} }
status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
@ -2381,15 +2381,17 @@ status_t Client::initCheck() const {
return NO_ERROR; return NO_ERROR;
} }
ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer) size_t Client::attachLayer(const sp<LayerBaseClient>& layer)
{ {
int32_t name = android_atomic_inc(&mNameGenerator); Mutex::Autolock _l(mLock);
size_t name = mNameGenerator++;
mLayers.add(name, layer); mLayers.add(name, layer);
return name; return name;
} }
void Client::detachLayer(const LayerBaseClient* layer) void Client::detachLayer(const LayerBaseClient* layer)
{ {
Mutex::Autolock _l(mLock);
// we do a linear search here, because this doesn't happen often // we do a linear search here, because this doesn't happen often
const size_t count = mLayers.size(); const size_t count = mLayers.size();
for (size_t i=0 ; i<count ; i++) { for (size_t i=0 ; i<count ; i++) {
@ -2399,9 +2401,11 @@ void Client::detachLayer(const LayerBaseClient* layer)
} }
} }
} }
sp<LayerBaseClient> Client::getLayerUser(int32_t i) const { sp<LayerBaseClient> Client::getLayerUser(int32_t i) const
{
Mutex::Autolock _l(mLock);
sp<LayerBaseClient> lbc; sp<LayerBaseClient> lbc;
const wp<LayerBaseClient>& layer(mLayers.valueFor(i)); wp<LayerBaseClient> layer(mLayers.valueFor(i));
if (layer != 0) { if (layer != 0) {
lbc = layer.promote(); lbc = layer.promote();
LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));

View File

@ -65,7 +65,7 @@ public:
status_t initCheck() const; status_t initCheck() const;
// protected by SurfaceFlinger::mStateLock // protected by SurfaceFlinger::mStateLock
ssize_t attachLayer(const sp<LayerBaseClient>& layer); size_t attachLayer(const sp<LayerBaseClient>& layer);
void detachLayer(const LayerBaseClient* layer); void detachLayer(const LayerBaseClient* layer);
sp<LayerBaseClient> getLayerUser(int32_t i) const; sp<LayerBaseClient> getLayerUser(int32_t i) const;
@ -81,9 +81,15 @@ private:
virtual status_t destroySurface(SurfaceID surfaceId); virtual status_t destroySurface(SurfaceID surfaceId);
virtual status_t setState(int32_t count, const layer_state_t* states); virtual status_t setState(int32_t count, const layer_state_t* states);
DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers; // constant
sp<SurfaceFlinger> mFlinger; sp<SurfaceFlinger> mFlinger;
int32_t mNameGenerator;
// protected by mLock
DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers;
size_t mNameGenerator;
// thread-safe
mutable Mutex mLock;
}; };
class UserClient : public BnSurfaceComposerClient class UserClient : public BnSurfaceComposerClient