formatted_raw_ostream both is-a raw_ostream and has-a raw_ostream. This

means that two separate raw_ostreams are doing buffering before data is
sent to the underlying stream. Besides the inefficiency of redundant
buffering, the second level of buffering doesn't recieve flush()
requests.

Fix this by having formatted_raw_ostream set the underlying raw_ostream
to be unbuffered. This eliminates inefficiency due to redundant buffering,
and it makes the flush() disconnect harmless.

This fixes PR4559.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75883 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2009-07-16 01:32:46 +00:00
parent fe2fe7094e
commit 0e0979ecda

View File

@ -33,7 +33,8 @@ namespace llvm
const static bool PRESERVE_STREAM = false;
private:
/// TheStream - The real stream we output to.
/// TheStream - The real stream we output to. We set it to be
/// unbuffered, since we're already doing our own buffering.
///
raw_ostream *TheStream;
/// DeleteStream - Do we need to delete TheStream in the
@ -70,13 +71,27 @@ namespace llvm
/// put into ErrorInfo, and the stream should be immediately
/// destroyed; the string will be empty if no error occurred.
///
/// As a side effect, the given Stream is set to be Unbuffered.
/// This is because formatted_raw_ostream does its own buffering,
/// so it doesn't want another layer of buffering to be happening
/// underneath it.
///
/// \param Filename - The file to open. If this is "-" then the
/// stream will use stdout instead.
/// \param Binary - The file should be opened in binary mode on
/// platforms that support this distinction.
formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
: raw_ostream(), TheStream(&Stream), DeleteStream(Delete), Column(0) {}
explicit formatted_raw_ostream()
: raw_ostream(), TheStream(&Stream), DeleteStream(Delete), Column(0) {
// This formatted_raw_ostream inherits from raw_ostream, so it'll do its
// own buffering, and it doesn't need or want TheStream to do another
// layer of buffering underneath. Resize the buffer to what TheStream
// had been using, and tell TheStream not to do its own buffering.
TheStream->flush();
if (size_t BufferSize = TheStream->GetNumBytesInBuffer())
SetBufferSize(BufferSize);
TheStream->SetUnbuffered();
}
explicit formatted_raw_ostream()
: raw_ostream(), TheStream(0), DeleteStream(false), Column(0) {}
~formatted_raw_ostream() {
@ -87,6 +102,12 @@ namespace llvm
void setStream(raw_ostream &Stream, bool Delete = false) {
TheStream = &Stream;
DeleteStream = Delete;
// Avoid double-buffering, as above.
TheStream->flush();
if (size_t BufferSize = TheStream->GetNumBytesInBuffer())
SetBufferSize(BufferSize);
TheStream->SetUnbuffered();
}
/// PadToColumn - Align the output to some column number.