summaryrefslogtreecommitdiffstats
path: root/Modules/_sqlite
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2021-11-03 21:01:37 (GMT)
committerGitHub <noreply@github.com>2021-11-03 21:01:37 (GMT)
commitc2739867113a2b650db300c03ef06cf18dcee3f4 (patch)
tree859f757fe8859147d1efa51a86207771968c5a27 /Modules/_sqlite
parent762173c6709f5cf3b59cbbe47d4e6fafbfe7ec2a (diff)
downloadcpython-c2739867113a2b650db300c03ef06cf18dcee3f4.zip
cpython-c2739867113a2b650db300c03ef06cf18dcee3f4.tar.gz
cpython-c2739867113a2b650db300c03ef06cf18dcee3f4.tar.bz2
bpo-45613: Set `sqlite3.threadsafety` dynamically (GH-29227)
Use the compile-time selected default SQLite threaded mode to set the DB-API 2.0 attribute 'threadsafety' Mappings: - SQLITE_THREADSAFE=0 => threadsafety=0 - SQLITE_THREADSAFE=1 => threadsafety=3 - SQLITE_THREADSAFE=2 => threadsafety=1
Diffstat (limited to 'Modules/_sqlite')
-rw-r--r--Modules/_sqlite/module.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c
index 3bca33b..3b9f797 100644
--- a/Modules/_sqlite/module.c
+++ b/Modules/_sqlite/module.c
@@ -540,6 +540,28 @@ add_integer_constants(PyObject *module) {
return 0;
}
+/* Convert SQLite default threading mode (as set by the compile-time constant
+ * SQLITE_THREADSAFE) to the corresponding DB-API 2.0 (PEP 249) threadsafety
+ * level. */
+static int
+get_threadsafety(pysqlite_state *state)
+{
+ int mode = sqlite3_threadsafe();
+ switch (mode) {
+ case 0: // Single-thread mode; threads may not share the module.
+ return 0;
+ case 1: // Serialized mode; threads may share the module,
+ return 3; // connections, and cursors.
+ case 2: // Multi-thread mode; threads may share the module, but not
+ return 1; // connections.
+ default:
+ PyErr_Format(state->InterfaceError,
+ "Unable to interpret SQLite threadsafety mode. Got %d, "
+ "expected 0, 1, or 2", mode);
+ return -1;
+ }
+}
+
static int
module_traverse(PyObject *module, visitproc visit, void *arg)
{
@@ -689,6 +711,14 @@ module_exec(PyObject *module)
goto error;
}
+ int threadsafety = get_threadsafety(state);
+ if (threadsafety < 0) {
+ goto error;
+ }
+ if (PyModule_AddIntConstant(module, "threadsafety", threadsafety) < 0) {
+ goto error;
+ }
+
/* initialize microprotocols layer */
if (pysqlite_microprotocols_init(module) < 0) {
goto error;