X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fio%2Fwindows%2Feventreader.cpp;h=8f208c20dda864c711ad5584697083c3df9b4ade;hb=HEAD;hp=62c9763d9fa92595385f658b36710d68087e09b8;hpb=609c9a508cfdc7b42c46c4f21d17639204165a00;p=libs%2Fcore.git diff --git a/source/io/windows/eventreader.cpp b/source/io/windows/eventreader.cpp index 62c9763..8f208c2 100644 --- a/source/io/windows/eventreader.cpp +++ b/source/io/windows/eventreader.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include "eventreader.h" @@ -11,31 +11,32 @@ namespace IO { struct EventReader::Private { - OVERLAPPED *overlapped; + OVERLAPPED overlapped; Handle event; - unsigned buf_size; - char *buffer; - unsigned buf_avail; - char *buf_next; + size_t buf_size = 0; + char *buffer = nullptr; + size_t buf_avail = 0; + char *buf_next = nullptr; + bool pending = false; + bool eof = false; }; -EventReader::EventReader(Handle &h, unsigned size): +EventReader::EventReader(Handle &h, size_t size): handle(h), priv(new Private) { - priv->overlapped = 0; - *priv->event = CreateEvent(0, true, false, 0); + memset(&priv->overlapped, 0, sizeof(OVERLAPPED)); + *priv->event = CreateEvent(nullptr, true, false, nullptr); + priv->overlapped.hEvent = *priv->event; priv->buf_size = size; priv->buffer = new char[priv->buf_size]; - priv->buf_avail = 0; priv->buf_next = priv->buffer; } EventReader::~EventReader() { CloseHandle(*priv->event); - delete priv->overlapped; delete[] priv->buffer; delete priv; } @@ -48,50 +49,56 @@ const Handle &EventReader::get_event() void EventReader::start() { - if(priv->buf_avail || priv->overlapped) + if(priv->buf_avail || priv->pending) return; - priv->overlapped = new OVERLAPPED; - memset(priv->overlapped, 0, sizeof(OVERLAPPED)); - priv->overlapped->hEvent = *priv->event; - DWORD ret; priv->buf_next = priv->buffer; - if(!ReadFile(*handle, priv->buffer, priv->buf_size, &ret, priv->overlapped)) + if(!ReadFile(*handle, priv->buffer, priv->buf_size, &ret, &priv->overlapped)) { unsigned err = GetLastError(); - if(err!=ERROR_IO_PENDING) + if(err==ERROR_BROKEN_PIPE) + priv->eof = true; + else if(err==ERROR_IO_PENDING) + priv->pending = true; + else throw system_error("ReadFile"); } else { priv->buf_avail = ret; - delete priv->overlapped; - priv->overlapped = 0; SetEvent(*priv->event); } } void EventReader::wait() { - if(!priv->overlapped) + if(!priv->pending) return; DWORD ret; - if(!GetOverlappedResult(*handle, priv->overlapped, &ret, true)) - throw system_error("GetOverlappedResult"); + if(!GetOverlappedResult(*handle, &priv->overlapped, &ret, true)) + { + DWORD err = GetLastError(); + if(err==ERROR_BROKEN_PIPE) + priv->eof = true; + else + throw system_error("GetOverlappedResult"); + } else { priv->buf_avail = ret; - delete priv->overlapped; - priv->overlapped = 0; + priv->pending = false; } } -unsigned EventReader::read(char *buf, unsigned len) +unsigned EventReader::read(char *buf, size_t len) { if(!priv->buf_avail) { + if(priv->eof) + return 0; + // No data in buffer, try to get some start(); wait();