def send_handle(conn, handle, destination_pid): process_handle = win32.OpenProcess(win32.PROCESS_ALL_ACCESS, False, destination_pid) try: new_handle = duplicate(handle, process_handle) conn.send(new_handle) finally: close(process_handle)
def _reset(obj): global _lock, _listener, _cache for h in _cache: close(h) _cache.clear() _lock = threading.Lock() _listener = None
def _serve(): from .util import is_exiting, sub_warning while 1: try: conn = _listener.accept() handle_wanted, destination_pid = conn.recv() _cache.remove(handle_wanted) send_handle(conn, handle_wanted, destination_pid) close(handle_wanted) conn.close() except: if not is_exiting(): import traceback sub_warning('thread for sharing handles raised exception :\n' + '-' * 79 + '\n' + traceback.format_exc() + '-' * 79)
def spawn_children(self, number=1): parent_pid = os.getpid() for i in range(number): self.log.debug('createing child %d', i) to_child_r, to_child_w = os.pipe() from_child_r, from_child_w = os.pipe() self.log.debug('pipes create') to_child_r = copy_fd(to_child_r) from_child_w = copy_fd(from_child_w) self.log.debug('pipes copied') handle = copy_socket(self.sock.fileno()) self.log.debug('socket copied') command = [_python_exe, '-c', 'import sys; from spawning import spawning_child; spawning_child.main()', str(parent_pid), str(handle), str(to_child_r), str(from_child_w), self.factory, json.dumps(self.args)] if self.args['reload'] == 'dev': command.append('--reload') env = environ() tpool_size = int(self.config.get('threadpool_workers', 0)) assert tpool_size >= 0, (tpool_size, 'Cannot have a negative --threads argument') if not tpool_size in (0, 1): env['EVENTLET_THREADPOOL_SIZE'] = str(tpool_size) self.log.debug('cmd %s', command) proc = subprocess.Popen(command, env=env) # controller process close(to_child_r) close(from_child_w) # XXX create eventlet to listen to from_child_r ? child = self.children[proc.pid] = Child(proc, to_child_w, from_child_r) eventlet.spawn(self.read_child_pipe, from_child_r, child) self.log.debug('create child: %d', proc.pid)
def __init__(self, process_obj, env): # No super init call by intention! from multiprocessing.forking import duplicate, get_command_line, _python_exe, close, get_preparation_data, HIGHEST_PROTOCOL, dump import msvcrt import _subprocess # create pipe for communication with child rfd, wfd = os.pipe() # get handle for read end of the pipe and make it inheritable rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True) os.close(rfd) # start process cmd = get_command_line() + [rhandle] cmd = ' '.join('"%s"' % x for x in cmd) hp, ht, pid, tid = _subprocess.CreateProcess( _python_exe, cmd, None, None, 1, 0, env, None, None ) ht.Close() close(rhandle) # set attributes of self self.pid = pid self.returncode = None self._handle = hp # send information to child prep_data = get_preparation_data(process_obj._name) to_child = os.fdopen(wfd, 'wb') mp_Popen._tls.process_handle = int(hp) try: dump(prep_data, to_child, HIGHEST_PROTOCOL) dump(process_obj, to_child, HIGHEST_PROTOCOL) finally: del mp_Popen._tls.process_handle to_child.close()
def _finalize_pipe_listener(queue, address): sub_debug('closing listener with address=%r', address) for handle in queue: close(handle)
def rebuild_socket(reduced_handle, family, type_, proto): fd = rebuild_handle(reduced_handle) _sock = fromfd(fd, family, type_, proto) close(fd) return _sock