Repository: lutris/lutris

Issue:
Games launched through shortcuts launch with fallback version of DXVK
If you launch a game using a shortcut (or directly through terminal with a command like this `lutris  lutris:rungameid/109`) that DXVK without the version specified, the game will launch with a fallback DXVK version.
This doesn't happen if your turn off the internet or if you specify the version.
I suspect that this happens because Lutris modifies `dxvk_versions.json` on launch, so when Lutris also simultaneously tries to determine which latest version of DXVK it should use before launching the game, it fails to do that (as the file is being modified/changed) and uses the fallback version.
To fix this, Lutris might need to change the way it updates the `dxvk_versions.json` to avoid this issue.
Games launched through shortcuts launch with fallback version of DXVK
If you launch a game using a shortcut (or directly through terminal with a command like this `lutris  lutris:rungameid/109`) that DXVK without the version specified, the game will launch with a fallback DXVK version.
This doesn't happen if your turn off the internet or if you specify the version.
I suspect that this happens because Lutris modifies `dxvk_versions.json` on launch, so when Lutris also simultaneously tries to determine which latest version of DXVK it should use before launching the game, it fails to do that (as the file is being modified/changed) and uses the fallback version.
To fix this, Lutris might need to change the way it updates the `dxvk_versions.json` to avoid this issue.


Discussion:
> I guess DXVK might be affected as well

This does also affect DXVK
> I guess DXVK might be affected as well

This does also affect DXVK

Resolving patch:
diff --git a/lutris/gui/application.py b/lutris/gui/application.py
--- a/lutris/gui/application.py
+++ b/lutris/gui/application.py
@@ -49,7 +49,7 @@
 from lutris.util.http import Request, HTTPError
 from lutris.api import parse_installer_url
 from lutris.startup import init_lutris, run_all_checks
-from lutris.util.wine.dxvk import init_dxvk_versions
+from lutris.util.wine.dxvk import init_dxvk_versions, wait_for_dxvk_init
 
 from .lutriswindow import LutrisWindow
 
@@ -370,6 +370,7 @@ def launch(self, game):
         logger.debug("Launching %s (%s)", game, id(game))
         self.running_games.append(game)
         game.connect("game-stop", self.on_game_stop)
+        wait_for_dxvk_init()
         game.load_config()  # Reload the config before launching it.
         game.play()
 
diff --git a/lutris/util/wine/dxvk.py b/lutris/util/wine/dxvk.py
--- a/lutris/util/wine/dxvk.py
+++ b/lutris/util/wine/dxvk.py
@@ -1,6 +1,7 @@
 """DXVK helper module"""
 import os
 import json
+import threading
 import time
 import shutil
 import urllib.request
@@ -54,7 +55,20 @@ def init_versions(manager):
             manager.DXVK_VERSIONS[1:9],
         )
 
-    init_versions(DXVKManager)
+    # prevent race condition with if statement
+    with DXVKManager.init_lock:
+        # don't start init twice
+        if not DXVKManager.init_started:
+            DXVKManager.init_started = True
+            init_versions(DXVKManager)
+
+
+def wait_for_dxvk_init():
+    # wait for finishing DXVK initialization and prevent race condition with if statement
+    with DXVKManager.init_lock:
+        # in case DXVK init never got started, start it to prevent waiting indefinitely
+        if not DXVKManager.init_started:
+            init_dxvk_versions()
 
 
 class UnavailableDXVKVersion(RuntimeError):
@@ -70,6 +84,9 @@ class DXVKManager:
     ]
     DXVK_LATEST, DXVK_PAST_RELEASES = DXVK_VERSIONS[0], DXVK_VERSIONS[1:9]
 
+    init_started = False
+    init_lock = threading.RLock()
+
     base_url = "https://github.com/doitsujin/dxvk/releases/download/v{}/dxvk-{}.tar.gz"
     base_name = "dxvk"
     base_dir = os.path.join(RUNTIME_DIR, base_name)


Test patch: