-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Avoid excessive reply buffer copy in WinHTTP using a hack
- Loading branch information
Sergey Ryabinin
committed
May 10, 2024
1 parent
2fedad7
commit bae5120
Showing
8 changed files
with
189 additions
and
10 deletions.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
src/aws-cpp-sdk-core/include/aws/core/utils/stream/StreamBufProtectedWriter.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
|
||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <aws/core/Core_EXPORTS.h> | ||
#include <aws/core/utils/Array.h> | ||
#include <streambuf> | ||
#include <functional> | ||
|
||
namespace Aws | ||
{ | ||
namespace Utils | ||
{ | ||
namespace Stream | ||
{ | ||
/** | ||
* This is a wrapper to perform a hack to write directly to the put area of the underlying streambuf | ||
*/ | ||
class AWS_CORE_API StreamBufProtectedWriter : public std::streambuf | ||
{ | ||
public: | ||
StreamBufProtectedWriter() = delete; | ||
|
||
using WriterFunc = std::function<bool(char* dst, uint64_t dstSz, uint64_t& read)>; | ||
|
||
static size_t ForceOverflow(StreamBufProtectedWriter* pBuffer, const WriterFunc& writerFunc) | ||
{ | ||
char dstChar; | ||
size_t read = 0; | ||
if (writerFunc(&dstChar, 1, read) && read > 0) | ||
{ | ||
pBuffer->overflow(dstChar); | ||
return 1; | ||
} | ||
return 0; | ||
} | ||
|
||
static size_t WriteToBuffer(std::streambuf* pBuffer, const WriterFunc& writerFunc) | ||
{ | ||
StreamBufProtectedWriter* pBufferCasted = static_cast<StreamBufProtectedWriter*>(pBuffer); | ||
auto dstBegin = pBufferCasted->pptr(); | ||
auto dstSz = pBufferCasted->epptr() - dstBegin; | ||
size_t totalRead = 0; | ||
uint64_t read = 0; | ||
if (dstSz == 0) | ||
{ | ||
// prime the initial buffer | ||
char tmpBuf[1024]; | ||
uint64_t tmpBufSz = sizeof(tmpBuf); | ||
if (writerFunc(tmpBuf, tmpBufSz, read) && read > 0) | ||
{ | ||
pBufferCasted->xsputn(tmpBuf, read); | ||
totalRead += read; | ||
if (pBufferCasted->pptr() >= pBufferCasted->epptr()) | ||
{ | ||
if(!ForceOverflow(pBufferCasted, writerFunc)) | ||
{ | ||
return totalRead; | ||
} else { | ||
totalRead++; | ||
} | ||
} | ||
} else { | ||
return 0; | ||
} | ||
|
||
dstBegin = pBufferCasted->pptr(); | ||
assert(pBufferCasted->epptr() > dstBegin); | ||
dstSz = pBufferCasted->epptr() - dstBegin; | ||
assert(dstSz); | ||
} | ||
|
||
read = 0; | ||
while (writerFunc(dstBegin, dstSz, read) && read > 0) | ||
{ | ||
totalRead += read; | ||
pBufferCasted->pbump((int) read); | ||
if (pBufferCasted->pptr() >= pBufferCasted->epptr()) | ||
{ | ||
if(!ForceOverflow(pBufferCasted, writerFunc)) | ||
{ | ||
return totalRead; | ||
} else { | ||
totalRead++; | ||
} | ||
} | ||
dstBegin = pBufferCasted->pptr(); | ||
assert(pBufferCasted->epptr() > dstBegin); | ||
dstSz = pBufferCasted->epptr() - dstBegin; | ||
assert(dstSz); | ||
} | ||
return totalRead; | ||
} | ||
}; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters