Esempio n. 1
0
        def write(self, buf, full=False, timeout=None):
            """Write data in 'buf' to file. If 'full' is True, the function
            waits till all data in buf is written; otherwise, it waits
            until one write completes. It returns length of data written.

            If no data has been written before timeout, then
            IOError('timedout') will be thrown.

            If timeout is given and full is True and timeout expires
            before all the data could be written, it returns length of
            data written before timeout if any data has been written.

            Must be used with 'yield' as
            'n = yield fd.write(buf)' to write (some) data in buf.
            """

            def _write(view, written):
                try:
                    n = os.write(self._fileno, view)
                except (OSError, IOError) as exc:
                    if exc.errno in (errno.EAGAIN, errno.EINTR):
                        n = 0
                    else:
                        self._notifier.clear(self, _AsyncPoller._Write)
                        if full:
                            view.release()
                        self._write_coro.throw(*sys.exc_info())
                        self._write_coro = self._write_task = None
                        return
                written += n
                if n == len(view) or not full:
                    self._notifier.clear(self, _AsyncPoller._Write)
                    if full:
                        view.release()
                    self._write_coro._proceed_(written)
                    self._write_coro = self._write_task = None
                else:
                    view = view[n:]
                    self._write_task = partial_func(_write, view, written)

            if not self._asyncoro:
                self._asyncoro = AsynCoro.scheduler()
                self._notifier = self._asyncoro._notifier
                if hasattr(self._fd, '_fileno'):
                    self._notifier.unregister(self._fd)
            if full:
                view = memoryview(buf)
            else:
                view = buf
            self._timeout = timeout
            self._write_coro = AsynCoro.cur_coro(self._asyncoro)
            self._write_coro._await_()
            self._write_task = partial_func(_write, view, 0)
            self._notifier.add(self, _AsyncPoller._Write)
Esempio n. 2
0
        def write(self, buf, full=False, timeout=None):
            """Write data in 'buf' to file. If 'full' is True, the function
            waits till all data in buf is written; otherwise, it waits
            until one write completes. It returns length of data written.

            If no data has been written before timeout, then
            IOError('timedout') will be thrown.

            If timeout is given and full is True and timeout expires
            before all the data could be written, it returns length of
            data written before timeout if any data has been written.

            Must be used with 'yield' as
            'n = yield fd.write(buf)' to write (some) data in buf.
            """
            def _write(view, written):
                try:
                    n = os.write(self._fileno, view)
                except (OSError, IOError) as exc:
                    if exc.errno in (errno.EAGAIN, errno.EINTR):
                        n = 0
                    else:
                        self._notifier.clear(self, _AsyncPoller._Write)
                        if full:
                            view.release()
                        self._write_coro.throw(*sys.exc_info())
                        self._write_coro = self._write_task = None
                        return
                written += n
                if n == len(view) or not full:
                    self._notifier.clear(self, _AsyncPoller._Write)
                    if full:
                        view.release()
                    self._write_coro._proceed_(written)
                    self._write_coro = self._write_task = None
                else:
                    view = view[n:]
                    self._write_task = partial_func(_write, view, written)

            if not self._asyncoro:
                self._asyncoro = AsynCoro.scheduler()
                self._notifier = self._asyncoro._notifier
                if hasattr(self._fd, '_fileno'):
                    self._notifier.unregister(self._fd)
            if full:
                view = memoryview(buf)
            else:
                view = buf
            self._timeout = timeout
            self._write_coro = AsynCoro.cur_coro(self._asyncoro)
            self._write_coro._await_()
            self._write_task = partial_func(_write, view, 0)
            self._notifier.add(self, _AsyncPoller._Write)
