Skip to content

Commit 0ee1811

Browse files
authored
[lldb] Eliminate InitializePythonRAII::InitializeThreadsPrivate (NFC) (llvm#151780)
The behavior of thread initialization changed in Python 3.7. The minimum supported Python version is now 3.8. That means that `PyEval_ThreadsInitialized` always returns true and `PyEval_InitThreads` is never called. The helper function existed to coordinate initializing the threads and acquiring the GIL, which is no longer necessary. With that, there's no point in having the helper at all. This PR eliminates the function and inlines to GIL acquisition into the caller.
1 parent 8d9afb8 commit 0ee1811

File tree

1 file changed

+10
-41
lines changed

1 file changed

+10
-41
lines changed

lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp

Lines changed: 10 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,16 @@ struct InitializePythonRAII {
137137
config.install_signal_handlers = 0;
138138
Py_InitializeFromConfig(&config);
139139
PyConfig_Clear(&config);
140-
InitializeThreadsPrivate();
140+
141+
// The only case we should go further and acquire the GIL: it is unlocked.
142+
if (PyGILState_Check())
143+
return;
144+
145+
m_was_already_initialized = true;
146+
m_gil_state = PyGILState_Ensure();
147+
LLDB_LOGV(GetLog(LLDBLog::Script),
148+
"Ensured PyGILState. Previous state = {0}locked\n",
149+
m_gil_state == PyGILState_UNLOCKED ? "un" : "");
141150
}
142151

143152
~InitializePythonRAII() {
@@ -153,46 +162,6 @@ struct InitializePythonRAII {
153162
}
154163

155164
private:
156-
void InitializeThreadsPrivate() {
157-
// Since Python 3.7 `Py_Initialize` calls `PyEval_InitThreads` inside
158-
// itself, so there is no way to determine whether the embedded interpreter
159-
// was already initialized by some external code.
160-
// `PyEval_ThreadsInitialized` would always return `true` and
161-
// `PyGILState_Ensure/Release` flow would be executed instead of unlocking
162-
// GIL with `PyEval_SaveThread`. When an another thread calls
163-
// `PyGILState_Ensure` it would get stuck in deadlock.
164-
165-
// The only case we should go further and acquire the GIL: it is unlocked.
166-
if (PyGILState_Check())
167-
return;
168-
169-
// `PyEval_ThreadsInitialized` was deprecated in Python 3.9 and removed in
170-
// Python 3.13. It has been returning `true` always since Python 3.7.
171-
#if PY_VERSION_HEX < 0x03090000
172-
if (PyEval_ThreadsInitialized()) {
173-
#else
174-
if (true) {
175-
#endif
176-
Log *log = GetLog(LLDBLog::Script);
177-
178-
m_was_already_initialized = true;
179-
m_gil_state = PyGILState_Ensure();
180-
LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked\n",
181-
m_gil_state == PyGILState_UNLOCKED ? "un" : "");
182-
183-
// `PyEval_InitThreads` was deprecated in Python 3.9 and removed in
184-
// Python 3.13.
185-
#if PY_VERSION_HEX < 0x03090000
186-
return;
187-
}
188-
189-
// InitThreads acquires the GIL if it hasn't been called before.
190-
PyEval_InitThreads();
191-
#else
192-
}
193-
#endif
194-
}
195-
196165
PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
197166
bool m_was_already_initialized = false;
198167
};

0 commit comments

Comments
 (0)