1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-06-05 09:53:33 +03:00

Implement releasing of monitor.JournalLock()

* Implement JournalLock.release_lock().
* Renamed other methods to remove journaldir_ prefix.
* Slightly tweak the code flow for obtaining the lock.
* Implement JournalLock.update_lock(), called from AppWindow.postprefs().
This commit is contained in:
Athanasius 2021-03-05 12:45:22 +00:00
parent c0e7be98f8
commit e9c31c3293
2 changed files with 77 additions and 14 deletions

View File

@ -79,8 +79,6 @@ if __name__ == '__main__': # noqa: C901
""" """
logger.trace('Begin...') logger.trace('Begin...')
locked = journal_lock.journaldir_obtain_lock()
if platform == 'win32': if platform == 'win32':
if not locked: if not locked:
@ -191,6 +189,7 @@ if __name__ == '__main__': # noqa: C901
root.mainloop() root.mainloop()
journal_lock = JournalLock() journal_lock = JournalLock()
locked = journal_lock.obtain_lock()
if journal_lock.journal_dir_lockfile: if journal_lock.journal_dir_lockfile:
if not no_other_instance_running(): if not no_other_instance_running():
@ -551,6 +550,9 @@ class AppWindow(object):
# (Re-)install hotkey monitoring # (Re-)install hotkey monitoring
hotkeymgr.register(self.w, config.getint('hotkey_code'), config.getint('hotkey_mods')) hotkeymgr.register(self.w, config.getint('hotkey_code'), config.getint('hotkey_mods'))
# Update Journal lock if needs be.
journal_lock.update_lock()
# (Re-)install log monitoring # (Re-)install log monitoring
if not monitor.start(self.w): if not monitor.start(self.w):
self.status['text'] = f'Error: Check {_("E:D journal file location")}' self.status['text'] = f'Error: Check {_("E:D journal file location")}'

View File

@ -5,6 +5,7 @@ import threading
from os import getpid as os_getpid from os import getpid as os_getpid
from os import listdir, SEEK_SET, SEEK_END from os import listdir, SEEK_SET, SEEK_END
from os.path import basename, expanduser, isdir, join from os.path import basename, expanduser, isdir, join
import pathlib
from sys import platform from sys import platform
from time import gmtime, localtime, sleep, strftime, strptime, time from time import gmtime, localtime, sleep, strftime, strptime, time
from calendar import timegm from calendar import timegm
@ -1030,9 +1031,20 @@ class JournalLock:
def __init__(self): def __init__(self):
"""Initialise where the journal directory and lock file are.""" """Initialise where the journal directory and lock file are."""
self.journal_dir: str = config.get('journaldir') or config.default_journal_dir self.journal_dir: str = config.get('journaldir') or config.default_journal_dir
self.journal_dir_path = pathlib.Path(self.journal_dir)
self.journal_dir_lock = None self.journal_dir_lock = None
self.journal_dir_lockfile_name = None
self.journal_dir_lockfile = None
self.journal_dir_lockfile_name: str = join(self.journal_dir, 'edmc-journal-lock.txt') def obtain_lock(self) -> bool:
"""
Attempt to obtain a lock on the journal directory.
:return: bool - True if we successfully obtained the lock
"""
logger.trace(f'journal_dir_lockfile = {self.journal_dir_lockfile!r}')
self.journal_dir_lockfile_name: str = self.journal_dir_path / 'edmc-journal-lock.txt'
try: try:
self.journal_dir_lockfile = open(self.journal_dir_lockfile_name, mode='w+', encoding='utf-8') self.journal_dir_lockfile = open(self.journal_dir_lockfile_name, mode='w+', encoding='utf-8')
@ -1042,14 +1054,6 @@ class JournalLock:
logger.warning(f"Couldn't open \"{self.journal_dir_lockfile_name}\" for \"w+\"" logger.warning(f"Couldn't open \"{self.journal_dir_lockfile_name}\" for \"w+\""
f" Aborting duplicate process checks: {e!r}") f" Aborting duplicate process checks: {e!r}")
def journaldir_obtain_lock(self) -> bool:
"""
Attempt to obtain a lock on the journal directory.
:return: bool - True if we successfully obtained the lock
"""
logger.trace(f'journal_dir_lockfile = {self.journal_dir_lockfile!r}')
if platform == 'win32': if platform == 'win32':
logger.trace('win32, using msvcrt') logger.trace('win32, using msvcrt')
# win32 doesn't have fcntl, so we have to use msvcrt # win32 doesn't have fcntl, so we have to use msvcrt
@ -1087,6 +1091,63 @@ class JournalLock:
logger.trace('Done') logger.trace('Done')
return True return True
def journaldir_release_lock(self) -> bool: def release_lock(self) -> bool:
"""Release lock on journal directory.""" """
pass Release lock on journal directory.
:return: bool - Success of unlocking operation."""
unlocked = False
if platform == 'win32':
logger.trace('win32, using msvcrt')
# win32 doesn't have fcntl, so we have to use msvcrt
import msvcrt
try:
msvcrt.locking(self.journal_dir_lockfile.fileno(), msvcrt.LK_UNLCK, 4096)
except Exception as e:
logger.info(f"Exception: Couldn't unlock journal directory \"{self.journal_dir}\": {e!r}")
else:
unlocked = True
else:
logger.trace('NOT win32, using fcntl')
try:
import fcntl
except ImportError:
logger.warning("Not on win32 and we have no fcntl, can't use a file lock!")
return True # Lie about being unlocked
try:
fcntl.flock(self.journal_dir_lockfile, fcntl.LOCK_UN)
except Exception as e:
logger.info(f"Exception: Couldn't unlock journal directory \"{self.journal_dir}\": {e!r}")
else:
unlocked = True
# Close the file whether or not the unlocking succeeded.
self.journal_dir_lockfile.close()
self.journal_dir_lock = None
self.journal_dir_lockfile_name = None
self.journal_dir_lockfile = None
return unlocked
def update_lock(self) -> bool:
"""
Update journal directory lock to new location if possible.
:return: bool - Success of obtaining new lock
"""
current_journaldir = config.get('journaldir') or config.default_journal_dir
if current_journaldir == self.journal_dir:
return True # Still the same
self.journaldir_release_lock()
return self.journaldir_obtain_lock()