Esempio n. 3
0
        def read(self, size=0, full=False, timeout=None):
            """Read at most 'size' bytes from file; if 'size' <= 0,
            all data up to EOF is read and returned. If 'full' is
            True, exactly 'size' bytes are returned (unless EOF or
            timeout occur before). If EOF is encountered before any
            more data is available, empty buffer is returned.

            If no data has been read before timeout, then
            IOError('timedout') will be thrown.

            If timeout is given and full is True and timeout expires
            before all the data could be read, it returns partial data
            read before timeout if any data has been read.

            Must be used in a coroutine with 'yield' as
            'data = yield fd.read(1024)'
            """
            def _read(self, size, full):
                if size > 0:
                    count = size
                else:
                    count = 16384
                try:
                    buf = os.read(self._fileno, count)
                except (OSError, IOError) as exc:
                    if exc.errno in (errno.EAGAIN, errno.EWOULDBLOCK):
                        return
                    else:
                        raise
                except:
                    _AsyncFile._notifier.clear(self, _AsyncPoller._Read)
                    self._read_task = None
                    coro, self._read_coro = self._read_coro, None
                    coro.throw(*sys.exc_info())
                    return

                if buf:
                    if size > 0:
                        size -= len(buf)
                        # assert size >= 0
                        if size == 0:
                            full = False
                    self._buflist.append(buf)
                    if full:
                        self._read_task = partial_func(_read, self, size, full)
                        return
                if self._buflist:
                    buf, self._buflist = ''.join(self._buflist), []
                _AsyncFile._notifier.clear(self, _AsyncPoller._Read)
                self._read_coro._proceed_(buf)
                self._read_coro = self._read_task = None

            if not size or size < 0:
                size = 0
                full = True
            elif self._buflist:
                buf, self._buflist = ''.join(self._buflist), []
                if len(buf) > size:
                    buf, self._buflist = buf[:size], [buf[size:]]
                if (not full) or (len(buf) == size):
                    return buf
                self._buflist = [buf]
                size -= len(buf)
            self._timeout = timeout
            self._read_task = partial_func(_read, self, size, full)
            if not self._asyncoro:
                self._asyncoro = AsynCoro.scheduler()
            self._read_coro = AsynCoro.cur_coro(self._asyncoro)
            self._read_coro._await_()
            _AsyncFile._notifier.add(self, _AsyncPoller._Read)
Esempio n. 4
0
        def write(self, buf, full=False, timeout=None):
            """Write data in 'buf' to file. If 'full' is True, the function
            waits till all data in buf is written; otherwise, it waits
            until one write completes. It returns length of data written.

            If no data has been written before timeout, then
            IOError('timedout') will be thrown.

            If timeout is given and full is True and timeout expires
            before all the data could be written, it returns length of
            data written before timeout if any data has been written.

            Must be used with 'yield' as
            'n = yield fd.write(buf)' to write (some) data in buf.
            """
            def _write(self, written, full, rc, n):
                if rc or n == 0:
                    if self._timeout:
                        _AsyncFile._notifier._del_timeout(self)
                    if rc != winerror.ERROR_OPERATION_ABORTED:
                        if written:
                            self._write_coro._proceed_(written)
                        else:
                            self._write_coro.throw(IOError(rc, 'WriteFile', str(rc)))
                    self._overlap.object = self._write_coro = self._write_result = None
                    return

                written += n
                self._overlap.Offset += n
                self._write_result = self._write_result[n:]
                if not full or len(self._write_result) == 0:
                    self._overlap.object = self._write_result = None
                    if self._timeout:
                        _AsyncFile._notifier._del_timeout(self)
                    self._write_coro._proceed_(written)
                    self._write_coro = None
                    return

                self._overlap.object = partial_func(_write, self, written, full)
                try:
                    rc, _ = win32file.WriteFile(self._handle, self._write_result, self._overlap)
                except pywintypes.error as exc:
                    rc = exc.winerror
                if rc and rc != winerror.ERROR_IO_PENDING:
                    self._overlap.object = self._write_result = None
                    if self._timeout:
                        _AsyncFile._notifier._del_timeout(self)
                    if written:
                        self._write_coro._proceed_(written)
                    else:
                        self._write_coro.throw(IOError(rc, 'WriteFile', str(rc)))
                    self._write_coro = None
                return

            self._write_result = buffer(buf)
            self._overlap.object = partial_func(_write, self, 0, full)
            if not self._asyncoro:
                self._asyncoro = AsynCoro.scheduler()
            self._write_coro = AsynCoro.cur_coro(self._asyncoro)
            self._write_coro._await_()
            try:
                rc, _ = win32file.WriteFile(self._handle, self._write_result, self._overlap)
            except pywintypes.error as exc:
                if exc.winerror == winerror.ERROR_BROKEN_PIPE:
                    self._write_coro._proceed_(0)
                    self._write_result = self._write_coro = self._overlap.object = None
                    return
                else:
                    rc = exc.winerror
            if rc and rc != winerror.ERROR_IO_PENDING:
                self._overlap.object = self._write_result = self._write_coro = None
                raise IOError(rc, 'WriteFile', str(rc))
            if timeout:
                self._timeout = timeout
                _AsyncFile._notifier._add_timeout(self)
