Skip to content

Commit 9bf0ee6

Browse files
committed
fix(robot): add lock for _workspace_languages to prevent race condition
WeakKeyDictionary is not thread-safe for concurrent read/write. Protect all access to _workspace_languages with a dedicated RLock.
1 parent e2e4cbd commit 9bf0ee6

1 file changed

Lines changed: 28 additions & 26 deletions

File tree

packages/robot/src/robotcode/robot/diagnostics/document_cache_helper.py

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def __init__(
7777
self._imports_managers_lock = threading.RLock()
7878
self._imports_managers: weakref.WeakKeyDictionary[WorkspaceFolder, ImportsManager] = weakref.WeakKeyDictionary()
7979
self._default_imports_manager: Optional[ImportsManager] = None
80+
self._workspace_languages_lock = threading.RLock()
8081
self._workspace_languages: weakref.WeakKeyDictionary[WorkspaceFolder, Optional[Languages]] = (
8182
weakref.WeakKeyDictionary()
8283
)
@@ -101,32 +102,33 @@ def get_languages_for_document(self, document_or_uri: Union[TextDocument, Uri, s
101102
if folder is None:
102103
return None
103104

104-
if folder in self._workspace_languages:
105-
return self._workspace_languages[folder]
106-
107-
self._logger.debug(lambda: f"Get language config for {uri} in workspace {folder.uri}")
108-
config = self.workspace.get_configuration(RobotConfig, folder.uri)
109-
110-
languages = [str(v) for v in self.robot_profile.languages or []]
111-
languages += config.languages or []
112-
113-
if not languages:
114-
self._workspace_languages[folder] = None
115-
return None
116-
117-
result = RobotLanguages()
118-
for lang in languages:
119-
try:
120-
result.add_language(lang)
121-
except ValueError as e:
122-
ex = e
123-
self._logger.exception(
124-
lambda: f"Language configuration is not valid: {ex}",
125-
exc_info=ex,
126-
level=CRITICAL,
127-
)
128-
129-
self._workspace_languages[folder] = result
105+
with self._workspace_languages_lock:
106+
if folder in self._workspace_languages:
107+
return self._workspace_languages[folder]
108+
109+
self._logger.debug(lambda: f"Get language config for {uri} in workspace {folder.uri}")
110+
config = self.workspace.get_configuration(RobotConfig, folder.uri)
111+
112+
languages = [str(v) for v in self.robot_profile.languages or []]
113+
languages += config.languages or []
114+
115+
if not languages:
116+
self._workspace_languages[folder] = None
117+
return None
118+
119+
result = RobotLanguages()
120+
for lang in languages:
121+
try:
122+
result.add_language(lang)
123+
except ValueError as e:
124+
ex = e
125+
self._logger.exception(
126+
lambda: f"Language configuration is not valid: {ex}",
127+
exc_info=ex,
128+
level=CRITICAL,
129+
)
130+
131+
self._workspace_languages[folder] = result
130132

131133
return cast(Languages, RobotLanguages(result.languages))
132134

0 commit comments

Comments
 (0)