Index: tools/telemetry/third_party/rope/rope/base/oi/doa.py |
diff --git a/tools/telemetry/third_party/rope/rope/base/oi/doa.py b/tools/telemetry/third_party/rope/rope/base/oi/doa.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..de45902b90d1a23f495c9fa5fe7e1064a717bd8d |
--- /dev/null |
+++ b/tools/telemetry/third_party/rope/rope/base/oi/doa.py |
@@ -0,0 +1,166 @@ |
+try: |
+ import pickle |
+except ImportError: |
+ import cPickle as pickle |
+import marshal |
+import os |
+import socket |
+import subprocess |
+import sys |
+import tempfile |
+import threading |
+ |
+ |
+class PythonFileRunner(object): |
+ """A class for running python project files""" |
+ |
+ def __init__(self, pycore, file_, args=None, stdin=None, |
+ stdout=None, analyze_data=None): |
+ self.pycore = pycore |
+ self.file = file_ |
+ self.analyze_data = analyze_data |
+ self.observers = [] |
+ self.args = args |
+ self.stdin = stdin |
+ self.stdout = stdout |
+ |
+ def run(self): |
+ """Execute the process""" |
+ env = dict(os.environ) |
+ file_path = self.file.real_path |
+ path_folders = self.pycore.project.get_source_folders() + \ |
+ self.pycore.project.get_python_path_folders() |
+ env['PYTHONPATH'] = os.pathsep.join(folder.real_path |
+ for folder in path_folders) |
+ runmod_path = self.pycore.project.find_module('rope.base.oi.runmod').real_path |
+ self.receiver = None |
+ self._init_data_receiving() |
+ send_info = '-' |
+ if self.receiver: |
+ send_info = self.receiver.get_send_info() |
+ args = [sys.executable, runmod_path, send_info, |
+ self.pycore.project.address, self.file.real_path] |
+ if self.analyze_data is None: |
+ del args[1:4] |
+ if self.args is not None: |
+ args.extend(self.args) |
+ self.process = subprocess.Popen( |
+ executable=sys.executable, args=args, env=env, |
+ cwd=os.path.split(file_path)[0], stdin=self.stdin, |
+ stdout=self.stdout, stderr=self.stdout, close_fds=os.name != 'nt') |
+ |
+ def _init_data_receiving(self): |
+ if self.analyze_data is None: |
+ return |
+ # Disabling FIFO data transfer due to blocking when running |
+ # unittests in the GUI. |
+ # XXX: Handle FIFO data transfer for `rope.ui.testview` |
+ if True or os.name == 'nt': |
+ self.receiver = _SocketReceiver() |
+ else: |
+ self.receiver = _FIFOReceiver() |
+ self.receiving_thread = threading.Thread( |
+ target=self._receive_information) |
+ self.receiving_thread.setDaemon(True) |
+ self.receiving_thread.start() |
+ |
+ def _receive_information(self): |
+ #temp = open('/dev/shm/info', 'w') |
+ for data in self.receiver.receive_data(): |
+ self.analyze_data(data) |
+ #temp.write(str(data) + '\n') |
+ #temp.close() |
+ for observer in self.observers: |
+ observer() |
+ |
+ def wait_process(self): |
+ """Wait for the process to finish""" |
+ self.process.wait() |
+ if self.analyze_data: |
+ self.receiving_thread.join() |
+ |
+ def kill_process(self): |
+ """Stop the process""" |
+ if self.process.poll() is not None: |
+ return |
+ try: |
+ if hasattr(self.process, 'terminate'): |
+ self.process.terminate() |
+ elif os.name != 'nt': |
+ os.kill(self.process.pid, 9) |
+ else: |
+ import ctypes |
+ handle = int(self.process._handle) |
+ ctypes.windll.kernel32.TerminateProcess(handle, -1) |
+ except OSError: |
+ pass |
+ |
+ def add_finishing_observer(self, observer): |
+ """Notify this observer when execution finishes""" |
+ self.observers.append(observer) |
+ |
+ |
+class _MessageReceiver(object): |
+ |
+ def receive_data(self): |
+ pass |
+ |
+ def get_send_info(self): |
+ pass |
+ |
+ |
+class _SocketReceiver(_MessageReceiver): |
+ |
+ def __init__(self): |
+ self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
+ self.data_port = 3037 |
+ while self.data_port < 4000: |
+ try: |
+ self.server_socket.bind(('', self.data_port)) |
+ break |
+ except socket.error: |
+ self.data_port += 1 |
+ self.server_socket.listen(1) |
+ |
+ def get_send_info(self): |
+ return str(self.data_port) |
+ |
+ def receive_data(self): |
+ conn, addr = self.server_socket.accept() |
+ self.server_socket.close() |
+ my_file = conn.makefile('r') |
+ while True: |
+ try: |
+ yield pickle.load(my_file) |
+ except EOFError: |
+ break |
+ my_file.close() |
+ conn.close() |
+ |
+ |
+class _FIFOReceiver(_MessageReceiver): |
+ |
+ def __init__(self): |
+ # XXX: this is insecure and might cause race conditions |
+ self.file_name = self._get_file_name() |
+ os.mkfifo(self.file_name) |
+ |
+ def _get_file_name(self): |
+ prefix = tempfile.gettempdir() + '/__rope_' |
+ i = 0 |
+ while os.path.exists(prefix + str(i).rjust(4, '0')): |
+ i += 1 |
+ return prefix + str(i).rjust(4, '0') |
+ |
+ def get_send_info(self): |
+ return self.file_name |
+ |
+ def receive_data(self): |
+ my_file = open(self.file_name, 'rb') |
+ while True: |
+ try: |
+ yield marshal.load(my_file) |
+ except EOFError: |
+ break |
+ my_file.close() |
+ os.remove(self.file_name) |