From d5c1ecaf643332b4e21dd4a1b23f3ce3a1468886 Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Tue, 10 Jul 2018 15:54:01 +0200 Subject: [PATCH] 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. --- generator/templates/wire/WireClient.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/generator/templates/wire/WireClient.cpp b/generator/templates/wire/WireClient.cpp index dc55254beb..afef5f93bf 100644 --- a/generator/templates/wire/WireClient.cpp +++ b/generator/templates/wire/WireClient.cpp @@ -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(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(commands, size, request.size); - if (requestData == nullptr) { + if (buffer->mappedData != nullptr) { return false; }