Esempio n. 5
0
        def read(self, size=0, full=False, timeout=None):
            """Read at most 'size' bytes from file; if 'size' <= 0,
            all data up to EOF is read and returned. If 'full' is
            True, exactly 'size' bytes are returned (unless EOF or
            timeout occur before). If EOF is encountered before any
            more data is available, empty buffer is returned.

            If no data has been read before timeout, then
            IOError('timedout') will be thrown.

            If timeout is given and full is True and timeout expires
            before all the data could be read, it returns partial data
            read before timeout if any data has been read.

            Must be used in a coroutine with 'yield' as
            'data = yield fd.read(1024)'
            """
            def _read(self, size, full, rc, n):
                if rc or n == 0:
                    if self._timeout:
                        _AsyncFile._notifier._del_timeout(self)
                    self._overlap.object = self._read_result = None
                    if rc != winerror.ERROR_OPERATION_ABORTED:
                        if (self._buflist or rc == winerror.ERROR_HANDLE_EOF or
                           rc == winerror.ERROR_BROKEN_PIPE):
                            buf, self._buflist = ''.join(self._buflist), []
                            self._read_coro._proceed_(buf)
                            return
                        self._read_coro.throw(IOError(rc, 'ReadFile', str(rc)))
                    self._overlap.object = self._read_coro = self._read_result = None
                    return

                buf = self._read_result[:n]
                if size > 0:
                    size -= len(buf)
                    assert size >= 0
                    if size == 0:
                        full = False
                self._buflist.append(buf)
                self._overlap.Offset += n
                if full:
                    self._overlap.object = partial_func(_read, self, size, full)
                    try:
                        rc, _ = win32file.ReadFile(self._handle, self._read_result, self._overlap)
                    except pywintypes.error as exc:
                        rc = exc.winerror
                    if rc and rc != winerror.ERROR_IO_PENDING:
                        buf, self._buflist = ''.join(self._buflist), []
                        self._overlap.object = self._read_result = None
                        if self._timeout:
                            _AsyncFile._notifier._del_timeout(self)
                        self._read_coro._proceed_(buf)
                        self._read_coro = None
                    return
                if self._buflist:
                    buf, self._buflist = ''.join(self._buflist), []
                if self._timeout:
                    _AsyncFile._notifier._del_timeout(self)
                self._overlap.object = self._read_result = None
                self._read_coro._proceed_(buf)
                self._read_coro = None

            if not size or size < 0:
                count = 16384
                full = True
            else:
                if self._buflist:
                    buf, self._buflist = ''.join(self._buflist), []
                    if len(buf) > size:
                        buf, self._buflist = buf[:size], [buf[size:]]
                    if (not full) or (len(buf) == size):
                        return buf
                    self._buflist = [buf]
                    size -= len(buf)
                count = size
            self._read_result = win32file.AllocateReadBuffer(count)
            self._overlap.object = partial_func(_read, self, size, full)
            if not self._asyncoro:
                self._asyncoro = AsynCoro.scheduler()
            self._read_coro = AsynCoro.cur_coro(self._asyncoro)
            self._read_coro._await_()
            try:
                rc, _ = win32file.ReadFile(self._handle, self._read_result, self._overlap)
            except pywintypes.error as exc:
                if exc.winerror == winerror.ERROR_BROKEN_PIPE:
                    buf, self._buflist = ''.join(self._buflist), []
                    self._read_coro._proceed_(buf)
                    self._read_result = self._read_coro = self._overlap.object = None
                    return
                else:
                    rc = exc.winerror
            if rc and rc != winerror.ERROR_IO_PENDING:
                self._overlap.object = self._read_result = self._read_coro = None
                raise IOError(rc, 'ReadFile', str(rc))
            if timeout:
                self._timeout = timeout
                _AsyncFile._notifier._add_timeout(self)
