From 12e71a29170756166095d2a0559e6f4253b1f905 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 7 Aug 2018 19:31:33 +0700 Subject: [PATCH] Set lower process priority when computing idle-pc value on Windows. Ref #2522. --- gns3server/compute/dynamips/__init__.py | 5 ++++ gns3server/compute/dynamips/nodes/router.py | 28 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/gns3server/compute/dynamips/__init__.py b/gns3server/compute/dynamips/__init__.py index 0254d969..c972c86a 100644 --- a/gns3server/compute/dynamips/__init__.py +++ b/gns3server/compute/dynamips/__init__.py @@ -561,6 +561,7 @@ class Dynamips(BaseManager): yield from vm.set_idlepc("0x0") was_auto_started = False + old_priority = None try: status = yield from vm.get_status() if status != "running": @@ -572,6 +573,8 @@ class Dynamips(BaseManager): if not idlepcs: raise DynamipsError("No Idle-PC values found") + if sys.platform.startswith("win"): + old_priority = vm.set_process_priority_windows(vm.hypervisor.process.pid) for idlepc in idlepcs: match = re.search(r"^0x[0-9a-f]{8}$", idlepc.split()[0]) if not match: @@ -600,6 +603,8 @@ class Dynamips(BaseManager): except DynamipsError: raise finally: + if old_priority is not None: + vm.set_process_priority_windows(vm.hypervisor.process.pid, old_priority) if was_auto_started: yield from vm.stop() return validated_idlepc diff --git a/gns3server/compute/dynamips/nodes/router.py b/gns3server/compute/dynamips/nodes/router.py index ec1a0f5c..8ff50afe 100644 --- a/gns3server/compute/dynamips/nodes/router.py +++ b/gns3server/compute/dynamips/nodes/router.py @@ -683,6 +683,29 @@ class Router(BaseNode): log.info('Router "{name}" [{id}]: idle-PC set to {idlepc}'.format(name=self._name, id=self._id, idlepc=idlepc)) self._idlepc = idlepc + def set_process_priority_windows(self, pid, priority=None): + """ + Sets process priority on Windows + + :param pid: process PID + """ + + import win32api + import win32process + import win32con + import pywintypes + + old_priority = None + try: + handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid) + old_priority = win32process.GetPriorityClass(handle) + if priority is None: + priority = win32process.BELOW_NORMAL_PRIORITY_CLASS + win32process.SetPriorityClass(handle, priority) + except pywintypes.error as e: + log.error("Cannot set priority for Dynamips process (PID={}) ".format(pid, e.strerror)) + return old_priority + @asyncio.coroutine def get_idle_pc_prop(self): """ @@ -701,8 +724,13 @@ class Router(BaseNode): yield from asyncio.sleep(20) # leave time to the router to boot log.info('Router "{name}" [{id}] has started calculating Idle-PC values'.format(name=self._name, id=self._id)) + old_priority = None + if sys.platform.startswith("win"): + old_priority = self.set_process_priority_windows(self._hypervisor.process.pid) begin = time.time() idlepcs = yield from self._hypervisor.send('vm get_idle_pc_prop "{}" 0'.format(self._name)) + if old_priority is not None: + self.set_process_priority_windows(self._hypervisor.process.pid, old_priority) log.info('Router "{name}" [{id}] has finished calculating Idle-PC values after {time:.4f} seconds'.format(name=self._name, id=self._id, time=time.time() - begin))