Index: boost/python/call.hpp
===================================================================
--- boost/python/call.hpp	(revision 64058)
+++ boost/python/call.hpp	(working copy)
@@ -59,12 +59,15 @@
     , boost::type<R>* = 0
     )
 {
+	PyGILState_STATE gstate;
+	gstate = PyGILState_Ensure();
     PyObject* const result = 
         PyEval_CallFunction(
             callable
             , const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
             BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil)
             );
+	PyGILState_Release( gstate );
     
     // This conversion *must not* be done in the same expression as
     // the call, because, in the special case where the result is a
Index: boost/python/detail/invoke.hpp
===================================================================
--- boost/python/detail/invoke.hpp	(revision 64058)
+++ boost/python/detail/invoke.hpp	(working copy)
@@ -20,6 +20,14 @@
 #  include <boost/preprocessor/repetition/enum_binary_params.hpp>
 #  include <boost/python/to_python_value.hpp>
 
+#include <boost/call_traits.hpp>
+// Predeclaration of py_iter_
+namespace boost { namespace python { namespace objects { 
+	template <class NextPolicies, class Iterator> struct iterator_range;
+	namespace detail {
+		template<class Target, class Iterator, class Accessor1, class Accessor2, class NextPolicies> struct py_iter_;
+}}}}
+
 // This file declares a series of overloaded invoke(...)  functions,
 // used to invoke wrapped C++ function (object)s from Python. Each one
 // accepts:
@@ -44,6 +52,7 @@
 // invoke(...), selecting the appropriate implementation
 typedef int void_result_to_python;
 
+// ned 23rd Oct 2003: invoke modifications based on those of Lijun Qin, thanks to him!
 template <bool void_return, bool member>
 struct invoke_tag_ {};
 
@@ -58,6 +67,66 @@
 {
 };
 
+// Predeclaration of member && datum
+template<class Data, class Class> struct member;
+template <class Data> struct datum;
+
+// Predeclaration of return extractor
+template<class F> struct ReturnExtract;
+// Specialisation for member data & datum data
+template<class Data, class Class> struct ReturnExtract<boost::python::detail::member<Data, Class> >
+{
+	typedef Data value;
+	enum { GIL=true };
+};
+template<class Data> struct ReturnExtract<boost::python::detail::datum<Data> >
+{
+	typedef Data value;
+	enum { GIL=true };
+};
+// Specialisation for iterators
+template<class Target, class Iterator, class Accessor1, class Accessor2, class NextPolicies>
+struct ReturnExtract<boost::python::objects::detail::py_iter_<Target, Iterator, Accessor1, Accessor2, NextPolicies> >
+{
+	typedef boost::python::objects::iterator_range<NextPolicies, Iterator> value;
+	enum { GIL=false };
+};
+// Fix for boost::python::objects::iterator_range<>::next (no other way of doing it :( )
+template <class T> struct ReturnExtract
+{
+	typedef typename T::result_type value;
+	enum { GIL=false };
+};
+
+// Placeholder for DoCPP when it's disabled
+struct EnterCPP
+{
+	void undo() {}
+};
+
+struct GIL_EnterCPP
+{
+	GIL_EnterCPP()
+	{	
+		// Release the GIL lock
+		_save = PyEval_SaveThread();
+	}
+
+	void undo()
+	{
+		PyEval_RestoreThread(_save);
+		_save = NULL;
+	}
+
+	~GIL_EnterCPP()
+	{
+		if( _save )
+			undo();
+	}
+
+	PyThreadState *_save;
+};
+
 #  define BOOST_PP_ITERATION_PARAMS_1                                            \
         (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/invoke.hpp>))
 #  include BOOST_PP_ITERATE()
@@ -69,29 +138,84 @@
 
 # define N BOOST_PP_ITERATION()
 
