Repository navigation
Conversation
…hreads SQLite calls Python callbacks with the connection mutex held, so never block on that mutex while holding the GIL: enter it first, releasing the GIL only if it is contended.
An SQLite built with SQLITE_THREADSAFE=0, such as the Emscripten port, does not export sqlite3_mutex_enter(), sqlite3_mutex_try() or sqlite3_mutex_leave().
This comment was marked as resolved.
This comment was marked as resolved.
SQLite 3.53, which the Windows build bundles, also takes the connection mutex in sqlite3_limit(), sqlite3_get_autocommit(), sqlite3_changes(), sqlite3_total_changes() and sqlite3_errcode().
gpshead
marked this pull request as ready for review
November 1, 2026 21:22
gpshead
requested review from
AA-Turner,
corona10,
emmatyping and
itamaro
as code owners
November 1, 2026 21:22
Member
Author
|
This could use review from anyone who knows anything about sqlite3. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SQLite runs Python callbacks (functions, aggregates, collations, authorizer, progress and trace handlers) from inside
sqlite3_step()with the connection mutex held, and the callback then takes the GIL. The module also made other SQLite calls that take the same mutex while holding the GIL, so two threads sharing a connection could take the two locks in opposite orders and deadlock.The fix is one rule: a thread never blocks on the connection mutex while holding the GIL. New helpers in
util.htry the mutex first and release the GIL to wait for it only when the try fails, so the uncontended case is unchanged. They wrap the SQLite calls made with the GIL held that may take the mutex; which calls do varies by SQLite version, and 3.53 takes it in more of them. The mutex is recursive, so SQLite calls made under it re-enter it, it is NULL (a no-op) unless SQLite is in serialized mode, and it is never held while calling into Python.Sharing one cached statement between threads (gh-118172, gh-146471) is a separate problem, not addressed here. The
sqlite3_mutex_*()functions are missing from an SQLite built withSQLITE_THREADSAFE=0, such as the Emscripten port, so configure checks for them and the helpers do nothing without them; such a build cannot be in serialized mode.Fixes #161065
ANT-2026-R7FMVV3W