-
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
- Loading branch information
1 parent
2c07e1b
commit 7e5292b
Showing
14 changed files
with
282 additions
and
42 deletions.
There are no files selected for viewing
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
121 changes: 121 additions & 0 deletions
121
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,121 @@ | ||
|
||
/** | ||
* 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 uint64_t WriteToBuffer(Aws::IOStream& ioStream, const WriterFunc& writerFunc) | ||
{ | ||
uint64_t totalRead = 0; | ||
|
||
while (true) | ||
{ | ||
StreamBufProtectedWriter* pBufferCasted = static_cast<StreamBufProtectedWriter*>(ioStream.rdbuf()); | ||
bool bufferPresent = pBufferCasted && pBufferCasted->pptr() && (pBufferCasted->pptr() < pBufferCasted->epptr()); | ||
uint64_t read = 0; | ||
bool success = false; | ||
if (bufferPresent) | ||
{ | ||
// have access to underlying put ptr. | ||
success = WriteDirectlyToPtr(pBufferCasted, writerFunc, read); | ||
} | ||
else | ||
{ | ||
// can't access underlying buffer, stream buffer maybe be customized to not use put ptr. | ||
// or underlying put buffer is simply not initialized yet. | ||
success = WriteWithHelperBuffer(ioStream, writerFunc, read); | ||
} | ||
totalRead += read; | ||
if (!success) | ||
{ | ||
return totalRead; | ||
} | ||
|
||
if (pBufferCasted && pBufferCasted->pptr() && (pBufferCasted->pptr() >= pBufferCasted->epptr())) | ||
{ | ||
if(!ForceOverflow(ioStream, writerFunc)) | ||
{ | ||
return totalRead; | ||
} else { | ||
totalRead++; | ||
} | ||
} | ||
} | ||
return totalRead; | ||
} | ||
protected: | ||
static bool ForceOverflow(Aws::IOStream& ioStream, const WriterFunc& writerFunc) | ||
{ | ||
char dstChar; | ||
uint64_t read = 0; | ||
if (writerFunc(&dstChar, 1, read) && read > 0) | ||
{ | ||
ioStream.write(&dstChar, 1); | ||
if (ioStream.fail()) { | ||
AWS_LOGSTREAM_ERROR("StreamBufProtectedWriter", "Failed to write 1 byte (eof: " | ||
<< ioStream.eof() << ", bad: " << ioStream.bad() << ")"); | ||
return 0; | ||
} | ||
return 1; | ||
} | ||
return false; | ||
} | ||
|
||
static uint64_t WriteWithHelperBuffer(Aws::IOStream& ioStream, const WriterFunc& writerFunc, uint64_t& read) | ||
{ | ||
char tmpBuf[1024]; | ||
uint64_t tmpBufSz = sizeof(tmpBuf); | ||
|
||
if(writerFunc(tmpBuf, tmpBufSz, read) && read > 0) | ||
{ | ||
ioStream.write(tmpBuf, read); | ||
if (ioStream.fail()) { | ||
AWS_LOGSTREAM_ERROR("StreamBufProtectedWriter", "Failed to write " << tmpBufSz | ||
<< " (eof: " << ioStream.eof() << ", bad: " << ioStream.bad() << ")"); | ||
return false; | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
static uint64_t WriteDirectlyToPtr(StreamBufProtectedWriter* pBuffer, const WriterFunc& writerFunc, uint64_t& read) | ||
{ | ||
auto dstBegin = pBuffer->pptr(); | ||
uint64_t dstSz = pBuffer->epptr() - dstBegin; | ||
std::cout << "dst size = " << dstSz << "\n"; | ||
if(writerFunc(dstBegin, dstSz, read) && read > 0) | ||
{ | ||
assert(read <= dstSz); | ||
pBuffer->pbump((int) read); | ||
return true; | ||
} | ||
return false; | ||
} | ||
}; | ||
} | ||
} | ||
} |
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
Oops, something went wrong.