| 98 | return self._closed |
| 99 | |
| 100 | def close(self): |
| 101 | if self._closed: |
| 102 | return |
| 103 | self._closed = True |
| 104 | |
| 105 | for proto in self._pipes.values(): |
| 106 | if proto is None: |
| 107 | continue |
| 108 | # See gh-114177 |
| 109 | # skip closing the pipe if loop is already closed |
| 110 | # this can happen e.g. when loop is closed immediately after |
| 111 | # process is killed |
| 112 | if self._loop and not self._loop.is_closed(): |
| 113 | proto.pipe.close() |
| 114 | |
| 115 | if (self._proc is not None and |
| 116 | # has the child process finished? |
| 117 | self._returncode is None and |
| 118 | # the child process has finished, but the |
| 119 | # transport hasn't been notified yet? |
| 120 | self._proc.poll() is None): |
| 121 | |
| 122 | if self._loop.get_debug(): |
| 123 | logger.warning('Close running child process: kill %r', self) |
| 124 | |
| 125 | try: |
| 126 | self._proc.kill() |
| 127 | except (ProcessLookupError, PermissionError): |
| 128 | # the process may have already exited or may be running setuid |
| 129 | pass |
| 130 | |
| 131 | # Don't clear the _proc reference yet: _post_init() may still run |
| 132 | |
| 133 | def __del__(self, _warn=warnings.warn): |
| 134 | if not self._closed: |