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
This commit is contained in:
Erlend Egeberg Aasland 2021-11-03 22:01:37 +01:00 committed by GitHub
parent 762173c670
commit c273986711
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 18 deletions

View file

@ -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;