(self, ov, obj, callback)
| 713 | # that succeed immediately. |
| 714 | |
| 715 | def _register(self, ov, obj, callback): |
| 716 | self._check_closed() |
| 717 | |
| 718 | # Return a future which will be set with the result of the |
| 719 | # operation when it completes. The future's value is actually |
| 720 | # the value returned by callback(). |
| 721 | f = _OverlappedFuture(ov, loop=self._loop) |
| 722 | if f._source_traceback: |
| 723 | del f._source_traceback[-1] |
| 724 | if not ov.pending: |
| 725 | # The operation has completed, so no need to postpone the |
| 726 | # work. We cannot take this short cut if we need the |
| 727 | # NumberOfBytes, CompletionKey values returned by |
| 728 | # PostQueuedCompletionStatus(). |
| 729 | try: |
| 730 | value = callback(None, None, ov) |
| 731 | except OSError as e: |
| 732 | f.set_exception(e) |
| 733 | else: |
| 734 | f.set_result(value) |
| 735 | # Even if GetOverlappedResult() was called, we have to wait for the |
| 736 | # notification of the completion in GetQueuedCompletionStatus(). |
| 737 | # Register the overlapped operation to keep a reference to the |
| 738 | # OVERLAPPED object, otherwise the memory is freed and Windows may |
| 739 | # read uninitialized memory. |
| 740 | |
| 741 | # Register the overlapped operation for later. Note that |
| 742 | # we only store obj to prevent it from being garbage |
| 743 | # collected too early. |
| 744 | self._cache[ov.address] = (f, ov, obj, callback) |
| 745 | return f |
| 746 | |
| 747 | def _unregister(self, ov): |
| 748 | """Unregister an overlapped object. |
no test coverage detected