Skip to content

Commit 74c1f41

Browse files
authored
gh-144377: Clean up sqlite3 Connection's list of weakrefs to Cursor objects (#144378)
1 parent 3abc03c commit 74c1f41

File tree

3 files changed

+2
-83
lines changed

3 files changed

+2
-83
lines changed

Modules/_sqlite/connection.c

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
3939
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
4040
#include "pycore_unicodeobject.h" // _PyUnicode_AsUTF8NoNUL
41-
#include "pycore_weakref.h"
4241

4342
#include <stdbool.h>
4443

@@ -144,7 +143,6 @@ class _sqlite3.Connection "pysqlite_Connection *" "clinic_state()->ConnectionTyp
144143
[clinic start generated code]*/
145144
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=67369db2faf80891]*/
146145

147-
static int _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self);
148146
static void incref_callback_context(callback_context *ctx);
149147
static void decref_callback_context(callback_context *ctx);
150148
static void set_callback_context(callback_context **ctx_pp,
@@ -285,17 +283,10 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database,
285283
goto error;
286284
}
287285

288-
/* Create lists of weak references to cursors and blobs */
289-
PyObject *cursors = PyList_New(0);
290-
if (cursors == NULL) {
291-
Py_DECREF(statement_cache);
292-
goto error;
293-
}
294-
286+
/* Create lists of weak references to blobs */
295287
PyObject *blobs = PyList_New(0);
296288
if (blobs == NULL) {
297289
Py_DECREF(statement_cache);
298-
Py_DECREF(cursors);
299290
goto error;
300291
}
301292

@@ -308,9 +299,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database,
308299
self->check_same_thread = check_same_thread;
309300
self->thread_ident = PyThread_get_thread_ident();
310301
self->statement_cache = statement_cache;
311-
self->cursors = cursors;
312302
self->blobs = blobs;
313-
self->created_cursors = 0;
314303
self->row_factory = Py_NewRef(Py_None);
315304
self->text_factory = Py_NewRef(&PyUnicode_Type);
316305
self->trace_ctx = NULL;
@@ -392,7 +381,6 @@ connection_traverse(PyObject *op, visitproc visit, void *arg)
392381
pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
393382
Py_VISIT(Py_TYPE(self));
394383
Py_VISIT(self->statement_cache);
395-
Py_VISIT(self->cursors);
396384
Py_VISIT(self->blobs);
397385
Py_VISIT(self->row_factory);
398386
Py_VISIT(self->text_factory);
@@ -417,7 +405,6 @@ connection_clear(PyObject *op)
417405
{
418406
pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
419407
Py_CLEAR(self->statement_cache);
420-
Py_CLEAR(self->cursors);
421408
Py_CLEAR(self->blobs);
422409
Py_CLEAR(self->row_factory);
423410
Py_CLEAR(self->text_factory);
@@ -562,11 +549,6 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory)
562549
return NULL;
563550
}
564551

565-
if (_pysqlite_drop_unused_cursor_references(self) < 0) {
566-
Py_DECREF(cursor);
567-
return NULL;
568-
}
569-
570552
if (cursor && self->row_factory != Py_None) {
571553
Py_INCREF(self->row_factory);
572554
Py_XSETREF(((pysqlite_Cursor *)cursor)->row_factory, self->row_factory);
@@ -1067,38 +1049,6 @@ final_callback(sqlite3_context *context)
10671049
PyGILState_Release(threadstate);
10681050
}
10691051

1070-
static int
1071-
_pysqlite_drop_unused_cursor_references(pysqlite_Connection* self)
1072-
{
1073-
/* we only need to do this once in a while */
1074-
if (self->created_cursors++ < 200) {
1075-
return 0;
1076-
}
1077-
1078-
self->created_cursors = 0;
1079-
1080-
PyObject* new_list = PyList_New(0);
1081-
if (!new_list) {
1082-
return -1;
1083-
}
1084-
1085-
assert(PyList_CheckExact(self->cursors));
1086-
Py_ssize_t imax = PyList_GET_SIZE(self->cursors);
1087-
for (Py_ssize_t i = 0; i < imax; i++) {
1088-
PyObject* weakref = PyList_GET_ITEM(self->cursors, i);
1089-
if (_PyWeakref_IsDead(weakref)) {
1090-
continue;
1091-
}
1092-
if (PyList_Append(new_list, weakref) != 0) {
1093-
Py_DECREF(new_list);
1094-
return -1;
1095-
}
1096-
}
1097-
1098-
Py_SETREF(self->cursors, new_list);
1099-
return 0;
1100-
}
1101-
11021052
/* Allocate a UDF/callback context structure. In order to ensure that the state
11031053
* pointer always outlives the callback context, we make sure it owns a
11041054
* reference to the module itself. create_callback_context() is always called

Modules/_sqlite/connection.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,9 @@ typedef struct
7070

7171
PyObject *statement_cache;
7272

73-
/* Lists of weak references to cursors and blobs used within this connection */
74-
PyObject *cursors;
73+
/* Lists of weak references to blobs used within this connection */
7574
PyObject *blobs;
7675

77-
/* Counters for how many cursors were created in the connection. May be
78-
* reset to 0 at certain intervals */
79-
int created_cursors;
80-
8176
PyObject* row_factory;
8277

8378
/* Determines how bytestrings from SQLite are converted to Python objects:

Modules/_sqlite/cursor.c

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -99,28 +99,6 @@ class _sqlite3.Cursor "pysqlite_Cursor *" "clinic_state()->CursorType"
9999
[clinic start generated code]*/
100100
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c5b8115c5cf30f1]*/
101101

102-
/*
103-
* Registers a cursor with the connection.
104-
*
105-
* 0 => error; 1 => ok
106-
*/
107-
static int
108-
register_cursor(pysqlite_Connection *connection, PyObject *cursor)
109-
{
110-
PyObject *weakref = PyWeakref_NewRef((PyObject *)cursor, NULL);
111-
if (weakref == NULL) {
112-
return 0;
113-
}
114-
115-
if (PyList_Append(connection->cursors, weakref) < 0) {
116-
Py_CLEAR(weakref);
117-
return 0;
118-
}
119-
120-
Py_DECREF(weakref);
121-
return 1;
122-
}
123-
124102
/*[clinic input]
125103
_sqlite3.Cursor.__init__ as pysqlite_cursor_init
126104
@@ -160,10 +138,6 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self,
160138
return -1;
161139
}
162140

163-
if (!register_cursor(connection, (PyObject *)self)) {
164-
return -1;
165-
}
166-
167141
self->initialized = 1;
168142

169143
return 0;

0 commit comments

Comments
 (0)