[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] Fix locking-related segfaults and deadlocks in the SWIG Python bindings

From: Max Bowsher <maxb_at_ukf.net>
Date: 2005-10-18 14:46:23 CEST

David James wrote:
> On 10/18/05, Marc Haesen <Marc.Haesen@telindus.be> wrote:
>>> This patch should fix the segfaults reported by Marc Haesen and Max
>>> Bowsher when using the Python bindings with ViewCVS in mod_python
>>> mode. I haven't tested this patch with mod_python yet, so please let
>>> me know if it helps.
...
>> If I apply this patch apache (with mod_python and python 2.4.2) is
>> crashing randomly (not only at shutdown/restart).
> Thanks for testing this, Marc! It looks like we'll need to look into
> this more closely then, since I don't have a debug setup for
> mod_python. Max?

Neither do I, but I use the following patch to make visible our attempts to
use PyEval_SaveThread/PyEval_RestoreThread other than in matched non-nested
pairs.

Max.

[[[
--- subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
(revision 16771)
+++ subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
(working copy)
@@ -71,13 +71,23 @@
 {
 #ifdef ACQUIRE_PYTHON_LOCK
   PyThreadState *thread_state;
+ void *saved_thread_state;

   if (_saved_thread_key == NULL) {
     /* Obviously, creating a top-level pool for this is pretty stupid. */
     apr_pool_create(&_saved_thread_pool, NULL);
     apr_threadkey_private_create(&_saved_thread_key, NULL,
_saved_thread_pool);
+ apr_threadkey_private_set(NULL, _saved_thread_key);
   }

+ apr_threadkey_private_get(&saved_thread_state, _saved_thread_key);
+ /* Do not double-release */
+ if (saved_thread_state)
+ {
+ fprintf(stderr, "WARNING!: Attempted to release PyGIL twice!\n");
+ return;
+ }
+
   thread_state = PyEval_SaveThread();
   apr_threadkey_private_set(thread_state, _saved_thread_key);
 #endif
@@ -86,11 +96,21 @@
 void svn_swig_py_acquire_py_lock(void)
 {
 #ifdef ACQUIRE_PYTHON_LOCK
- void *val;
   PyThreadState *thread_state;
- apr_threadkey_private_get(&val, _saved_thread_key);
- thread_state = val;
+ void *saved_thread_state;
+
+ apr_threadkey_private_get(&saved_thread_state, _saved_thread_key);
+ /* Do not double-acquire */
+ if (! saved_thread_state)
+ {
+ fprintf(stderr, "WARNING!: "
+ "Attempted to acquire PyGIL without a saved threadstate!\n");
+ return;
+ }
+
+ thread_state = saved_thread_state;
   PyEval_RestoreThread(thread_state);
+ apr_threadkey_private_set(NULL, _saved_thread_key);
 #endif
 }

]]]

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Oct 18 14:47:31 2005

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.