Avoid crash when setting buffer on deleted layer
When setLayerBuffer() was called on a layer previously destroyed by destroyLayer() the code would crash. Instead, return an error. Bug: 37159844 Test: Ran vr flinger in a way that would trigger the crash, and confirmed that I now get error logs instead of crashing. Unfortunately the error code is consumed by the Composer wrapper class and not propagated back to the caller, but that's a separate issue (b/37901601). Change-Id: I75a5b954d47a1deac44d03851f60f347085eca89
This commit is contained in:
parent
9f5b6aaf73
commit
58da77ea4b
2 changed files with 44 additions and 21 deletions
|
@ -655,18 +655,24 @@ bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
|
|||
auto fence = readFence();
|
||||
auto dataspace = readSigned();
|
||||
auto damage = readRegion((length - 4) / 4);
|
||||
bool closeFence = true;
|
||||
|
||||
auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
|
||||
slot, useCache, clientTarget, &clientTarget);
|
||||
if (err == Error::NONE) {
|
||||
err = mHal.setClientTarget(mDisplay, clientTarget, fence,
|
||||
dataspace, damage);
|
||||
|
||||
updateBuffer(BufferCache::CLIENT_TARGETS, slot, useCache,
|
||||
clientTarget);
|
||||
auto updateBufErr = updateBuffer(BufferCache::CLIENT_TARGETS, slot,
|
||||
useCache, clientTarget);
|
||||
if (err == Error::NONE) {
|
||||
closeFence = false;
|
||||
err = updateBufErr;
|
||||
}
|
||||
}
|
||||
if (closeFence) {
|
||||
close(fence);
|
||||
}
|
||||
if (err != Error::NONE) {
|
||||
close(fence);
|
||||
mWriter.setError(getCommandLoc(), err);
|
||||
}
|
||||
|
||||
|
@ -683,17 +689,23 @@ bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
|
|||
auto slot = read();
|
||||
auto outputBuffer = readHandle(&useCache);
|
||||
auto fence = readFence();
|
||||
bool closeFence = true;
|
||||
|
||||
auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
|
||||
slot, useCache, outputBuffer, &outputBuffer);
|
||||
if (err == Error::NONE) {
|
||||
err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
|
||||
|
||||
updateBuffer(BufferCache::OUTPUT_BUFFERS,
|
||||
slot, useCache, outputBuffer);
|
||||
auto updateBufErr = updateBuffer(BufferCache::OUTPUT_BUFFERS,
|
||||
slot, useCache, outputBuffer);
|
||||
if (err == Error::NONE) {
|
||||
closeFence = false;
|
||||
err = updateBufErr;
|
||||
}
|
||||
}
|
||||
if (closeFence) {
|
||||
close(fence);
|
||||
}
|
||||
if (err != Error::NONE) {
|
||||
close(fence);
|
||||
mWriter.setError(getCommandLoc(), err);
|
||||
}
|
||||
|
||||
|
@ -786,17 +798,23 @@ bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
|
|||
auto slot = read();
|
||||
auto buffer = readHandle(&useCache);
|
||||
auto fence = readFence();
|
||||
bool closeFence = true;
|
||||
|
||||
auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
|
||||
slot, useCache, buffer, &buffer);
|
||||
if (err == Error::NONE) {
|
||||
err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
|
||||
|
||||
updateBuffer(BufferCache::LAYER_BUFFERS,
|
||||
slot, useCache, buffer);
|
||||
auto updateBufErr = updateBuffer(BufferCache::LAYER_BUFFERS, slot,
|
||||
useCache, buffer);
|
||||
if (err == Error::NONE) {
|
||||
closeFence = false;
|
||||
err = updateBufErr;
|
||||
}
|
||||
}
|
||||
if (closeFence) {
|
||||
close(fence);
|
||||
}
|
||||
if (err != Error::NONE) {
|
||||
close(fence);
|
||||
mWriter.setError(getCommandLoc(), err);
|
||||
}
|
||||
|
||||
|
@ -915,8 +933,10 @@ bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
|
|||
auto err = lookupLayerSidebandStream(stream, &stream);
|
||||
if (err == Error::NONE) {
|
||||
err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
|
||||
|
||||
updateLayerSidebandStream(stream);
|
||||
auto updateErr = updateLayerSidebandStream(stream);
|
||||
if (err == Error::NONE) {
|
||||
err = updateErr;
|
||||
}
|
||||
}
|
||||
if (err != Error::NONE) {
|
||||
mWriter.setError(getCommandLoc(), err);
|
||||
|
@ -1097,21 +1117,24 @@ Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
|
|||
return Error::NONE;
|
||||
}
|
||||
|
||||
void ComposerClient::CommandReader::updateBuffer(BufferCache cache,
|
||||
Error ComposerClient::CommandReader::updateBuffer(BufferCache cache,
|
||||
uint32_t slot, bool useCache, buffer_handle_t handle)
|
||||
{
|
||||
// handle was looked up from cache
|
||||
if (useCache) {
|
||||
return;
|
||||
return Error::NONE;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
|
||||
|
||||
BufferCacheEntry* entry = nullptr;
|
||||
lookupBufferCacheEntryLocked(cache, slot, &entry);
|
||||
LOG_FATAL_IF(!entry, "failed to find the cache entry to update");
|
||||
Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
|
||||
if (error != Error::NONE) {
|
||||
return error;
|
||||
}
|
||||
|
||||
*entry = handle;
|
||||
return Error::NONE;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
|
|
|
@ -173,7 +173,7 @@ protected:
|
|||
Error lookupBuffer(BufferCache cache, uint32_t slot,
|
||||
bool useCache, buffer_handle_t handle,
|
||||
buffer_handle_t* outHandle);
|
||||
void updateBuffer(BufferCache cache, uint32_t slot,
|
||||
Error updateBuffer(BufferCache cache, uint32_t slot,
|
||||
bool useCache, buffer_handle_t handle);
|
||||
|
||||
Error lookupLayerSidebandStream(buffer_handle_t handle,
|
||||
|
@ -182,9 +182,9 @@ protected:
|
|||
return lookupBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
|
||||
0, false, handle, outHandle);
|
||||
}
|
||||
void updateLayerSidebandStream(buffer_handle_t handle)
|
||||
Error updateLayerSidebandStream(buffer_handle_t handle)
|
||||
{
|
||||
updateBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
|
||||
return updateBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
|
||||
0, false, handle);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue