bufferpool2: fix native handle race condition

Return cloned handle as output parameter in order to use it after
closing the bufferpool connection.

Bug: 138171841
Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
Merged-In: I4ac142fcb7e3ecdb3fb02792f516b343d71bfc38
Change-Id: I4ac142fcb7e3ecdb3fb02792f516b343d71bfc38
(cherry picked from commit dc5cb62ff4)
gugelfrei
Sungtak Lee 5 years ago
parent 3ef81e1acc
commit 47897d5ff9

@ -351,7 +351,17 @@ ResultStatus ClientManager::Impl::allocate(
} }
client = it->second; client = it->second;
} }
return client->allocate(params, handle, buffer); native_handle_t *origHandle;
ResultStatus res = client->allocate(params, &origHandle, buffer);
if (res != ResultStatus::OK) {
return res;
}
*handle = native_handle_clone(origHandle);
if (handle == NULL) {
buffer->reset();
return ResultStatus::NO_MEMORY;
}
return ResultStatus::OK;
} }
ResultStatus ClientManager::Impl::receive( ResultStatus ClientManager::Impl::receive(
@ -367,7 +377,18 @@ ResultStatus ClientManager::Impl::receive(
} }
client = it->second; client = it->second;
} }
return client->receive(transactionId, bufferId, timestampUs, handle, buffer); native_handle_t *origHandle;
ResultStatus res = client->receive(
transactionId, bufferId, timestampUs, &origHandle, buffer);
if (res != ResultStatus::OK) {
return res;
}
*handle = native_handle_clone(origHandle);
if (handle == NULL) {
buffer->reset();
return ResultStatus::NO_MEMORY;
}
return ResultStatus::OK;
} }
ResultStatus ClientManager::Impl::postSend( ResultStatus ClientManager::Impl::postSend(

@ -104,7 +104,9 @@ struct ClientManager : public IClientManager {
ResultStatus flush(ConnectionId connectionId); ResultStatus flush(ConnectionId connectionId);
/** /**
* Allocates a buffer from the specified connection. * Allocates a buffer from the specified connection. The output parameter
* handle is cloned from the internal handle. So it is safe to use directly,
* and it should be deleted and destroyed after use.
* *
* @param connectionId The id of the connection. * @param connectionId The id of the connection.
* @param params The allocation parameters. * @param params The allocation parameters.
@ -123,7 +125,9 @@ struct ClientManager : public IClientManager {
std::shared_ptr<BufferPoolData> *buffer); std::shared_ptr<BufferPoolData> *buffer);
/** /**
* Receives a buffer for the transaction. * Receives a buffer for the transaction. The output parameter handle is
* cloned from the internal handle. So it is safe to use directly, and it
* should be deleted and destoyed after use.
* *
* @param connectionId The id of the receiving connection. * @param connectionId The id of the receiving connection.
* @param transactionId The id for the transaction. * @param transactionId The id for the transaction.

@ -1434,6 +1434,11 @@ bool objcpy(C2BaseBlock* d, const BaseBlock& s) {
d->type = C2BaseBlock::GRAPHIC; d->type = C2BaseBlock::GRAPHIC;
return true; return true;
} }
if (cHandle) {
// Though we got cloned handle, creating block failed.
native_handle_close(cHandle);
native_handle_delete(cHandle);
}
LOG(ERROR) << "Unknown handle type in BaseBlock::pooledBlock."; LOG(ERROR) << "Unknown handle type in BaseBlock::pooledBlock.";
return false; return false;

@ -413,17 +413,14 @@ std::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
std::shared_ptr<C2LinearAllocation> alloc; std::shared_ptr<C2LinearAllocation> alloc;
if (C2AllocatorIon::isValid(cHandle)) { if (C2AllocatorIon::isValid(cHandle)) {
native_handle_t *handle = native_handle_clone(cHandle); c2_status_t err = sAllocator->priorLinearAllocation(cHandle, &alloc);
if (handle) { const std::shared_ptr<C2PooledBlockPoolData> poolData =
c2_status_t err = sAllocator->priorLinearAllocation(handle, &alloc); std::make_shared<C2PooledBlockPoolData>(data);
const std::shared_ptr<C2PooledBlockPoolData> poolData = if (err == C2_OK && poolData) {
std::make_shared<C2PooledBlockPoolData>(data); // TODO: config params?
if (err == C2_OK && poolData) { std::shared_ptr<C2LinearBlock> block =
// TODO: config params? _C2BlockFactory::CreateLinearBlock(alloc, poolData);
std::shared_ptr<C2LinearBlock> block = return block;
_C2BlockFactory::CreateLinearBlock(alloc, poolData);
return block;
}
} }
} }
return nullptr; return nullptr;
@ -674,17 +671,14 @@ public:
ResultStatus status = mBufferPoolManager->allocate( ResultStatus status = mBufferPoolManager->allocate(
mConnectionId, params, &cHandle, &bufferPoolData); mConnectionId, params, &cHandle, &bufferPoolData);
if (status == ResultStatus::OK) { if (status == ResultStatus::OK) {
native_handle_t *handle = native_handle_clone(cHandle); std::shared_ptr<C2LinearAllocation> alloc;
if (handle) { std::shared_ptr<C2PooledBlockPoolData> poolData =
std::shared_ptr<C2LinearAllocation> alloc; std::make_shared<C2PooledBlockPoolData>(bufferPoolData);
std::shared_ptr<C2PooledBlockPoolData> poolData = c2_status_t err = mAllocator->priorLinearAllocation(cHandle, &alloc);
std::make_shared<C2PooledBlockPoolData>(bufferPoolData); if (err == C2_OK && poolData && alloc) {
c2_status_t err = mAllocator->priorLinearAllocation(handle, &alloc); *block = _C2BlockFactory::CreateLinearBlock(alloc, poolData, 0, capacity);
if (err == C2_OK && poolData && alloc) { if (*block) {
*block = _C2BlockFactory::CreateLinearBlock(alloc, poolData, 0, capacity); return C2_OK;
if (*block) {
return C2_OK;
}
} }
} }
return C2_NO_MEMORY; return C2_NO_MEMORY;
@ -710,19 +704,16 @@ public:
ResultStatus status = mBufferPoolManager->allocate( ResultStatus status = mBufferPoolManager->allocate(
mConnectionId, params, &cHandle, &bufferPoolData); mConnectionId, params, &cHandle, &bufferPoolData);
if (status == ResultStatus::OK) { if (status == ResultStatus::OK) {
native_handle_t *handle = native_handle_clone(cHandle); std::shared_ptr<C2GraphicAllocation> alloc;
if (handle) { std::shared_ptr<C2PooledBlockPoolData> poolData =
std::shared_ptr<C2GraphicAllocation> alloc; std::make_shared<C2PooledBlockPoolData>(bufferPoolData);
std::shared_ptr<C2PooledBlockPoolData> poolData = c2_status_t err = mAllocator->priorGraphicAllocation(
std::make_shared<C2PooledBlockPoolData>(bufferPoolData); cHandle, &alloc);
c2_status_t err = mAllocator->priorGraphicAllocation( if (err == C2_OK && poolData && alloc) {
handle, &alloc); *block = _C2BlockFactory::CreateGraphicBlock(
if (err == C2_OK && poolData && alloc) { alloc, poolData, C2Rect(width, height));
*block = _C2BlockFactory::CreateGraphicBlock( if (*block) {
alloc, poolData, C2Rect(width, height)); return C2_OK;
if (*block) {
return C2_OK;
}
} }
} }
return C2_NO_MEMORY; return C2_NO_MEMORY;
@ -1117,17 +1108,14 @@ std::shared_ptr<C2GraphicBlock> _C2BlockFactory::CreateGraphicBlock(
std::shared_ptr<C2GraphicAllocation> alloc; std::shared_ptr<C2GraphicAllocation> alloc;
if (C2AllocatorGralloc::isValid(cHandle)) { if (C2AllocatorGralloc::isValid(cHandle)) {
native_handle_t *handle = native_handle_clone(cHandle); c2_status_t err = sAllocator->priorGraphicAllocation(cHandle, &alloc);
if (handle) { const std::shared_ptr<C2PooledBlockPoolData> poolData =
c2_status_t err = sAllocator->priorGraphicAllocation(handle, &alloc); std::make_shared<C2PooledBlockPoolData>(data);
const std::shared_ptr<C2PooledBlockPoolData> poolData = if (err == C2_OK && poolData) {
std::make_shared<C2PooledBlockPoolData>(data); // TODO: config setup?
if (err == C2_OK && poolData) { std::shared_ptr<C2GraphicBlock> block =
// TODO: config setup? _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
std::shared_ptr<C2GraphicBlock> block = return block;
_C2BlockFactory::CreateGraphicBlock(alloc, poolData);
return block;
}
} }
} }
return nullptr; return nullptr;

Loading…
Cancel
Save