Eryk Sun <eryk...@gmail.com> added the comment:
I'm not fond of the way reduction.DupHandle() expects the receiving process to steal the duplicated handle. I'd prefer using the resource_sharer module, like reduction.DupFd() does in POSIX. Except spawning is a special case, for which reduction.DupHandle() can take advantage of the duplicate_for_child() method of the popen_spawn_win32.Popen instance. With the resource sharer, the handle still needs to be duplicated in the sending process. But an important difference is the resource_sharer.stop() method, which at least allows closing any handles that no longer need to be shared. --- Proposed Changes (untested) resource_sharer.py: class DupHandle(object): '''Wrapper for a handle that can be used at any time.''' def __init__(self, handle): dh = reduction.duplicate(handle) def send(conn, pid): reduction.send_handle(conn, dh, pid) def close(): _winapi.CloseHandle(dh) self._id = _resource_sharer.register(send, close) def detach(self): '''Get the handle. This should only be called once.''' with _resource_sharer.get_connection(self._id) as conn: return reduction.recv_handle(conn) reduction.py: def send_handle(conn, handle, destination_pid): '''Send a handle over a local connection.''' proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, destination_pid) try: dh = duplicate(handle, proc) conn.send(dh) finally: _winapi.CloseHandle(proc) def recv_handle(conn): '''Receive a handle over a local connection.''' return conn.recv() class _DupHandle: def __init__(self, handle): self.handle = handle def detach(self): return self.handle def DupHandle(handle): '''Return a wrapper for a handle.''' popen_obj = context.get_spawning_popen() if popen_obj is not None: return _DupHandle(popen_obj.duplicate_for_child(handle)) from . import resource_sharer return resource_sharer.DupHandle(handle) connection.py: def reduce_pipe_connection(conn): dh = reduction.DupHandle(conn.fileno()) return rebuild_pipe_connection, (dh, conn.readable, conn.writable) def rebuild_pipe_connection(dh, readable, writable): return PipeConnection(dh.detach(), readable, writable) reduction.register(PipeConnection, reduce_pipe_connection) ---------- components: +Library (Lib) nosy: +eryksun versions: +Python 3.10 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue42968> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com