]> git.tdb.fi Git - libs/core.git/blobdiff - source/io/windows/eventreader.cpp
Use a persistent OVERLAPPED structure in EventReader
[libs/core.git] / source / io / windows / eventreader.cpp
index 62c9763d9fa92595385f658b36710d68087e09b8..8a4c862d3eb7a9d846af590322fffed6d73b1ccb 100644 (file)
@@ -11,12 +11,13 @@ namespace IO {
 
 struct EventReader::Private
 {
-       OVERLAPPED *overlapped;
+       OVERLAPPED overlapped;
        Handle event;
        unsigned buf_size;
        char *buffer;
        unsigned buf_avail;
        char *buf_next;
+       bool pending;
 };
 
 
@@ -24,18 +25,19 @@ 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;
+       priv->pending = false;
 }
 
 EventReader::~EventReader()
 {
        CloseHandle(*priv->event);
-       delete priv->overlapped;
        delete[] priv->buffer;
        delete priv;
 }
@@ -48,43 +50,38 @@ 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_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))
+       if(!GetOverlappedResult(*handle, &priv->overlapped, &ret, true))
                throw system_error("GetOverlappedResult");
        else
        {
                priv->buf_avail = ret;
-               delete priv->overlapped;
-               priv->overlapped = 0;
+               priv->pending = false;
        }
 }