Esempio n. 6
0
        def read(self, size=0, full=False, timeout=None):
            """Read at most 'size' bytes from file; if 'size' <= 0,
            all data up to EOF is read and returned. If 'full' is
            True, exactly 'size' bytes are returned (unless EOF or
            timeout occur before). If EOF is encountered before any
            more data is available, empty buffer is returned.

            If no data has been read before timeout, then
            IOError('timedout') will be thrown.

            If timeout is given and full is True and timeout expires
            before all the data could be read, it returns partial data
            read before timeout if any data has been read.

            Must be used in a coroutine with 'yield' as
            'data = yield fd.read(1024)'
            """

            def _read(size, full):
                if size > 0:
                    count = size
                else:
                    count = 16384
                try:
                    buf = os.read(self._fileno, count)
                except (OSError, IOError) as exc:
                    if exc.errno in (errno.EAGAIN, errno.EWOULDBLOCK):
                        return
                    else:
                        raise
                except:
                    self._notifier.clear(self, _AsyncPoller._Read)
                    self._read_coro.throw(*sys.exc_info())
                    self._read_coro = self._read_task = None
                    return

                if buf:
                    if size > 0:
                        size -= len(buf)
                        # assert size >= 0
                        if size == 0:
                            full = False
                    self._buflist.append(buf)
                    if full:
                        self._read_task = partial_func(_read, size, full)
                        return
                if self._buflist:
                    buf, self._buflist = ''.join(self._buflist), []
                self._notifier.clear(self, _AsyncPoller._Read)
                self._read_coro._proceed_(buf)
                self._read_coro = self._read_task = None

            if not self._asyncoro:
                self._asyncoro = AsynCoro.scheduler()
                self._notifier = self._asyncoro._notifier
                if hasattr(self._fd, '_fileno'):
                    self._notifier.unregister(self._fd)
            if not size or size < 0:
                size = 0
                full = True
            elif self._buflist:
                buf, self._buflist = ''.join(self._buflist), []
                if len(buf) > size:
                    buf, self._buflist = buf[:size], [buf[size:]]
                if (not full) or (len(buf) == size):
                    return buf
                self._buflist = [buf]
                size -= len(buf)
            self._timeout = timeout
            self._read_coro = AsynCoro.cur_coro(self._asyncoro)
            self._read_coro._await_()
            self._read_task = partial_func(_read, size, full)
            self._notifier.add(self, _AsyncPoller._Read)
