1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-13 07:47:14 +03:00

Change JournalLock.obtain_lock() return to an Enum.

This way we can tell the difference between:

1. This process obtained the lock.
2. Another process has the lock.
3. We couldn't get the lock due to not being able to open the lock file
   read-write.

Case 3 is currently also returned if the configured journal directory
doesn't exist.  This will be the case on any MacOS system that never had
the game running.  Likely given the OS hasn't been supported for the
game in years now.
This commit is contained in:
Athanasius 2021-03-12 19:30:34 +00:00
parent e76e76bbe4
commit 60c67723ca
2 changed files with 21 additions and 13 deletions

View File

@ -33,7 +33,7 @@ if __name__ == '__main__':
# After the redirect in case config does logging setup
from config import appversion, appversion_nobuild, config, copyright
from EDMCLogging import edmclogger, logger, logging
from journal_lock import JournalLock
from journal_lock import JournalLock, JournalLockResult
if __name__ == '__main__': # noqa: C901
# Command-line arguments
@ -72,16 +72,14 @@ if __name__ == '__main__': # noqa: C901
config.set_auth_force_localserver()
def handle_edmc_callback_or_foregrounding(): # noqa: CCR001
"""
Handle any edmc:// auth callback, else foreground existing window.
"""
"""Handle any edmc:// auth callback, else foreground existing window."""
logger.trace('Begin...')
if platform == 'win32':
# If *this* instance hasn't locked, then another already has and we
# now need to do the edmc:// checks for auth callback
if not locked:
if locked != JournalLockResult.LOCKED:
import ctypes
from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPCWSTR, LPWSTR
@ -190,7 +188,7 @@ if __name__ == '__main__': # noqa: C901
handle_edmc_callback_or_foregrounding()
if not locked:
if locked == JournalLockResult.ALREADY_LOCKED:
# There's a copy already running.
logger.info("An EDMarketConnector.exe process was already running, exiting.")

View File

@ -2,6 +2,7 @@
import pathlib
import tkinter as tk
from enum import Enum
from os import getpid as os_getpid
from sys import platform
from tkinter import ttk
@ -17,6 +18,15 @@ if TYPE_CHECKING:
return x
class JournalLockResult(Enum):
"""Enumeration of possible outcomes of trying to lock the Journal Directory."""
LOCKED = 1
JOURNALDIR_NOTEXIST = 2
JOURNALDIR_READONLY = 3
ALREADY_LOCKED = 4
class JournalLock:
"""Handle locking of journal directory."""
@ -28,11 +38,11 @@ class JournalLock:
# We never test truthiness of this, so let it be defined when first assigned. Avoids type hint issues.
# self.journal_dir_lockfile: Optional[IO] = None
def obtain_lock(self) -> bool:
def obtain_lock(self) -> JournalLockResult:
"""
Attempt to obtain a lock on the journal directory.
:return: bool - True if we successfully obtained the lock
:return: LockResult - See the class Enum definition
"""
self.journal_dir_lockfile_name = self.journal_dir_path / 'edmc-journal-lock.txt'
logger.trace(f'journal_dir_lockfile_name = {self.journal_dir_lockfile_name!r}')
@ -44,7 +54,7 @@ class JournalLock:
except Exception as e: # For remote FS this could be any of a wide range of exceptions
logger.warning(f"Couldn't open \"{self.journal_dir_lockfile_name}\" for \"w+\""
f" Aborting duplicate process checks: {e!r}")
return False
return JournalLockResult.JOURNALDIR_READONLY
if platform == 'win32':
logger.trace('win32, using msvcrt')
@ -57,7 +67,7 @@ class JournalLock:
except Exception as e:
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\""
f", assuming another process running: {e!r}")
return False
return JournalLockResult.ALREADY_LOCKED
else:
logger.trace('NOT win32, using fcntl')
@ -67,7 +77,7 @@ class JournalLock:
except ImportError:
logger.warning("Not on win32 and we have no fcntl, can't use a file lock!"
"Allowing multiple instances!")
return True # Lie about being locked
return JournalLockResult.LOCKED
try:
fcntl.flock(self.journal_dir_lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
@ -75,13 +85,13 @@ class JournalLock:
except Exception as e:
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\", "
f"assuming another process running: {e!r}")
return False
return JournalLockResult.ALREADY_LOCKED
self.journal_dir_lockfile.write(f"Path: {self.journal_dir}\nPID: {os_getpid()}\n")
self.journal_dir_lockfile.flush()
logger.trace('Done')
return True
return JournalLockResult.LOCKED
def release_lock(self) -> bool:
"""