Merged revisions 78563 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r78563 | florent.xicluna | 2010-03-01 21:45:01 +0100 (lun, 01 mar 2010) | 2 lines

  #7808: Fix reference leaks in _bsddb and related tests.
........
This commit is contained in:
Florent Xicluna 2010-03-01 21:08:21 +00:00
parent 4c0e894e69
commit 75f82fdb7a
4 changed files with 19 additions and 3 deletions

View File

@ -193,6 +193,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
errorOut = temp.getvalue() errorOut = temp.getvalue()
if not successRe.search(errorOut): if not successRe.search(errorOut):
self.fail("unexpected stderr output:\n"+errorOut) self.fail("unexpected stderr output:\n"+errorOut)
sys.exc_traceback = sys.last_traceback = None
def _test_compare_function_exception (self): def _test_compare_function_exception (self):
self.startTest () self.startTest ()

View File

@ -4,6 +4,7 @@
import os import os
import time import time
import unittest import unittest
import weakref
from test_all import db, test_support, have_threads, verbose, \ from test_all import db, test_support, have_threads, verbose, \
get_new_environment_path, get_new_database_path get_new_environment_path, get_new_database_path
@ -34,13 +35,16 @@ class DBReplicationManager(unittest.TestCase):
| db.DB_INIT_LOG | db.DB_INIT_MPOOL | db.DB_INIT_LOCK | | db.DB_INIT_LOG | db.DB_INIT_MPOOL | db.DB_INIT_LOCK |
db.DB_INIT_REP | db.DB_RECOVER | db.DB_THREAD, 0666) db.DB_INIT_REP | db.DB_RECOVER | db.DB_THREAD, 0666)
wr = weakref.ref(self)
self.confirmed_master=self.client_startupdone=False self.confirmed_master=self.client_startupdone=False
def confirmed_master(a,b,c) : def confirmed_master(a,b,c) :
if b==db.DB_EVENT_REP_MASTER : if b==db.DB_EVENT_REP_MASTER :
self = wr()
self.confirmed_master=True self.confirmed_master=True
def client_startupdone(a,b,c) : def client_startupdone(a,b,c) :
if b==db.DB_EVENT_REP_STARTUPDONE : if b==db.DB_EVENT_REP_STARTUPDONE :
self = wr()
self.client_startupdone=True self.client_startupdone=True
self.dbenvMaster.set_event_notify(confirmed_master) self.dbenvMaster.set_event_notify(confirmed_master)
@ -215,12 +219,15 @@ class DBReplicationManager(unittest.TestCase):
class DBBaseReplication(DBReplicationManager): class DBBaseReplication(DBReplicationManager):
def setUp(self) : def setUp(self) :
DBReplicationManager.setUp(self) DBReplicationManager.setUp(self)
wr = weakref.ref(self)
def confirmed_master(a,b,c) : def confirmed_master(a,b,c) :
if (b == db.DB_EVENT_REP_MASTER) or (b == db.DB_EVENT_REP_ELECTED) : if (b == db.DB_EVENT_REP_MASTER) or (b == db.DB_EVENT_REP_ELECTED) :
self = wr()
self.confirmed_master = True self.confirmed_master = True
def client_startupdone(a,b,c) : def client_startupdone(a,b,c) :
if b == db.DB_EVENT_REP_STARTUPDONE : if b == db.DB_EVENT_REP_STARTUPDONE :
self = wr()
self.client_startupdone = True self.client_startupdone = True
self.dbenvMaster.set_event_notify(confirmed_master) self.dbenvMaster.set_event_notify(confirmed_master)
@ -233,9 +240,11 @@ class DBBaseReplication(DBReplicationManager):
# There are only two nodes, so we don't need to # There are only two nodes, so we don't need to
# do any routing decision # do any routing decision
def m2c(dbenv, control, rec, lsnp, envid, flags) : def m2c(dbenv, control, rec, lsnp, envid, flags) :
self = wr()
self.m2c.put((control, rec)) self.m2c.put((control, rec))
def c2m(dbenv, control, rec, lsnp, envid, flags) : def c2m(dbenv, control, rec, lsnp, envid, flags) :
self = wr()
self.c2m.put((control, rec)) self.c2m.put((control, rec))
self.dbenvMaster.rep_set_transport(13,m2c) self.dbenvMaster.rep_set_transport(13,m2c)
@ -252,10 +261,12 @@ class DBBaseReplication(DBReplicationManager):
#self.dbenvClient.set_verbose(db.DB_VERB_FILEOPS_ALL, True) #self.dbenvClient.set_verbose(db.DB_VERB_FILEOPS_ALL, True)
def thread_master() : def thread_master() :
self = wr()
return self.thread_do(self.dbenvMaster, self.c2m, 3, return self.thread_do(self.dbenvMaster, self.c2m, 3,
self.master_doing_election, True) self.master_doing_election, True)
def thread_client() : def thread_client() :
self = wr()
return self.thread_do(self.dbenvClient, self.m2c, 13, return self.thread_do(self.dbenvClient, self.m2c, 13,
self.client_doing_election, False) self.client_doing_election, False)
@ -408,6 +419,7 @@ class DBBaseReplication(DBReplicationManager):
break break
except db.DBRepUnavailError : except db.DBRepUnavailError :
pass pass
if not election_status[0] and not self.confirmed_master : if not election_status[0] and not self.confirmed_master :
from threading import Thread from threading import Thread
election_status[0] = True election_status[0] = True

View File

@ -241,6 +241,8 @@ Library
Extension Modules Extension Modules
----------------- -----------------
- Issue #7808: Fix reference leaks in _bsddb and related tests.
- Stop providing crtassem.h symbols when compiling with Visual Studio 2010, as - Stop providing crtassem.h symbols when compiling with Visual Studio 2010, as
msvcr100.dll is not a platform assembly anymore. msvcr100.dll is not a platform assembly anymore.

View File

@ -2382,8 +2382,6 @@ _db_compareCallback(DB* db,
args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size); args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
if (args != NULL) { if (args != NULL) {
/* XXX(twouters) I highly doubt this INCREF is correct */
Py_INCREF(self);
result = PyEval_CallObject(self->btCompareCallback, args); result = PyEval_CallObject(self->btCompareCallback, args);
} }
if (args == NULL || result == NULL) { if (args == NULL || result == NULL) {
@ -2432,10 +2430,12 @@ DB_set_bt_compare(DBObject* self, PyObject* comparator)
if (result == NULL) if (result == NULL)
return NULL; return NULL;
if (!NUMBER_Check(result)) { if (!NUMBER_Check(result)) {
Py_DECREF(result);
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"callback MUST return an int"); "callback MUST return an int");
return NULL; return NULL;
} else if (NUMBER_AsLong(result) != 0) { } else if (NUMBER_AsLong(result) != 0) {
Py_DECREF(result);
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"callback failed to return 0 on two empty strings"); "callback failed to return 0 on two empty strings");
return NULL; return NULL;
@ -5776,6 +5776,8 @@ DBEnv_repmgr_site_list(DBEnvObject* self)
free(listp); free(listp);
return NULL; return NULL;
} }
Py_DECREF(key);
Py_DECREF(tuple);
} }
free(listp); free(listp);
return stats; return stats;
@ -7578,4 +7580,3 @@ PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
return PyInit__bsddb(); /* Note the two underscores */ return PyInit__bsddb(); /* Note the two underscores */
#endif #endif
} }