X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fio%2Fwindows%2Feventreader.cpp;h=8c4102067854eb0c9096ff92ab4277c1e3cf6441;hp=62c9763d9fa92595385f658b36710d68087e09b8;hb=03862ac4f38db0799872850dc4ab43b88688e4eb;hpb=609c9a508cfdc7b42c46c4f21d17639204165a00 diff --git a/source/io/windows/eventreader.cpp b/source/io/windows/eventreader.cpp index 62c9763..8c41020 100644 --- a/source/io/windows/eventreader.cpp +++ b/source/io/windows/eventreader.cpp @@ -11,12 +11,14 @@ 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 = 0; + size_t buf_avail = 0; + char *buf_next = 0; + bool pending = false; + bool eof = false; }; @@ -24,18 +26,17 @@ EventReader::EventReader(Handle &h, unsigned size): handle(h), priv(new Private) { - priv->overlapped = 0; + memset(&priv->overlapped, 0, sizeof(OVERLAPPED)); *priv->event = CreateEvent(0, true, false, 0); + 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,43 +49,46 @@ 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; } } @@ -92,6 +96,9 @@ unsigned EventReader::read(char *buf, unsigned len) { if(!priv->buf_avail) { + if(priv->eof) + return 0; + // No data in buffer, try to get some start(); wait();