Esempio n. 7
0
        def write(self, buf, full=False, timeout=None):
            """Write data in 'buf' to file. If 'full' is True, the function
            waits till all data in buf is written; otherwise, it waits
            until one write completes. It returns length of data written.

            If no data has been written before timeout, then
            IOError('timedout') will be thrown.

            If timeout is given and full is True and timeout expires
            before all the data could be written, it returns length of
            data written before timeout if any data has been written.

            Must be used with 'yield' as
            'n = yield fd.write(buf)' to write (some) data in buf.
            """

            def _write(written, rc, n):
                if rc or n == 0:
                    if self._timeout:
                        self._notifier._del_timeout(self)
                    if rc != winerror.ERROR_OPERATION_ABORTED:
                        if written:
                            self._write_coro._proceed_(written)
                        else:
                            self._write_coro.throw(IOError(rc, 'WriteFile', str(rc)))
                    self._overlap.object = self._write_coro = self._write_result = None
                    return

                written += n
                self._overlap.Offset += n
                self._write_result = self._write_result[n:]
                if not full or len(self._write_result) == 0:
                    self._overlap.object = self._write_result = None
                    if self._timeout:
                        self._notifier._del_timeout(self)
                    self._write_coro._proceed_(written)
                    self._write_coro = None
                    return

                self._overlap.object = partial_func(_write, written)
                try:
                    rc, _ = win32file.WriteFile(self._handle, self._write_result, self._overlap)
                except pywintypes.error as exc:
                    rc = exc.winerror
                if rc and rc != winerror.ERROR_IO_PENDING:
                    self._overlap.object = self._write_result = None
                    if self._timeout:
                        self._notifier._del_timeout(self)
                    if written:
                        self._write_coro._proceed_(written)
                    else:
                        self._write_coro.throw(IOError(rc, 'WriteFile', str(rc)))
                    self._write_coro = None
                return

            if not self._asyncoro:
                self._asyncoro = AsynCoro.scheduler()
                self._notifier = self._asyncoro._notifier
                self._notifier.register(self._handle)
            self._write_result = buffer(buf)
            self._overlap.object = partial_func(_write, 0)
            self._write_coro = AsynCoro.cur_coro(self._asyncoro)
            self._write_coro._await_()
            try:
                rc, _ = win32file.WriteFile(self._handle, self._write_result, self._overlap)
            except pywintypes.error as exc:
                if exc.winerror == winerror.ERROR_BROKEN_PIPE:
                    self._write_coro._proceed_(0)
                    self._write_result = self._write_coro = self._overlap.object = None
                    return
                else:
                    rc = exc.winerror
            if rc and rc != winerror.ERROR_IO_PENDING:
                self._overlap.object = self._write_result = self._write_coro = None
                self._write_coro._proceed_(None)
                raise IOError(rc, 'WriteFile', str(rc))
            if timeout:
                self._timeout = timeout
                self._notifier._add_timeout(self)
