| 3743 | |
| 3744 | # Create a mock process object that JsonRpcClient expects |
| 3745 | class SocketWrapper: |
| 3746 | def __init__(self, sock_file, sock_obj): |
| 3747 | self.stdin = sock_file |
| 3748 | self.stdout = sock_file |
| 3749 | self.stderr = None |
| 3750 | self._socket = sock_obj |
| 3751 | |
| 3752 | def terminate(self): |
| 3753 | import socket as _socket_mod |
| 3754 | |
| 3755 | # shutdown() sends TCP FIN to the server (triggering |
| 3756 | # server-side disconnect detection) and interrupts any |
| 3757 | # pending blocking reads on other threads immediately. |
| 3758 | try: |
| 3759 | self._socket.shutdown(_socket_mod.SHUT_RDWR) |
| 3760 | except OSError: |
| 3761 | pass # Safe to ignore — socket may already be closed |
| 3762 | # Close the file wrapper — makefile() holds its own |
| 3763 | # reference to the fd, so socket.close() alone won't |
| 3764 | # release the OS resource until the wrapper is closed too. |
| 3765 | try: |
| 3766 | self.stdin.close() |
| 3767 | except OSError: |
| 3768 | pass # Safe to ignore — already closed |
| 3769 | try: |
| 3770 | self._socket.close() |
| 3771 | except OSError: |
| 3772 | pass # Safe to ignore — already closed |
| 3773 | |
| 3774 | def kill(self): |
| 3775 | self.terminate() |
| 3776 | |
| 3777 | def wait(self, timeout=None): |
| 3778 | pass |
| 3779 | |
| 3780 | self._process = SocketWrapper(sock_file, sock) # type: ignore |
| 3781 | self._client = JsonRpcClient(self._process) |
no outgoing calls
no test coverage detected
searching dependent graphs…