-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Overlapped Support in ReadFile() #141
base: master
Are you sure you want to change the base?
Conversation
@opalmer, thanks. |
@opalmer, I didn't manage to get time to review yesterday like i expected; here it is now:
Missing:
More radical possibility:
Let me know of your thoughts on these ideas and please point out anything I may be misunderstanding. Thanks. |
The more I read over your comment and think about the various use cases the more I think it would be appropriate to go with the fully backwards incompatible approach. There's a few reasons I think this route would be better:
I think making the backwards incompatible change would address nearly add the comments above (except for the missing tests of course....). |
Gave it some more thought and believe that moving to an incompatible signature/behavior is the best way forward. I believed that the current implementation could be enough as long as The most flexible, kind of Pythoninc, approach will be changing the signature and return value to something closer to the underlying system call:
Error conditions would raise exceptions, as currently. Returning the number of bytes read is fundamental such that the caller knows how much of the passed in buffer was filled up in the non-overlapped cases; in the overlapping cases I seem to remember that that information is somewhere else (maybe on the OVERLAPPED object?). In some way, such an API somehow mimics the standard library's Key benefit: buffer management 100% on the caller's side. I say, let's break compatibility now (better than later)! |
This commit updates the signature of ReadFile() to better match the underlying Windows API. By doing so we should be able to better support overlapped I/O and give the user of this function greater control over the input and output. For a complete discussion around why this change was made see #141.
@exvito please take a look at the latest commit (5434743), I think will address the discussion above. Updating the code was easy and I especially like that it made the tests more explicit: def test_read(self):
path, written = self._create_file(b"hello world")
self.assertEqual(written, 11)
hFile = self._handle_to_read_file(path)
lpBuffer = bytearray(written)
read = ReadFile(hFile, lpBuffer, 5)
self.assertEqual(read, 5)
self.assertEqual(lpBuffer[:read], bytearray(b"hello"))
# The rest of the buffer is essentially unmanaged but let's be sure
# the remainder of the buffer has not been modified by ReadFile().
self.assertEqual(
lpBuffer[read:], bytearray(b"\x00\x00\x00\x00\x00\x00")) I still need to write tests for overlapped I/O but I'd like you to review the latest changes first to be sure I'm not missing anything. |
It's looking preety good @opalmer.
|
One last, probably important note, regarding error checking and sync/async operation:
|
Fixed a couple of issues while I had some down time. Still need to work through the others (especially the tests). You're probably right that there may be some additional checks we need to implement...I need to take another pass at reading Side note, in the future could you post comments under |
This is looking better and better. Like I commented before, I believe there are two things that need improvement:
PS: Sorry for the comments on the commits, I didn't notice that. I will try to pay more attention. :) |
@exvito thanks and happy new year to you too :) Still not done here, but I added a function in 4f2b0ba which I think will cover basic error checks for both overlapped and non-overlapped I/O. When performing overlapped I/O, additional checks will be needed outside the calls to ReadFile and WriteFile. Definitely something I'm going to dive deeper into when I update the tests. |
|
||
# Overlapped IO case. | ||
_, library = dist.load() | ||
if GetLastError() == library.ERROR_IO_PENDING and code != 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the other way around. That is, we're facing an error if both:
code == 0
GetLastError() != ERROR_IO_PENDING
Looking better and better. I just made a comment on one error checking condition which seems to be the other way around: as far as I can tell, I made it under "Files Changed" and not in the commit. Hopefully I got that right, like you asked the other day. Let me know about that. Cheers. |
Resolves #116.