diff --git a/generator/templates/wire/WireClient.cpp b/generator/templates/wire/WireClient.cpp index 75b9d91f04..a56ecbed85 100644 --- a/generator/templates/wire/WireClient.cpp +++ b/generator/templates/wire/WireClient.cpp @@ -545,9 +545,12 @@ namespace wire { } buffer->mappedData = malloc(request.size); memcpy(buffer->mappedData, cmd->GetData(), request.size); + + request.callback(static_cast(cmd->status), buffer->mappedData, request.userdata); + } else { + request.callback(static_cast(cmd->status), nullptr, request.userdata); } - request.callback(static_cast(cmd->status), buffer->mappedData, request.userdata); buffer->readRequests.erase(requestIt); return true; } diff --git a/src/tests/unittests/WireTests.cpp b/src/tests/unittests/WireTests.cpp index 36fbb33b1f..6efb932938 100644 --- a/src/tests/unittests/WireTests.cpp +++ b/src/tests/unittests/WireTests.cpp @@ -642,3 +642,39 @@ TEST_F(WireBufferMappingTests, UnmapCalledTooEarly) { // The callback shouldn't get called, even when the request succeeded on the server side FlushServer(); } + +// Check that an error callback gets nullptr while a buffer is already mapped +TEST_F(WireBufferMappingTests, MappingErrorWhileAlreadyMappedGetsNullptr) { + // Successful map + nxtCallbackUserdata userdata = 34098; + nxtBufferMapReadAsync(buffer, 40, sizeof(uint32_t), ToMockBufferMapReadCallback, userdata); + + uint32_t bufferContent = 31337; + EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, 40, sizeof(uint32_t), _, _)) + .WillOnce(InvokeWithoutArgs([&]() { + api.CallMapReadCallback(apiBuffer, NXT_BUFFER_MAP_READ_STATUS_SUCCESS, &bufferContent); + })) + .RetiresOnSaturation(); + + FlushClient(); + + EXPECT_CALL(*mockBufferMapReadCallback, Call(NXT_BUFFER_MAP_READ_STATUS_SUCCESS, Pointee(Eq(bufferContent)), userdata)) + .Times(1); + + FlushServer(); + + // Map failure while the buffer is already mapped + userdata ++; + nxtBufferMapReadAsync(buffer, 40, sizeof(uint32_t), ToMockBufferMapReadCallback, userdata); + EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, 40, sizeof(uint32_t), _, _)) + .WillOnce(InvokeWithoutArgs([&]() { + api.CallMapReadCallback(apiBuffer, NXT_BUFFER_MAP_READ_STATUS_ERROR, nullptr); + })); + + FlushClient(); + + EXPECT_CALL(*mockBufferMapReadCallback, Call(NXT_BUFFER_MAP_READ_STATUS_ERROR, nullptr, userdata)) + .Times(1); + + FlushServer(); +}