mirror of
https://github.com/PyMySQL/mysqlclient.git
synced 2025-08-15 19:31:54 +08:00
Kill bastardly refcount bug that occurs starting with Python 2.0.1.
PyArgs_ParseTupleAndKeywords() returns borrowed references for O format starting in 2.0.1, prior to that it returns new references, so it's necessary to test the Python version to determine whether or not we should Py_INCREF() it. If we always Py_INCREF() it, this produces a memory leak in versions prior to 2.0.1.
This commit is contained in:
@ -159,26 +159,20 @@ _mysql_ResultObject_New(
|
|||||||
int n, i;
|
int n, i;
|
||||||
MYSQL_FIELD *fields;
|
MYSQL_FIELD *fields;
|
||||||
_mysql_ResultObject *r;
|
_mysql_ResultObject *r;
|
||||||
if (!(r = PyObject_NEW(_mysql_ResultObject, &_mysql_ResultObject_Type)))
|
|
||||||
return NULL;
|
r = PyObject_NEW(_mysql_ResultObject, &_mysql_ResultObject_Type);
|
||||||
|
if (!r) return NULL;
|
||||||
r->conn = (PyObject *) conn;
|
r->conn = (PyObject *) conn;
|
||||||
r->converter = NULL;
|
|
||||||
r->use = use;
|
r->use = use;
|
||||||
Py_INCREF(conn);
|
|
||||||
Py_INCREF(conv);
|
|
||||||
r->result = result;
|
r->result = result;
|
||||||
n = mysql_num_fields(result);
|
n = mysql_num_fields(result);
|
||||||
r->nfields = n;
|
r->nfields = n;
|
||||||
if (n) {
|
if (!(r->converter = PyTuple_New(n))) goto error;
|
||||||
if (!(r->converter = PyTuple_New(n))) {
|
|
||||||
Py_DECREF(conv);
|
|
||||||
Py_DECREF(conn);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
fields = mysql_fetch_fields(result);
|
fields = mysql_fetch_fields(result);
|
||||||
for (i=0; i<n; i++) {
|
for (i=0; i<n; i++) {
|
||||||
PyObject *tmp, *fun;
|
PyObject *tmp, *fun;
|
||||||
tmp = PyInt_FromLong((long) fields[i].type);
|
tmp = PyInt_FromLong((long) fields[i].type);
|
||||||
|
if (!tmp) goto error;
|
||||||
fun = PyObject_GetItem(conv, tmp);
|
fun = PyObject_GetItem(conv, tmp);
|
||||||
Py_DECREF(tmp);
|
Py_DECREF(tmp);
|
||||||
if (!fun) {
|
if (!fun) {
|
||||||
@ -188,9 +182,11 @@ _mysql_ResultObject_New(
|
|||||||
}
|
}
|
||||||
PyTuple_SET_ITEM(r->converter, i, fun);
|
PyTuple_SET_ITEM(r->converter, i, fun);
|
||||||
}
|
}
|
||||||
}
|
Py_INCREF(conn);
|
||||||
Py_DECREF(conv);
|
|
||||||
return r;
|
return r;
|
||||||
|
error:
|
||||||
|
Py_DECREF(r);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char _mysql_connect__doc__[] =
|
static char _mysql_connect__doc__[] =
|
||||||
@ -252,14 +248,21 @@ _mysql_connect(
|
|||||||
&init_command, &read_default_file,
|
&init_command, &read_default_file,
|
||||||
&read_default_group))
|
&read_default_group))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (conv) {
|
|
||||||
|
if (!conv)
|
||||||
|
conv = PyDict_New();
|
||||||
|
#if PY_VERSION_HEX > 0x02000100
|
||||||
|
else
|
||||||
|
Py_INCREF(conv);
|
||||||
|
#endif
|
||||||
c->converter = conv;
|
c->converter = conv;
|
||||||
} else {
|
if (!(c->converter)) {
|
||||||
if (!(c->converter = PyDict_New())) {
|
|
||||||
Py_DECREF(c);
|
Py_DECREF(c);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
printf("<%d> ", c->ob_refcnt);
|
||||||
|
c->open = 0;
|
||||||
Py_BEGIN_ALLOW_THREADS ;
|
Py_BEGIN_ALLOW_THREADS ;
|
||||||
conn = mysql_init(&(c->connection));
|
conn = mysql_init(&(c->connection));
|
||||||
if (connect_timeout) {
|
if (connect_timeout) {
|
||||||
@ -282,13 +285,13 @@ _mysql_connect(
|
|||||||
conn = mysql_real_connect(&(c->connection), host, user, passwd, db,
|
conn = mysql_real_connect(&(c->connection), host, user, passwd, db,
|
||||||
port, unix_socket, client_flag);
|
port, unix_socket, client_flag);
|
||||||
Py_END_ALLOW_THREADS ;
|
Py_END_ALLOW_THREADS ;
|
||||||
c->open = 1;
|
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
_mysql_Exception(c);
|
_mysql_Exception(c);
|
||||||
c->open = 0;
|
|
||||||
Py_DECREF(c);
|
Py_DECREF(c);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
c->open = 1;
|
||||||
return (PyObject *) c;
|
return (PyObject *) c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1161,7 +1164,6 @@ _mysql_ConnectionObject_dealloc(
|
|||||||
o = _mysql_ConnectionObject_close(self, NULL);
|
o = _mysql_ConnectionObject_close(self, NULL);
|
||||||
Py_XDECREF(o);
|
Py_XDECREF(o);
|
||||||
}
|
}
|
||||||
Py_XDECREF(self->converter);
|
|
||||||
PyMem_Free((char *) self);
|
PyMem_Free((char *) self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1232,7 +1234,7 @@ _mysql_ResultObject_dealloc(
|
|||||||
{
|
{
|
||||||
mysql_free_result(self->result);
|
mysql_free_result(self->result);
|
||||||
Py_DECREF(self->conn);
|
Py_DECREF(self->conn);
|
||||||
Py_DECREF(self->converter);
|
Py_XDECREF(self->converter);
|
||||||
PyMem_Free((char *) self);
|
PyMem_Free((char *) self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user