Ticket #364: python-multiinterpreter-locking.patch

File python-multiinterpreter-locking.patch, 3.2 KB (added by Olly Betts, 13 years ago)

Patch to implement locking using the "full" thread API

  • xapian-bindings/python/python.i

    diff --git a/xapian-bindings/python/python.i b/xapian-bindings/python/python.i
    index 316c036..d87b0a5 100644
    a b  
    2828 * overhead of thread locking when the user's code isn't using threads. */
    2929#define SWIG_PYTHON_NO_USE_GIL
    3030
    31        class XapianSWIG_Python_Thread_Block {
    32          bool status;
    33          PyGILState_STATE state;
    34        public:
    35          void end() { if (status) { PyGILState_Release(state); status = false;} }
    36          XapianSWIG_Python_Thread_Block() : status(PyEval_ThreadsInitialized()) { if (status) state = PyGILState_Ensure(); }
    37          ~XapianSWIG_Python_Thread_Block() { end(); }
    38        };
    39        class XapianSWIG_Python_Thread_Allow {
    40          bool status;
    41          PyThreadState *save;
    42        public:
    43          void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
    44          XapianSWIG_Python_Thread_Allow() : status(PyEval_ThreadsInitialized()) { if (status) save = PyEval_SaveThread(); }
    45          ~XapianSWIG_Python_Thread_Allow() { end(); }
    46        };
     31static __thread PyThreadState * swig_pythreadstate = NULL;
     32
     33class XapianSWIG_Python_Thread_Block {
     34    bool status;
     35  public:
     36    XapianSWIG_Python_Thread_Block()
     37        : status(PyEval_ThreadsInitialized() && swig_pythreadstate) {
     38        if (status) {
     39            PyEval_RestoreThread(swig_pythreadstate);
     40            swig_pythreadstate = NULL;
     41        }
     42    }
     43    void end() {
     44        if (status) {
     45            if (swig_pythreadstate) Py_FatalError("swig_pythreadstate set in XapianSWIG_Python_Thread_Block::end()");
     46            swig_pythreadstate = PyEval_SaveThread();
     47            status = false;
     48        }
     49    }
     50    ~XapianSWIG_Python_Thread_Block() { end(); }
     51};
     52
     53class XapianSWIG_Python_Thread_Allow {
     54    bool status;
     55  public:
     56    XapianSWIG_Python_Thread_Allow() : status(PyEval_ThreadsInitialized()) {
     57        if (status) {
     58            if (swig_pythreadstate) Py_FatalError("swig_pythreadstate set in XapianSWIG_Python_Thread_Allow ctor");
     59            swig_pythreadstate = PyEval_SaveThread();
     60        }
     61    }
     62    void end() {
     63        if (status) {
     64            if (!swig_pythreadstate) Py_FatalError("swig_pythreadstate unset in XapianSWIG_Python_Thread_Block::end()");
     65            PyEval_RestoreThread(swig_pythreadstate);
     66            swig_pythreadstate = NULL;
     67            status = false;
     68        }
     69    }
     70    ~XapianSWIG_Python_Thread_Allow() { end(); }
     71};
    4772
    4873#define SWIG_PYTHON_THREAD_BEGIN_BLOCK   XapianSWIG_Python_Thread_Block _xapian_swig_thread_block
    4974#define SWIG_PYTHON_THREAD_END_BLOCK     _xapian_swig_thread_block.end()
  • xapian-bindings/python/pythontest2.py

    diff --git a/xapian-bindings/python/pythontest2.py b/xapian-bindings/python/pythontest2.py
    index 64a722c..cdd5eb6 100644
    a b  
    1919# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
    2020# USA
    2121
     22import thread
    2223import gc
    2324import os
    2425import random
    def test_removed_features():  
    16281629    check_missing(titer, 'positionlist_end')
    16291630
    16301631# Run all tests (ie, callables with names starting "test_").
    1631 if not runtests(globals(), sys.argv[1:]):
    1632     sys.exit(1)
     1632def f():
     1633    if not runtests(globals(), sys.argv[1:]):
     1634        sys.exit(1)
     1635
     1636thread.start_new_thread(f, ())
     1637os.system("sleep 1")
    16331638
    16341639# vim:syntax=python:set expandtab: