[Python-Dev] New thread death in test_bsddb3

Tim Peters tim@zope.com
Tue, 22 Apr 2003 11:36:24 -0400


test_bsddb3.py fails quickly today under a debug build, with a thread state
error, on Win2K, every time.  Linux?

I assume this is a bad interaction between Mark Hammond's new
auto-thread-state code and _bsddb.c's custom thread-manipulation macros:


C:\Code\python\PCbuild>python_d ../lib/test/test_bsddb3.py
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Sleepycat Software: Berkeley DB 4.1.25: (December 19, 2002)
bsddb.db.version():   (4, 1, 25)
bsddb.db.__version__: 4.1.5
bsddb.db.cvsid:       $Id: _bsddb.c,v 1.11 2003/03/31 19:51:29 bwarsaw Exp $
python version:        2.3a2+ (#39, Apr 22 2003, 10:48:23) [MSC v.1200 32
bit (I
ntel)]
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Fatal Python error: Invalid thread state for this thread

C:\Code\python\PCbuild>


It's dying in _db_associateCallback, here:

static int
_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
                      DBT* secKey)
{
    int       retval = DB_DONOTINDEX;
    DBObject* secondaryDB = (DBObject*)db->app_private;
    PyObject* callback = secondaryDB->associateCallback;
    int       type = secondaryDB->primaryDBType;
    PyObject* key;
    PyObject* data;
    PyObject* args;
    PyObject* result;


    if (callback != NULL) {
        MYDB_BEGIN_BLOCK_THREADS;   ************ HERE *************




The macro is defined like so:

#define MYDB_BEGIN_BLOCK_THREADS {                              \
        PyThreadState* prevState;                               \
        PyThreadState* newState;                                \
        PyEval_AcquireLock();                                   \
        newState  = PyThreadState_New(_db_interpreterState);    \
        prevState = PyThreadState_Swap(newState);





PyThreadState_Swap is complaining here:

#if defined(Py_DEBUG)
	if (new) {
		PyThreadState *check = PyGILState_GetThisThreadState();
		if (check && check != new)
			Py_FatalError("Invalid thread state for this thread");
	}
#endif




This is a new check, I believe it's an intentional check, and I doubt
_bsddb.c *should* pass it as-is.