Also fixes li_std_vector_enum testcase when run with -threads.
Patch supplied on swig-devel mailing list on 12 Sep with details...
==============================================
I just wanted to mention that I found a crash issue in bug..
I am using SWIG 2.0.11 with python and have –threads enabled. I have a C++ std::vector that I instantiate in SWIG with %template. I also have a method in a class that returns this vector. I also include std_vector.i, btw..
When I iterate like so:
children = Action.getActionList()
for child in children:
pass
Everything is fine..
When I iterate like this:
for child in Action.getActionList()
pass
Product crashes.
The problem is the following. This code gets called first:
SWIGINTERN PyObject *_wrap_delete_SwigPyIterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
if(!PyArg_UnpackTuple(args,(char *)"delete_SwigPyIterator",1,1,&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SwigPyIterator" "', argument " "1"" of type '" "swig::SwigPyIterator *""'");
}
arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
{
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
delete arg1;
SWIG_PYTHON_THREAD_END_ALLOW;
}
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
Note the SWIG_PYTHON_THREAD_BEGIN_ALLOW/END_ALLOW. In between those two statements, we delete arg1. That in turn will eventually end up in this code:
namespace swig {
class SwigPtr_PyObject {
protected:
PyObject *_obj;
public:
… snip! …
~SwigPtr_PyObject()
{
Py_XDECREF(_obj);
}
Uh-oh! We call Py_XDECREF when we aren’t supposed to because we are in a SWIG_PYTHON_THREAD_BEGIN_ALLOW/END_ALLOW section!
This takes care of the issue:
namespace swig {
class SwigPtr_PyObject {
protected:
PyObject *_obj;
public:
… snip! …
~SwigPtr_PyObject()
{
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
Py_XDECREF(_obj);
SWIG_PYTHON_THREAD_END_BLOCK;
}
There are several other methods in this class that use the Python API, but don’t have the BEGIN/END block defined. I’m not sure if they are required for all of them, but I believe they are..
I have attached a modified pyclasses.swg with what I believe are the correct changes. This code is from 2.0.11, but as far as I can tell, it’s the same as what is in 3.0.2…
Apologies for not doing more here (making/running tests, getting it in the code repository, etc..), but I’m under some pressure to get some unrelated things done…
/* -----------------------------------------------------------------------------
*
* User interfaces: include these ones as needed
*
* ----------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* Special types and user helpers
* ----------------------------------------------------------------------------- */
argcargv.i Handler for (int argc, char **argv)
attribute.i Convert a pair of set/get methods into a "native" python attribute
ccomplex.i C99 complex type
complex.i C99 or C++ complex type
cstring.i Various forms of C character string handling
cwstring.i Various forms of C wchar_t string handling
embed.i embedding the Python interpreter in something else
embed15.i embedding the Python interpreter in something else
file.i FILE C type
implicit.i Allow the use of implicit C++ constructors
wchar.i wchar_t C type
/* -----------------------------------------------------------------------------
* C++ STD + STL
* ----------------------------------------------------------------------------- */
std_alloc.i allocator
std_basic_string.i basic string
std_char_traits.i char traits
std_complex.i complex
std_deque.i deque
std_except.i exceptions
std_ios.i ios
std_iostream.i istream/ostream
std_list.i list
std_map.i map
std_multimap.i multimap
std_multiset.i multiset
std_pair.i pair
std_set.i set
std_sstream.i string stream
std_streambuf.i streambuf
std_string.i string
std_vector.i vector
std_wios.i wios
std_wiostream.i wistream/wostream
std_wsstream.i wstring stream
std_wstreambuf.i wstreambuf
std_wstring.i wstring
/* -----------------------------------------------------------------------------
/*
* Implementation files: don't look at them unless you are really drunk
*
* ----------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* Basic files
* ----------------------------------------------------------------------------- */
python.swg Main language file, it just includes what is needed.
pyuserdir.swg User visible directives (%pythonnondynamic, etc)
pymacros.swg Internal macros used for typemaps
pyfragments.swg Allow the user to overload the default fragments
pyopers.swg Python operations (+=, *=, etc)
pythonkw.swg Python keywords and special names
pyinit.swg Python Init method
/* -----------------------------------------------------------------------------
* The runtime part
* ----------------------------------------------------------------------------- */
pyruntime.swg Main runtime file definition
pyapi.swg SWIG/Python API declarations
pyrun.swg Python run-time code
/* -----------------------------------------------------------------------------
* Internal typemap specializations
* ----------------------------------------------------------------------------- */
pyswigtype.swg SWIGTYPE
pystrings.swg Char strings (char *)
pywstrings.swg Wchar Strings (wchar_t *)
pyprimtypes.swg Primitive types (shot,int,double,etc)
pycomplex.swg PyComplex and helper for C/C++ complex types
pydocs.swg Typemaps documentation
/* -----------------------------------------------------------------------------
* C++ STD + STL
* ----------------------------------------------------------------------------- */
pycontainer.swg python container iterators
std_common.i general common code for the STD/STL implementation
std_container.i general common code for the STD/STL containers
/*-----------------------------------------------------------------------------
* Backward compatibility and deprecated
* ----------------------------------------------------------------------------- */
std_vectora.i vector + allocator (allocators are now supported in STD/STL)
typemaps.i old in/out typemaps (doesn't need to be included)
defarg.swg for processing default arguments with shadow classes