Esempio n. 8
0
        def read(self, size=0, full=False, timeout=None):
            """Read at most 'size' bytes from file; if 'size' <= 0,
            all data up to EOF is read and returned. If 'full' is
            True, exactly 'size' bytes are returned (unless EOF or
            timeout occur before). If EOF is encountered before any
            more data is available, empty buffer is returned.

            If no data has been read before timeout, then
            IOError('timedout') will be thrown.

            If timeout is given and full is True and timeout expires
            before all the data could be read, it returns partial data
            read before timeout if any data has been read.

            Must be used in a coroutine with 'yield' as
            'data = yield fd.read(1024)'
            """

            def _read(size, full, rc, n):
                if rc or n == 0:
                    if self._timeout:
                        self._notifier._del_timeout(self)
                    self._overlap.object = self._read_result = None
                    if rc != winerror.ERROR_OPERATION_ABORTED:
                        if (self._buflist or rc == winerror.ERROR_HANDLE_EOF or
                           rc == winerror.ERROR_BROKEN_PIPE):
                            buf, self._buflist = ''.join(self._buflist), []
                            self._read_coro._proceed_(buf)
                            return
                        self._read_coro.throw(IOError(rc, 'ReadFile', str(rc)))
                    self._overlap.object = self._read_coro = self._read_result = None
                    return

                buf = self._read_result[:n]
                if size > 0:
                    size -= len(buf)
                    assert size >= 0
                    if size == 0:
                        full = False
                self._buflist.append(buf)
                self._overlap.Offset += n
                if full:
                    self._overlap.object = partial_func(_read, size, full)
                    try:
                        rc, _ = win32file.ReadFile(self._handle, self._read_result, self._overlap)
                    except pywintypes.error as exc:
                        rc = exc.winerror
                    if rc and rc != winerror.ERROR_IO_PENDING:
                        buf, self._buflist = ''.join(self._buflist), []
                        self._overlap.object = self._read_result = None
                        if self._timeout:
                            self._notifier._del_timeout(self)
                        self._read_coro._proceed_(buf)
                        self._read_coro = None
                    return
                if self._buflist:
                    buf, self._buflist = ''.join(self._buflist), []
                if self._timeout:
                    self._notifier._del_timeout(self)
                self._overlap.object = self._read_result = None
                self._read_coro._proceed_(buf)
                self._read_coro = None

            if not self._asyncoro:
                self._asyncoro = AsynCoro.scheduler()
                self._notifier = self._asyncoro._notifier
                self._notifier.register(self._handle)
            if not size or size < 0:
                count = 16384
                full = True
            else:
                if self._buflist:
                    buf, self._buflist = ''.join(self._buflist), []
                    if len(buf) > size:
                        buf, self._buflist = buf[:size], [buf[size:]]
                    if (not full) or (len(buf) == size):
                        return buf
                    self._buflist = [buf]
                    size -= len(buf)
                count = size
            self._read_result = win32file.AllocateReadBuffer(count)
            self._overlap.object = partial_func(_read, size, full)
            self._read_coro = AsynCoro.cur_coro(self._asyncoro)
            self._read_coro._await_()
            try:
                rc, _ = win32file.ReadFile(self._handle, self._read_result, self._overlap)
            except pywintypes.error as exc:
                if exc.winerror == winerror.ERROR_BROKEN_PIPE:
                    buf, self._buflist = ''.join(self._buflist), []
                    self._read_coro._proceed_(buf)
                    self._read_result = self._read_coro = self._overlap.object = None
                    return
                else:
                    rc = exc.winerror
            if rc and rc != winerror.ERROR_IO_PENDING:
                self._overlap.object = self._read_result = self._read_coro = None
                self._read_coro.throw(IOError(rc, 'ReadFile', str(rc)))
            if timeout:
                self._timeout = timeout
                self._notifier._add_timeout(self)
Esempio n. 9
0
        def write(self, buf, full=False, timeout=None):
            """Must be used with 'yield' as 'n = yield afile.write(buf)'
            """
            def _write(self, written, full, rc, n):
                if rc or n == 0:
                    if self._timeout:
                        _AsyncFile._notifier._del_timeout(self)
                    if rc != winerror.ERROR_OPERATION_ABORTED:
                        if written:
                            self._write_coro._proceed_(written)
                        else:
                            self._write_coro.throw(
                                IOError(rc, 'WriteFile', str(rc)))
                    self._overlap.object = self._write_coro = self._write_result = None
                    return

                written += n
                self._overlap.Offset += n
                self._write_result = self._write_result[n:]
                if not full or len(self._write_result) == 0:
                    self._overlap.object = self._write_result = None
                    if self._timeout:
                        _AsyncFile._notifier._del_timeout(self)
                    self._write_coro._proceed_(written)
                    self._write_coro = None
                    return

                self._overlap.object = partial_func(_write, self, written,
                                                    full)
                try:
                    rc, _ = win32file.WriteFile(self._handle,
                                                self._write_result,
                                                self._overlap)
                except pywintypes.error as exc:
                    rc = exc.winerror
                if rc and rc != winerror.ERROR_IO_PENDING:
                    self._overlap.object = self._write_result = None
                    if self._timeout:
                        _AsyncFile._notifier._del_timeout(self)
                    if written:
                        self._write_coro._proceed_(written)
                    else:
                        self._write_coro.throw(
                            IOError(rc, 'WriteFile', str(rc)))
                    self._write_coro = None
                return

            self._write_result = buffer(buf)
            self._overlap.object = partial_func(_write, self, 0, full)
            self._write_coro = AsynCoro.cur_coro()
            self._write_coro._await_()
            try:
                rc, _ = win32file.WriteFile(self._handle, self._write_result,
                                            self._overlap)
            except pywintypes.error as exc:
                if exc.winerror == winerror.ERROR_BROKEN_PIPE:
                    self._write_coro._proceed_(0)
                    self._write_result = self._write_coro = self._overlap.object = None
                    return
                else:
                    rc = exc.winerror
            if rc and rc != winerror.ERROR_IO_PENDING:
                self._overlap.object = self._write_result = self._write_coro = None
                raise IOError(rc, 'WriteFile', str(rc))
            if timeout:
                self._timeout = timeout
                _AsyncFile._notifier._add_timeout(self)
