summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGregory P. Smith <greg@mad-scientist.com>2003-11-02 08:06:29 (GMT)
committerGregory P. Smith <greg@mad-scientist.com>2003-11-02 08:06:29 (GMT)
commite2767171133ead86ec3aacc205d1d8365a0a2d07 (patch)
tree8bbf6e6a28584dc14d3165ab23e1c8c71072fd1e
parent54a831bef74fc2213dc2a8467236a5f481957d5c (diff)
downloadcpython-e2767171133ead86ec3aacc205d1d8365a0a2d07.zip
cpython-e2767171133ead86ec3aacc205d1d8365a0a2d07.tar.gz
cpython-e2767171133ead86ec3aacc205d1d8365a0a2d07.tar.bz2
Fix a tuple memory leak when raising DB, DBEnv and DBCursor "object
has been closed" exceptions. Adds a DBCursorClosedError exception in the closed cursor case for future use in fixing the legacy bsddb interface deadlock problems due to its use of cursors with DB_INIT_LOCK | DB_THREAD support enabled.
-rw-r--r--Modules/_bsddb.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index e705526..6cf733f 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -148,6 +148,7 @@ static PyInterpreterState* _db_interpreterState = NULL;
/* Exceptions */
static PyObject* DBError; /* Base class, all others derive from this */
+static PyObject* DBCursorClosedError; /* raised when trying to use a closed cursor object */
static PyObject* DBKeyEmptyError; /* DB_KEYEMPTY */
static PyObject* DBKeyExistError; /* DB_KEYEXIST */
static PyObject* DBLockDeadlockError; /* DB_LOCK_DEADLOCK */
@@ -258,27 +259,23 @@ staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLoc
#define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
-#define CHECK_DB_NOT_CLOSED(dbobj) \
- if (dbobj->db == NULL) { \
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, \
- "DB object has been closed")); \
- return NULL; \
+#define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
+ if ((nonNull) == NULL) { \
+ PyObject *errTuple = NULL; \
+ errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
+ PyErr_SetObject((pyErrObj), errTuple); \
+ Py_DECREF(errTuple); \
+ return NULL; \
}
-#define CHECK_ENV_NOT_CLOSED(env) \
- if (env->db_env == NULL) { \
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, \
- "DBEnv object has been closed"));\
- return NULL; \
- }
+#define CHECK_DB_NOT_CLOSED(dbobj) \
+ _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
-#define CHECK_CURSOR_NOT_CLOSED(curs) \
- if (curs->dbc == NULL) { \
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, \
- "DBCursor object has been closed"));\
- return NULL; \
- }
+#define CHECK_ENV_NOT_CLOSED(env) \
+ _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
+#define CHECK_CURSOR_NOT_CLOSED(curs) \
+ _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
#define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
@@ -4717,6 +4714,7 @@ DL_EXPORT(void) init_bsddb(void)
#if !INCOMPLETE_IS_WARNING
MAKE_EX(DBIncompleteError);
#endif
+ MAKE_EX(DBCursorClosedError);
MAKE_EX(DBKeyEmptyError);
MAKE_EX(DBKeyExistError);
MAKE_EX(DBLockDeadlockError);