#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
#include "pycore_unicodeobject.h" // _PyUnicode_AsUTF8NoNUL
-#include "pycore_weakref.h"
#include <stdbool.h>
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=67369db2faf80891]*/
-static int _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self);
static void incref_callback_context(callback_context *ctx);
static void decref_callback_context(callback_context *ctx);
static void set_callback_context(callback_context **ctx_pp,
goto error;
}
- /* Create lists of weak references to cursors and blobs */
- PyObject *cursors = PyList_New(0);
- if (cursors == NULL) {
- Py_DECREF(statement_cache);
- goto error;
- }
-
+ /* Create lists of weak references to blobs */
PyObject *blobs = PyList_New(0);
if (blobs == NULL) {
Py_DECREF(statement_cache);
- Py_DECREF(cursors);
goto error;
}
self->check_same_thread = check_same_thread;
self->thread_ident = PyThread_get_thread_ident();
self->statement_cache = statement_cache;
- self->cursors = cursors;
self->blobs = blobs;
- self->created_cursors = 0;
self->row_factory = Py_NewRef(Py_None);
self->text_factory = Py_NewRef(&PyUnicode_Type);
self->trace_ctx = NULL;
pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->statement_cache);
- Py_VISIT(self->cursors);
Py_VISIT(self->blobs);
Py_VISIT(self->row_factory);
Py_VISIT(self->text_factory);
{
pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
Py_CLEAR(self->statement_cache);
- Py_CLEAR(self->cursors);
Py_CLEAR(self->blobs);
Py_CLEAR(self->row_factory);
Py_CLEAR(self->text_factory);
return NULL;
}
- if (_pysqlite_drop_unused_cursor_references(self) < 0) {
- Py_DECREF(cursor);
- return NULL;
- }
-
if (cursor && self->row_factory != Py_None) {
Py_INCREF(self->row_factory);
Py_XSETREF(((pysqlite_Cursor *)cursor)->row_factory, self->row_factory);
PyGILState_Release(threadstate);
}
-static int
-_pysqlite_drop_unused_cursor_references(pysqlite_Connection* self)
-{
- /* we only need to do this once in a while */
- if (self->created_cursors++ < 200) {
- return 0;
- }
-
- self->created_cursors = 0;
-
- PyObject* new_list = PyList_New(0);
- if (!new_list) {
- return -1;
- }
-
- assert(PyList_CheckExact(self->cursors));
- Py_ssize_t imax = PyList_GET_SIZE(self->cursors);
- for (Py_ssize_t i = 0; i < imax; i++) {
- PyObject* weakref = PyList_GET_ITEM(self->cursors, i);
- if (_PyWeakref_IsDead(weakref)) {
- continue;
- }
- if (PyList_Append(new_list, weakref) != 0) {
- Py_DECREF(new_list);
- return -1;
- }
- }
-
- Py_SETREF(self->cursors, new_list);
- return 0;
-}
-
/* Allocate a UDF/callback context structure. In order to ensure that the state
* pointer always outlives the callback context, we make sure it owns a
* reference to the module itself. create_callback_context() is always called