WireClient: MapReadCallback, unconditionnally consume the data

When a MapReadRequestCallback arrived late and hit one of the early out
of the handler (for example if the buffer was already unmapped), the
handler wouldn't consume the data payload of the command. This would
cause the command buffer pointer to not be advanced enough and point to
random data instead of the next command.
This commit is contained in:
Corentin Wallez 2018-07-10 15:54:01 +02:00 committed by Kai Ninomiya
parent 234becf175
commit d5c1ecaf64
1 changed files with 14 additions and 6 deletions

View File

@ -552,6 +552,16 @@ namespace nxt { namespace wire {
return false;
}
//* Unconditionnally get the data from the buffer so that the correct amount of data is
//* consumed from the buffer, even when we ignore the command and early out.
const char* requestData = nullptr;
if (cmd->status == NXT_BUFFER_MAP_ASYNC_STATUS_SUCCESS) {
requestData = GetData<char>(commands, size, cmd->dataLength);
if (requestData == nullptr) {
return false;
}
}
auto* buffer = mDevice->buffer.GetObject(cmd->bufferId);
uint32_t bufferSerial = mDevice->buffer.GetSerial(cmd->bufferId);
@ -572,7 +582,8 @@ namespace nxt { namespace wire {
}
auto request = requestIt->second;
//* Delete the request before calling the callback otherwise the callback could be fired a second time. If, for example, buffer.Unmap() is called inside the callback.
//* Delete the request before calling the callback otherwise the callback could be fired a
//* second time. If, for example, buffer.Unmap() is called inside the callback.
buffer->requests.erase(requestIt);
//* On success, we copy the data locally because the IPC buffer isn't valid outside of this function
@ -583,12 +594,9 @@ namespace nxt { namespace wire {
return false;
}
if (buffer->mappedData != nullptr) {
return false;
}
ASSERT(requestData != nullptr);
const char* requestData = GetData<char>(commands, size, request.size);
if (requestData == nullptr) {
if (buffer->mappedData != nullptr) {
return false;
}