[Lxml-checkins] r38419 - lxml/trunk/src/lxml

scoder at codespeak.net scoder at codespeak.net
Sat Feb 10 22:35:17 CET 2007


Author: scoder
Date: Sat Feb 10 22:35:15 2007
New Revision: 38419

Added:
   lxml/trunk/src/lxml/config.pxd
Modified:
   lxml/trunk/src/lxml/etree.pyx
   lxml/trunk/src/lxml/etree_defs.h
   lxml/trunk/src/lxml/parser.pxi
   lxml/trunk/src/lxml/python.pxd
Log:
ported parser locking to pythread.h (instead of Python thread module)

Added: lxml/trunk/src/lxml/config.pxd
==============================================================================
--- (empty file)
+++ lxml/trunk/src/lxml/config.pxd	Sat Feb 10 22:35:15 2007
@@ -0,0 +1,2 @@
+cdef extern from "etree_defs.h":
+    cdef int ENABLE_THREADING

Modified: lxml/trunk/src/lxml/etree.pyx
==============================================================================
--- lxml/trunk/src/lxml/etree.pyx	(original)
+++ lxml/trunk/src/lxml/etree.pyx	Sat Feb 10 22:35:15 2007
@@ -1,4 +1,4 @@
-cimport tree, python
+cimport tree, python, config
 from tree cimport xmlDoc, xmlNode, xmlAttr, xmlNs, _isElement, _getNs
 from python cimport isinstance, issubclass, hasattr, getattr, callable
 from python cimport iter, repr, str, _cstr, _isString, Py_ssize_t
@@ -38,12 +38,6 @@
 cdef object re
 import re
 
-cdef object thread
-try:
-    import thread
-except ImportError:
-    pass
-
 cdef object ITER_EMPTY
 ITER_EMPTY = iter(())
 

Modified: lxml/trunk/src/lxml/etree_defs.h
==============================================================================
--- lxml/trunk/src/lxml/etree_defs.h	(original)
+++ lxml/trunk/src/lxml/etree_defs.h	Sat Feb 10 22:35:15 2007
@@ -28,6 +28,17 @@
   #define PyEval_RestoreThread(state)
   #define PyGILState_Ensure() (PyGILState_UNLOCKED)
   #define PyGILState_Release(state)
+
+  #define PyThread_allocate_lock() (NULL)
+  #define PyThread_free_lock(lock)
+  #define PyThread_acquire_lock(lock, mode) (1)
+  #define PyThread_release_lock(lock)
+#endif
+
+#ifdef WITHOUT_THREADING
+  #define ENABLE_THREADING 0
+#else
+  #define ENABLE_THREADING 1
 #endif
 
 /* libxml2 version specific setup */

Modified: lxml/trunk/src/lxml/parser.pxi
==============================================================================
--- lxml/trunk/src/lxml/parser.pxi	(original)
+++ lxml/trunk/src/lxml/parser.pxi	Sat Feb 10 22:35:15 2007
@@ -349,8 +349,7 @@
     cdef LxmlParserType _parser_type
     cdef xmlParserCtxt* _parser_ctxt
     cdef ElementClassLookup _class_lookup
-    cdef object _lockParser
-    cdef object _unlockParser
+    cdef python.PyThread_type_lock _parser_lock
 
     def __init__(self, context_class=_ResolverContext):
         cdef xmlParserCtxt* pctxt
@@ -371,14 +370,12 @@
         if pctxt.sax != NULL:
             # hard switch-off for CDATA nodes => makes them plain text
             pctxt.sax.cdataBlock = NULL
-        if thread is None or self._parser_type == LXML_ITERPARSE_PARSER:
+        if not config.ENABLE_THREADING or \
+               self._parser_type == LXML_ITERPARSE_PARSER:
             # no threading
-            self._lockParser   = self.__dummy
-            self._unlockParser = self.__dummy
+            self._parser_lock = NULL
         else:
-            lock = thread.allocate_lock()
-            self._lockParser   = lock.acquire
-            self._unlockParser = lock.release
+            self._parser_lock = python.PyThread_allocate_lock()
         self._error_log = _ErrorLog()
         self.resolvers  = _ResolverRegistry()
         self._context = context_class(self.resolvers)
@@ -387,6 +384,8 @@
     def __dealloc__(self):
         if self._parser_ctxt is not NULL:
             xmlparser.xmlFreeParserCtxt(self._parser_ctxt)
+        if self._parser_lock is not NULL:
+            python.PyThread_free_lock(self._parser_lock)
 
     cdef void _cleanup(self):
         cdef xmlParserCtxt* pctxt
@@ -395,6 +394,21 @@
             if pctxt.spaceTab is not NULL: # work around bug in libxml2
                 xmlparser.xmlClearParserCtxt(pctxt)
 
+    cdef int _lockParser(self) except 1:
+        cdef python.PyThreadState* state
+        cdef int result
+        if config.ENABLE_THREADING and self._parser_lock != NULL:
+            state = python.PyEval_SaveThread()
+            result = python.PyThread_acquire_lock(self._parser_lock, python.WAIT_LOCK)
+            python.PyEval_RestoreThread(state)
+            if result == 0:
+                raise ParserError, "parser locking failed"
+        return 0
+
+    cdef void _unlockParser(self):
+        if config.ENABLE_THREADING and self._parser_lock != NULL:
+            python.PyThread_release_lock(self._parser_lock)
+
     property error_log:
         def __get__(self):
             return self._error_log.copy()

Modified: lxml/trunk/src/lxml/python.pxd
==============================================================================
--- lxml/trunk/src/lxml/python.pxd	(original)
+++ lxml/trunk/src/lxml/python.pxd	Sat Feb 10 22:35:15 2007
@@ -88,6 +88,18 @@
     cdef void PyEval_RestoreThread(PyThreadState* state)
     cdef PyObject* PyThreadState_GetDict()
 
+cdef extern from "pythread.h":
+    ctypedef void* PyThread_type_lock
+    cdef PyThread_type_lock PyThread_allocate_lock()
+    cdef void PyThread_free_lock(PyThread_type_lock lock)
+    cdef int  PyThread_acquire_lock(PyThread_type_lock lock, int mode)
+    cdef void PyThread_release_lock(PyThread_type_lock lock)
+    cdef long PyThread_get_thread_ident()
+
+    ctypedef enum __WaitLock:
+        WAIT_LOCK
+        NOWAIT_LOCK
+
 cdef extern from "etree_defs.h": # redefines some functions as macros
     cdef int _isString(object obj)
     cdef int isinstance(object instance, object classes)


More information about the lxml-checkins mailing list