Remove StreamHandle

It was functionally identical to `std::shared_ptr<IStream>`.
This commit is contained in:
yvt 2019-07-23 21:55:39 +09:00
parent a2257a6fb7
commit 5fe8b0fe18
5 changed files with 16 additions and 113 deletions

View File

@ -39,10 +39,10 @@ namespace spades {
struct GameMapLoader::Decoder : public IRunnable {
GameMapLoader &parent;
StreamHandle rawDataReader;
std::unique_ptr<IStream> rawDataReader;
Decoder(GameMapLoader &parent, StreamHandle rawDataReader)
: parent{parent}, rawDataReader{rawDataReader} {}
Decoder(GameMapLoader &parent, std::unique_ptr<IStream> rawDataReader)
: parent{parent}, rawDataReader{std::move(rawDataReader)} {}
void Run() override {
SPADES_MARK_FUNCTION();
@ -50,7 +50,7 @@ namespace spades {
auto result = stmp::make_unique<Result>();
try {
DeflateStream inflate(&*rawDataReader, CompressModeDecompress, false);
DeflateStream inflate(rawDataReader.get(), CompressModeDecompress, false);
GameMap *gameMapPtr =
GameMap::Load(&inflate, [this](int x) { HandleProgress(x); });
@ -75,16 +75,10 @@ namespace spades {
auto pipe = CreatePipeStream();
rawDataWriter = StreamHandle{std::get<0>(pipe)};
auto rawDataReader = StreamHandle{std::get<1>(pipe)};
rawDataWriter = std::unique_ptr<IStream>{std::get<0>(pipe)};
auto rawDataReader = std::unique_ptr<IStream>{std::get<1>(pipe)};
decodingThreadRunnable = stmp::make_unique<Decoder>(*this, rawDataReader);
// Drop `rawDataReader` before the thread starts. `StreamHandle`'s internally
// ref-counted and it's not thread-safe. So, if we don't drop it here, there'll be
// a data race between the constructor of `Decoder` and the deconstruction of the local
// variable `rawDataReader`.
rawDataReader = StreamHandle{};
decodingThreadRunnable = stmp::make_unique<Decoder>(*this, std::move(rawDataReader));
decodingThread = stmp::make_unique<Thread>(&*decodingThreadRunnable);
decodingThread->Start();
@ -94,7 +88,7 @@ namespace spades {
SPADES_MARK_FUNCTION();
// Hang up the writer. This causes the decoder thread to exit gracefully.
rawDataWriter = StreamHandle{};
rawDataWriter.reset();
decodingThread->Join();
decodingThread.reset();
@ -116,7 +110,7 @@ namespace spades {
if (!rawDataWriter) {
SPRaise("The raw data channel is already closed.");
}
rawDataWriter = StreamHandle{};
rawDataWriter.reset();
}
bool GameMapLoader::IsComplete() { return resultCell.operator bool(); }

View File

@ -86,7 +86,7 @@ namespace spades {
struct Result;
/** A writable stream used to send undecoded data to the decoding thread. */
StreamHandle rawDataWriter;
std::unique_ptr<IStream> rawDataWriter;
/** A handle for the decoding thread. */
std::unique_ptr<Thread> decodingThread;

View File

@ -84,9 +84,9 @@ namespace spades {
if (codec->CanLoad() && codec->CheckExtension(filename)) {
// give it a try.
// open error shouldn't be handled here
StreamHandle str = FileManager::OpenForReading(filename.c_str());
std::unique_ptr<IStream> str{FileManager::OpenForReading(filename.c_str())};
try {
return {codec->Load(str), false};
return {codec->Load(str.get()), false};
} catch (const std::exception &ex) {
errMsg += codec->GetName();
errMsg += ":\n";
@ -135,9 +135,9 @@ namespace spades {
std::vector<IBitmapCodec *> codecs = IBitmapCodec::GetAllCodecs();
for (IBitmapCodec *codec : codecs) {
if (codec->CanSave() && codec->CheckExtension(filename)) {
StreamHandle str = FileManager::OpenForWriting(filename.c_str());
std::unique_ptr<IStream> str{FileManager::OpenForWriting(filename.c_str())};
codec->Save(str, this);
codec->Save(str.get(), this);
return;
}
}

View File

@ -20,10 +20,10 @@
#include <algorithm>
#include <Core/Debug.h>
#include "Debug.h"
#include "Exception.h"
#include "IStream.h"
#include <Core/Debug.h>
namespace spades {
IStream::~IStream() {}
@ -111,70 +111,4 @@ namespace spades {
SPRaise("Failed to read 4 bytes");
return data;
}
StreamHandle::StreamHandle() : o(NULL) {}
StreamHandle::StreamHandle(IStream *stream) {
SPADES_MARK_FUNCTION();
if (!stream)
SPInvalidArgument("stream");
o = new SharedStream(stream);
}
StreamHandle::StreamHandle(const StreamHandle &handle) : o(handle.o) {
SPADES_MARK_FUNCTION_DEBUG();
o->Retain();
}
StreamHandle::~StreamHandle() {
SPADES_MARK_FUNCTION();
Reset();
}
spades::StreamHandle &StreamHandle::operator=(const spades::StreamHandle &h) {
SPADES_MARK_FUNCTION();
if (o != h.o) {
SharedStream *old = o;
o = h.o;
if (o) {
o->Retain();
}
if (old) {
old->Release();
}
}
return *this;
}
IStream *StreamHandle::operator->() const {
SPAssert(o);
return o->stream;
}
StreamHandle::operator class spades::IStream *() const {
SPAssert(o);
return o->stream;
}
StreamHandle::operator bool() const { return o->stream; }
void StreamHandle::Reset() {
if (o) {
o->Release();
o = NULL;
}
}
StreamHandle::SharedStream::SharedStream(IStream *s) : stream(s), refCount(1) {}
StreamHandle::SharedStream::~SharedStream() { delete stream; }
void StreamHandle::SharedStream::Retain() { refCount++; }
void StreamHandle::SharedStream::Release() {
SPAssert(refCount > 0);
refCount--;
if (refCount == 0)
delete this;
}
}
} // namespace spades

View File

@ -66,29 +66,4 @@ namespace spades {
// utilities
virtual std::string ReadAllBytes();
};
/** makes management of stream lifetime easier.
* don't create multiple StreamHandles with the same IStream. */
class StreamHandle {
struct SharedStream {
IStream *stream;
int refCount;
SharedStream(IStream *);
~SharedStream();
void Retain();
void Release();
};
SharedStream *o;
public:
StreamHandle();
StreamHandle(IStream *);
StreamHandle(const StreamHandle &);
~StreamHandle();
spades::StreamHandle &operator=(const StreamHandle &);
void Reset();
IStream *operator->() const;
operator IStream *() const;
operator bool() const;
};
}