Esempio n. 10
0
        def read(self, size=0, full=False, timeout=None):
            """Must be used with 'yield' as 'buf = yield afile.read(1024)'
            """
            def _read(self, size, full, rc, n):
                if rc or n == 0:
                    if self._timeout:
                        _AsyncFile._notifier._del_timeout(self)
                    self._overlap.object = self._read_result = None
                    if rc != winerror.ERROR_OPERATION_ABORTED:
                        if self._buflist or rc == winerror.ERROR_HANDLE_EOF:
                            buf, self._buflist = ''.join(self._buflist), []
                            self._read_coro._proceed_(buf)
                            return
                        self._read_coro.throw(IOError(rc, 'ReadFile', str(rc)))
                    self._overlap.object = self._read_coro = self._read_result = None
                    return

                buf = self._read_result[:n]
                if size > 0:
                    size -= len(buf)
                    assert size >= 0
                    if size == 0:
                        full = False
                self._buflist.append(buf)
                self._overlap.Offset += n
                if full:
                    self._overlap.object = partial_func(
                        _read, self, size, full)
                    try:
                        rc, _ = win32file.ReadFile(self._handle,
                                                   self._read_result,
                                                   self._overlap)
                    except pywintypes.error as exc:
                        rc = exc.winerror
                    if rc and rc != winerror.ERROR_IO_PENDING:
                        buf, self._buflist = ''.join(self._buflist), []
                        self._overlap.object = self._read_result = None
                        if self._timeout:
                            _AsyncFile._notifier._del_timeout(self)
                        self._read_coro._proceed_(buf)
                        self._read_coro = None
                    return
                if self._buflist:
                    buf, self._buflist = ''.join(self._buflist), []
                if self._timeout:
                    _AsyncFile._notifier._del_timeout(self)
                self._overlap.object = self._read_result = None
                self._read_coro._proceed_(buf)
                self._read_coro = None

            if not size or size < 0:
                count = 16384
                full = True
            else:
                if self._buflist:
                    buf, self._buflist = ''.join(self._buflist), []
                    if len(buf) > size:
                        buf, self._buflist = buf[:size], [buf[size:]]
                    if (not full) or (len(buf) == size):
                        return buf
                    self._buflist = [buf]
                    size -= len(buf)
                count = size
            self._read_result = win32file.AllocateReadBuffer(count)
            self._overlap.object = partial_func(_read, self, size, full)
            self._read_coro = AsynCoro.cur_coro()
            self._read_coro._await_()
            try:
                rc, _ = win32file.ReadFile(self._handle, self._read_result,
                                           self._overlap)
            except pywintypes.error as exc:
                if exc.winerror == winerror.ERROR_BROKEN_PIPE:
                    buf, self._buflist = ''.join(self._buflist), []
                    self._read_coro._proceed_(buf)
                    self._read_result = self._read_coro = self._overlap.object = None
                    return
                else:
                    rc = exc.winerror
            if rc and rc != winerror.ERROR_IO_PENDING:
                self._overlap.object = self._read_result = self._read_coro = None
                raise IOError(rc, 'ReadFile', str(rc))
            if timeout:
                self._timeout = timeout
                _AsyncFile._notifier._add_timeout(self)