+#define CONVERT_ARG(z, n, _) typename boost::call_traits<typename AC##n::result_type>::param_type a##n = ac##n();
+
+template<typename R, typename O BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
+struct ReturnExtract<R (O::*)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, AC, ac) )>
+{
+	typedef R value;
+	enum { GIL=true };
+};
+
+template<typename R, typename O BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
+struct ReturnExtract<R (O::*)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, AC, ac) ) const>
+{
+	typedef R value;
+	enum { GIL=true };
+};
+
+template<typename R BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
+struct ReturnExtract<R (*)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, AC, ac) )>
+{
+	typedef R value;
+	enum { GIL=true };
+};
+
 template <class RC, class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
 inline PyObject* invoke(invoke_tag_<false,false>, RC const& rc, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
 {
-    return rc(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ));
+	BOOST_PP_REPEAT(N, CONVERT_ARG,	nil)
+	typedef ReturnExtract<F> RetExt;
+	typedef typename RetExt::value rettype;
+
+	typename boost::mpl::if_c<RetExt::GIL, GIL_EnterCPP, EnterCPP>::type cpphold;		// Releases the Python GIL
+	rettype ret=f(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, a, BOOST_PP_INTERCEPT));
+	cpphold.undo();
+
+	return rc(ret);
+    //return rc(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ));
 }
                  
 template <class RC, class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
 inline PyObject* invoke(invoke_tag_<true,false>, RC const&, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
 {
-    f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) );
+	BOOST_PP_REPEAT(N, CONVERT_ARG,	nil)
+
+	GIL_EnterCPP cpphold;		// Releases the Python GIL
+	f(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, a, BOOST_PP_INTERCEPT));
+	cpphold.undo();
+
+    //f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) );
     return none();
 }
 
 template <class RC, class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
 inline PyObject* invoke(invoke_tag_<false,true>, RC const& rc, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
 {
-    return rc( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) );
+	BOOST_PP_REPEAT(N, CONVERT_ARG,	nil)
+	typename TC::result_type c=tc();
+	typedef ReturnExtract<F> RetExt;
+	typedef typename RetExt::value rettype;
+
+	typename boost::mpl::if_c<RetExt::GIL, GIL_EnterCPP, EnterCPP>::type cpphold;		// Releases the Python GIL
+	rettype ret=(c.*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, a, BOOST_PP_INTERCEPT));
+	cpphold.undo();
+
+	return rc(ret);
+    //return rc( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) );
 }
                  
 template <class RC, class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
 inline PyObject* invoke(invoke_tag_<true,true>, RC const&, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
 {
-    (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT));
+	BOOST_PP_REPEAT(N, CONVERT_ARG,	nil)
+	typename TC::result_type c=tc();
+
+	GIL_EnterCPP cpphold;		// Releases the Python GIL
+	(c.*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, a, BOOST_PP_INTERCEPT));
+	cpphold.undo();
+
+    //(tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT));
     return none();
 }
 
Index: boost/python/override.hpp
===================================================================
--- boost/python/override.hpp	(revision 64058)
+++ boost/python/override.hpp	(working copy)
@@ -27,6 +27,31 @@
 
 namespace detail
 {
+	struct GIL_ExitCPP
+	{
+		GIL_ExitCPP()
+		{	
+			// Release the GIL lock
+			_gstate = PyGILState_Ensure();
+			_isReleased = false;
+		}
+
+		void undo()
+		{
+			PyGILState_Release(_gstate);
+			_isReleased = true;
+		}
+
+		~GIL_ExitCPP()
+		{
+			if( !_isReleased )
+				undo();
+		}
+
+		bool _isReleased;
+		PyGILState_STATE _gstate;
+	};
+
   class wrapper_base;
   
   // The result of calling a method.
@@ -90,19 +115,27 @@
     friend class detail::wrapper_base;
     override(handle<> x)
       : object(x)
-    {}
-    
+    {
+    }
  public:
+    override(const override &o) : object(o)
+    {
+    }
     detail::method_result
     operator()() const
     {
+		detail::GIL_ExitCPP holdgil;
         detail::method_result x(
             PyEval_CallFunction(
                 this->ptr()
               , const_cast<char*>("()")
             ));
+		holdgil.undo();
         return x;
     }
+    ~override()
+    {
+    }
 
 # define BOOST_PYTHON_fast_arg_to_python_get(z, n, _)   \
     , converter::arg_to_python<A##n>(a##n).get()
@@ -131,12 +164,14 @@
 detail::method_result
 operator()( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a) ) const
 {
+	detail::GIL_ExitCPP holdgil;
     detail::method_result x(
         PyEval_CallFunction(
             this->ptr()
           , const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
             BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_fast_arg_to_python_get, nil)
         ));
+	holdgil.undo();
     return x;
 }
 
Index: boost/python/object_core.hpp
===================================================================
--- boost/python/object_core.hpp	(revision 64058)
+++ boost/python/object_core.hpp	(working copy)
@@ -523,7 +523,16 @@
 
 inline api::object_base::~object_base()
 {
-    Py_DECREF(m_ptr);
+	if( m_ptr->ob_refcnt == 1 )
+	{
+		PyGILState_STATE state = PyGILState_Ensure();
+    		Py_DECREF(m_ptr);
+		PyGILState_Release( state );
+	}
+	else
+	{
+		Py_DECREF(m_ptr);
+	}
 }
 
 inline object::object(detail::borrowed_reference p)
Index: libs/python/src/wrapper.cpp
===================================================================
--- libs/python/src/wrapper.cpp	(revision 64058)
+++ libs/python/src/wrapper.cpp	(working copy)
@@ -15,6 +15,7 @@
   {
       if (this->m_self)
       {
+		  detail::GIL_ExitCPP holdgil;
           if (handle<> m = handle<>(
                   python::allow_null(
                       ::PyObject_GetAttrString(
@@ -35,8 +36,12 @@
 
               }
               if (borrowed_f != ((PyMethodObject*)m.get())->im_func)
+			  {
+				  holdgil.undo();
                   return override(m);
+			  }
           }
+		  holdgil.undo();
       }
       return override(handle<>(detail::none()));
   }
