Skip to content

Commit

Permalink
Make a bunch of tweaks to try to fix memory errors blocking shutdown
Browse files Browse the repository at this point in the history
Tweaked the order of some resources getting destroyed, did a bit more manual cleanup of WX resources in `WxApp`.

Also shortened the loop sleep time in SnapshotService so that it can react quicker to kill signals.
  • Loading branch information
Crozzers committed Jul 1, 2024
1 parent f28dc00 commit 2fa5bd4
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/gui/systray.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def CreatePopupMenu(self):
return menu

def exit(self):
self.RemoveIcon()
if callable(self._on_exit):
self._on_exit()
self.RemoveIcon()

def __enter__(self):
return self
Expand Down
15 changes: 15 additions & 0 deletions src/gui/wx_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class WxApp(wx.App):
def __init__(self):
self._log = logging.getLogger(__name__).getChild(self.__class__.__name__ + '.' + str(id(self)))
super().__init__()
self.SetExitOnFrameDelete(False)

def __new__(cls, *args, **kwargs):
if not isinstance(getattr(cls, '_WxApp__instance', None), cls):
Expand Down Expand Up @@ -50,13 +51,27 @@ def check_parent_alive():
if not parent or parent.is_running():
return
self._log.info('parent process no longer running. exiting mainloop...')
if self.timer.IsRunning():
self.timer.Stop()
self.ExitMainLoop()

# enable sigterm by regularly returning control back to python
self.timer = wx.Timer(self._top_frame)
self._top_frame.Bind(wx.EVT_TIMER, lambda *_: check_parent_alive(), self.timer)
self.timer.Start(1000)

def Destroy(self):
if self.timer.IsRunning():
self.timer.Stop()
self.timer.Destroy()
if self._top_frame:
self._top_frame.Destroy()
if top := self.GetTopWindow():
top.Destroy()
if top := self.GetMainTopWindow():
top.Destroy()
return super().Destroy()


def spawn_gui(snapshot: SnapshotFile, start_page: Literal['rules', 'settings'] = 'rules'):
top = WxApp()._top_frame
Expand Down
11 changes: 7 additions & 4 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import psutil
import win32con
import win32gui

import wx
from common import Window, XandY, load_json, local_path, match, single_call
from device import DeviceChangeCallback, DeviceChangeService
from gui import TaskbarIcon, WxApp, about_dialog, radio_menu
Expand Down Expand Up @@ -190,14 +190,16 @@ def find_matching_profile(window: Window) -> Optional[dict]:
@single_call
def shutdown(*_):
log.info('begin shutdown process')
app.ExitMainLoop()
monitor_thread.stop()
snapshot_service.stop()
log.debug('destroy WxApp')
app.Destroy()
window_spawn_thread.stop()
log.info('save snapshot before shutting down')
snap.save()
log.debug('destroy WxApp')
app.ExitMainLoop()
app.Destroy()
log.info('end shutdown process')
wx.Exit()


if __name__ == '__main__':
Expand Down Expand Up @@ -288,3 +290,4 @@ def shutdown(*_):
log.info('app mainloop closed')
shutdown()
log.debug('fin')
wx.Exit()
2 changes: 1 addition & 1 deletion src/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,6 @@ def _runner(self, snapshot: SnapshotFile):

sleep_start = time.time()
while time.time() - sleep_start < settings.get('snapshot_freq', 30):
time.sleep(1)
time.sleep(0.5)
if self._kill_signal.is_set():
return

0 comments on commit 2fa5bd4

Please sign in to comment.