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

scoder at codespeak.net scoder at codespeak.net
Sun Dec 2 14:45:02 CET 2007


Author: scoder
Date: Sun Dec  2 14:45:01 2007
New Revision: 49277

Modified:
   lxml/trunk/src/lxml/c14n.pxd
   lxml/trunk/src/lxml/cstd.pxd
   lxml/trunk/src/lxml/dtd.pxi
   lxml/trunk/src/lxml/dtdvalid.pxd
   lxml/trunk/src/lxml/etreepublic.pxd
   lxml/trunk/src/lxml/htmlparser.pxd
   lxml/trunk/src/lxml/lxml.etree.pyx
   lxml/trunk/src/lxml/parser.pxi
   lxml/trunk/src/lxml/relaxng.pxd
   lxml/trunk/src/lxml/relaxng.pxi
   lxml/trunk/src/lxml/schematron.pxd
   lxml/trunk/src/lxml/schematron.pxi
   lxml/trunk/src/lxml/serializer.pxi
   lxml/trunk/src/lxml/tree.pxd
   lxml/trunk/src/lxml/xinclude.pxd
   lxml/trunk/src/lxml/xmlerror.pxd
   lxml/trunk/src/lxml/xmlparser.pxd
   lxml/trunk/src/lxml/xmlschema.pxd
   lxml/trunk/src/lxml/xmlschema.pxi
   lxml/trunk/src/lxml/xpath.pxd
   lxml/trunk/src/lxml/xpath.pxi
   lxml/trunk/src/lxml/xslt.pxd
   lxml/trunk/src/lxml/xslt.pxi
Log:
use 'with gil/nogil' where appropriate instead of acquiring/releasing the GIL by hand

Modified: lxml/trunk/src/lxml/c14n.pxd
==============================================================================
--- lxml/trunk/src/lxml/c14n.pxd	(original)
+++ lxml/trunk/src/lxml/c14n.pxd	Sun Dec  2 14:45:01 2007
@@ -7,7 +7,7 @@
                                   int exclusive,
                                   char** inclusive_ns_prefixes,
                                   int with_comments,
-                                  char** doc_txt_ptr)
+                                  char** doc_txt_ptr) nogil
 
     cdef int xmlC14NDocSave(xmlDoc* doc,
                             xmlNodeSet* nodes,
@@ -15,12 +15,12 @@
                             char** inclusive_ns_prefixes,
                             int with_comments,
                             char* filename,
-                            int compression)
+                            int compression) nogil
 
     cdef int xmlC14NDocSaveTo(xmlDoc* doc,
                               xmlNodeSet* nodes,
                               int exclusive,
                               char** inclusive_ns_prefixes,
                               int with_comments,
-                              xmlOutputBuffer* buffer)
-    
+                              xmlOutputBuffer* buffer) nogil
+

Modified: lxml/trunk/src/lxml/cstd.pxd
==============================================================================
--- lxml/trunk/src/lxml/cstd.pxd	(original)
+++ lxml/trunk/src/lxml/cstd.pxd	Sun Dec  2 14:45:01 2007
@@ -1,29 +1,29 @@
 
 cdef extern from "stdio.h":
     ctypedef struct FILE
-    cdef int sprintf(char* str, char* format, ...)
-    cdef int printf(char* str)
+    cdef int sprintf(char* str, char* format, ...) nogil
+    cdef int printf(char* str) nogil
 
 cdef extern from "string.h":
     ctypedef int size_t
-    cdef int strlen(char* s)
-    cdef char* strstr(char* haystack, char* needle)
-    cdef char* strchr(char* haystack, int needle)
-    cdef char* strrchr(char* haystack, int needle)
-    cdef int strcmp(char* s1, char* s2)
-    cdef int strncmp(char* s1, char* s2, size_t len)
-    cdef void* memcpy(void* dest, void* src, size_t len)
-    cdef void* memset(void* s, int c, size_t len)
+    cdef int strlen(char* s) nogil
+    cdef char* strstr(char* haystack, char* needle) nogil
+    cdef char* strchr(char* haystack, int needle) nogil
+    cdef char* strrchr(char* haystack, int needle) nogil
+    cdef int strcmp(char* s1, char* s2) nogil
+    cdef int strncmp(char* s1, char* s2, size_t len) nogil
+    cdef void* memcpy(void* dest, void* src, size_t len) nogil
+    cdef void* memset(void* s, int c, size_t len) nogil
 
 cdef extern from "stdlib.h":
-    cdef void* malloc(size_t size)
-    cdef void  free(void* ptr)
+    cdef void* malloc(size_t size) nogil
+    cdef void  free(void* ptr) nogil
 
 cdef extern from "stdarg.h":
     ctypedef void *va_list
-    void va_start(va_list ap, void *last)
-    void va_end(va_list ap)
+    void va_start(va_list ap, void *last) nogil
+    void va_end(va_list ap) nogil
 
 cdef extern from "etree_defs.h":
-    cdef int va_int(va_list ap)
-    cdef char *va_charptr(va_list ap)
+    cdef int va_int(va_list ap) nogil
+    cdef char *va_charptr(va_list ap) nogil

Modified: lxml/trunk/src/lxml/dtd.pxi
==============================================================================
--- lxml/trunk/src/lxml/dtd.pxi	(original)
+++ lxml/trunk/src/lxml/dtd.pxi	Sun Dec  2 14:45:01 2007
@@ -53,7 +53,6 @@
 
         Returns true if the document is valid, false if not.
         """
-        cdef python.PyThreadState* state
         cdef _Document doc
         cdef _Element root_node
         cdef xmlDoc* c_doc
@@ -70,9 +69,8 @@
             raise DTDError, "Failed to create validation context"
 
         c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
-        state = python.PyEval_SaveThread()
-        ret = dtdvalid.xmlValidateDtd(valid_ctxt, c_doc, self._c_dtd)
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            ret = dtdvalid.xmlValidateDtd(valid_ctxt, c_doc, self._c_dtd)
         _destroyFakeDoc(doc._c_doc, c_doc)
 
         dtdvalid.xmlFreeValidCtxt(valid_ctxt)

Modified: lxml/trunk/src/lxml/dtdvalid.pxd
==============================================================================
--- lxml/trunk/src/lxml/dtdvalid.pxd	(original)
+++ lxml/trunk/src/lxml/dtdvalid.pxd	Sun Dec  2 14:45:01 2007
@@ -4,7 +4,7 @@
 cdef extern from "libxml/valid.h":
     ctypedef struct xmlValidCtxt
 
-    cdef xmlValidCtxt* xmlNewValidCtxt()
-    cdef void xmlFreeValidCtxt(xmlValidCtxt* cur)
+    cdef xmlValidCtxt* xmlNewValidCtxt() nogil
+    cdef void xmlFreeValidCtxt(xmlValidCtxt* cur) nogil
 
-    cdef int xmlValidateDtd(xmlValidCtxt* ctxt, xmlDoc* doc, xmlDtd* dtd)
+    cdef int xmlValidateDtd(xmlValidCtxt* ctxt, xmlDoc* doc, xmlDtd* dtd) nogil

Modified: lxml/trunk/src/lxml/etreepublic.pxd
==============================================================================
--- lxml/trunk/src/lxml/etreepublic.pxd	(original)
+++ lxml/trunk/src/lxml/etreepublic.pxd	Sun Dec  2 14:45:01 2007
@@ -5,16 +5,16 @@
 
 cdef extern from "etree_defs.h":
     # test if c_node is considered an Element (i.e. Element, Comment, etc.)
-    cdef bint _isElement(tree.xmlNode* c_node)
+    cdef bint _isElement(tree.xmlNode* c_node) nogil
 
     # return the namespace URI of the node or NULL
-    cdef char* _getNs(tree.xmlNode* node)
+    cdef char* _getNs(tree.xmlNode* node) nogil
 
     # pair of macros for tree traversal
     cdef void BEGIN_FOR_EACH_ELEMENT_FROM(tree.xmlNode* tree_top,
                                           tree.xmlNode* start_node,
-                                          int start_node_inclusive)
-    cdef void END_FOR_EACH_ELEMENT_FROM(tree.xmlNode* start_node)
+                                          int start_node_inclusive) nogil
+    cdef void END_FOR_EACH_ELEMENT_FROM(tree.xmlNode* start_node) nogil
 
 cdef extern from "lxml.etree_api.h":
 
@@ -129,23 +129,23 @@
     # XML node helper functions
 
     # check if the element has at least one child
-    cdef bint hasChild(tree.xmlNode* c_node)
+    cdef bint hasChild(tree.xmlNode* c_node) nogil
 
     # find child element number 'index' (supports negative indexes)
     cdef tree.xmlNode* findChild(tree.xmlNode* c_node,
-                                 Py_ssize_t index)
+                                 Py_ssize_t index) nogil
 
     # find child element number 'index' starting at first one
     cdef tree.xmlNode* findChildForwards(tree.xmlNode* c_node,
-                                         Py_ssize_t index)
+                                         Py_ssize_t index) nogil
 
     # find child element number 'index' starting at last one
     cdef tree.xmlNode* findChildBackwards(tree.xmlNode* c_node,
-                                          Py_ssize_t index)
+                                          Py_ssize_t index) nogil
 
     # return next/previous sibling element of the node
-    cdef tree.xmlNode* nextElement(tree.xmlNode* c_node)
-    cdef tree.xmlNode* previousElement(tree.xmlNode* c_node)
+    cdef tree.xmlNode* nextElement(tree.xmlNode* c_node) nogil
+    cdef tree.xmlNode* previousElement(tree.xmlNode* c_node) nogil
 
     ##########################################################################
     # iterators
@@ -191,10 +191,10 @@
     cdef object namespacedNameFromNsName(char* c_ns, char* c_tag)
 
     # check if the node has a text value (which may be '')
-    cdef bint hasText(tree.xmlNode* c_node)
+    cdef bint hasText(tree.xmlNode* c_node) nogil
 
     # check if the node has a tail value (which may be '')
-    cdef bint hasTail(tree.xmlNode* c_node)
+    cdef bint hasTail(tree.xmlNode* c_node) nogil
 
     # get the text content of an element (or None)
     cdef object textOf(tree.xmlNode* c_node)

Modified: lxml/trunk/src/lxml/htmlparser.pxd
==============================================================================
--- lxml/trunk/src/lxml/htmlparser.pxd	(original)
+++ lxml/trunk/src/lxml/htmlparser.pxd	Sun Dec  2 14:45:01 2007
@@ -14,30 +14,34 @@
         HTML_PARSE_RECOVER    # Relaxed parsing
         HTML_PARSE_COMPACT    # compact small text nodes
 
-    cdef xmlParserCtxt* htmlCreateMemoryParserCtxt(char* buffer, int size)
-    cdef xmlParserCtxt* htmlCreateFileParserCtxt(char* filename, char* encoding)
+    cdef xmlParserCtxt* htmlCreateMemoryParserCtxt(
+        char* buffer, int size) nogil
+    cdef xmlParserCtxt* htmlCreateFileParserCtxt(
+        char* filename, char* encoding) nogil
     cdef xmlParserCtxt* htmlCreatePushParserCtxt(xmlSAXHandler* sax,
                                                  void* user_data,
                                                  char* chunk, int size,
-                                                 char* filename, int enc)
-    cdef void htmlFreeParserCtxt(xmlParserCtxt* ctxt)
-    cdef void htmlCtxtReset(xmlParserCtxt* ctxt)
-    cdef int htmlCtxtUseOptions(xmlParserCtxt* ctxt, int options)
-    cdef int htmlParseDocument(xmlParserCtxt* ctxt)
+                                                 char* filename, int enc) nogil
+    cdef void htmlFreeParserCtxt(xmlParserCtxt* ctxt) nogil
+    cdef void htmlCtxtReset(xmlParserCtxt* ctxt) nogil
+    cdef int htmlCtxtUseOptions(xmlParserCtxt* ctxt, int options) nogil
+    cdef int htmlParseDocument(xmlParserCtxt* ctxt) nogil
     cdef int htmlParseChunk(xmlParserCtxt* ctxt, 
-                            char* chunk, int size, int terminate)
+                            char* chunk, int size, int terminate) nogil
 
     cdef xmlDoc* htmlCtxtReadFile(xmlParserCtxt* ctxt,
                                   char* filename, char* encoding,
-                                  int options)
+                                  int options) nogil
     cdef xmlDoc* htmlCtxtReadDoc(xmlParserCtxt* ctxt,
                                  char* buffer, char* URL, char* encoding,
-                                 int options)
+                                 int options) nogil
     cdef xmlDoc* htmlCtxtReadIO(xmlParserCtxt* ctxt, 
                                 xmlInputReadCallback ioread, 
                                 xmlInputCloseCallback ioclose, 
                                 void* ioctx,
-                                char* URL, char* encoding, int options)
+                                char* URL, char* encoding,
+                                int options) nogil
     cdef xmlDoc* htmlCtxtReadMemory(xmlParserCtxt* ctxt,
                                     char* buffer, int size,
-                                    char* filename, char* encoding, int options)
+                                    char* filename, char* encoding,
+                                    int options) nogil

Modified: lxml/trunk/src/lxml/lxml.etree.pyx
==============================================================================
--- lxml/trunk/src/lxml/lxml.etree.pyx	(original)
+++ lxml/trunk/src/lxml/lxml.etree.pyx	Sun Dec  2 14:45:01 2007
@@ -1588,8 +1588,8 @@
         Note that XInclude does not support custom resolvers in Python space
         due to restrictions of libxml2 <= 2.6.29.
         """
-        cdef python.PyThreadState* state
         cdef int result
+        self._assertHasRoot()
         # We cannot pass the XML_PARSE_NOXINCNODE option as this would free
         # the XInclude nodes - there may still be Python references to them!
         # Therefore, we allow XInclude nodes to be converted to
@@ -1597,16 +1597,14 @@
         # siblings.  Tree traversal will simply ignore them as they are not
         # typed as elements.  The included fragment is added between the two,
         # i.e. as a sibling, which does not conflict with traversal.
-        self._assertHasRoot()
-        state = python.PyEval_SaveThread()
-        if self._context_node._doc._parser is not None:
-            result = xinclude.xmlXIncludeProcessTreeFlags(
-                self._context_node._c_node,
-                self._context_node._doc._parser._parse_options)
-        else:
-            result = xinclude.xmlXIncludeProcessTree(
-                self._context_node._c_node)
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            if self._context_node._doc._parser is not None:
+                result = xinclude.xmlXIncludeProcessTreeFlags(
+                    self._context_node._c_node,
+                    self._context_node._doc._parser._parse_options)
+            else:
+                result = xinclude.xmlXIncludeProcessTree(
+                    self._context_node._c_node)
         if result == -1:
             raise XIncludeError, "XInclude processing failed"
 

Modified: lxml/trunk/src/lxml/parser.pxi
==============================================================================
--- lxml/trunk/src/lxml/parser.pxi	(original)
+++ lxml/trunk/src/lxml/parser.pxi	Sun Dec  2 14:45:01 2007
@@ -228,7 +228,6 @@
         return xmlparser.xmlNewIOInputStream(ctxt, c_buffer, 0)
 
     cdef xmlDoc* _readDoc(self, xmlparser.xmlParserCtxt* ctxt, int options):
-        cdef python.PyThreadState* state
         cdef xmlDoc* result
         cdef char* c_encoding
 
@@ -237,29 +236,24 @@
         else:
             c_encoding = _cstr(self._encoding)
 
-        state = python.PyEval_SaveThread()
-        if ctxt.html:
-            result = htmlparser.htmlCtxtReadIO(
-                ctxt, _readFilelikeParser, NULL, <python.PyObject*>self,
-                self._c_url, c_encoding, options)
-        else:
-            result = xmlparser.xmlCtxtReadIO(
-                ctxt, _readFilelikeParser, NULL, <python.PyObject*>self,
-                self._c_url, c_encoding, options)
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            if ctxt.html:
+                result = htmlparser.htmlCtxtReadIO(
+                    ctxt, _readFilelikeParser, NULL, <python.PyObject*>self,
+                    self._c_url, c_encoding, options)
+            else:
+                result = xmlparser.xmlCtxtReadIO(
+                    ctxt, _readFilelikeParser, NULL, <python.PyObject*>self,
+                    self._c_url, c_encoding, options)
         return result
 
     cdef tree.xmlDtd* _readDtd(self):
-        cdef python.PyThreadState* state
-        cdef tree.xmlDtd* result
         cdef xmlparser.xmlParserInputBuffer* c_buffer
         c_buffer = xmlparser.xmlAllocParserInputBuffer(0)
         c_buffer.context = <python.PyObject*>self
         c_buffer.readcallback = _readFilelikeParser
-        state = python.PyEval_SaveThread()
-        result = xmlparser.xmlIOParseDTD(NULL, c_buffer, 0)
-        python.PyEval_RestoreThread(state)
-        return result
+        with nogil:
+            return xmlparser.xmlIOParseDTD(NULL, c_buffer, 0)
 
     cdef int copyToBuffer(self, char* c_buffer, int c_size):
         cdef char* c_start
@@ -699,7 +693,6 @@
         """Parse unicode document, share dictionary if possible.
         """
         cdef _ParserContext context
-        cdef python.PyThreadState* state
         cdef xmlDoc* result
         cdef xmlparser.xmlParserCtxt* pctxt
         cdef Py_ssize_t py_buffer_len
@@ -719,16 +712,15 @@
             __GLOBAL_PARSER_CONTEXT.initParserDict(pctxt)
 
             c_text = python.PyUnicode_AS_DATA(utext)
-            state = python.PyEval_SaveThread()
-            if self._for_html:
-                result = htmlparser.htmlCtxtReadMemory(
-                    pctxt, c_text, buffer_len, c_filename, _UNICODE_ENCODING,
-                    self._parse_options)
-            else:
-                result = xmlparser.xmlCtxtReadMemory(
-                    pctxt, c_text, buffer_len, c_filename, _UNICODE_ENCODING,
-                    self._parse_options)
-            python.PyEval_RestoreThread(state)
+            with nogil:
+                if self._for_html:
+                    result = htmlparser.htmlCtxtReadMemory(
+                        pctxt, c_text, buffer_len, c_filename, _UNICODE_ENCODING,
+                        self._parse_options)
+                else:
+                    result = xmlparser.xmlCtxtReadMemory(
+                        pctxt, c_text, buffer_len, c_filename, _UNICODE_ENCODING,
+                        self._parse_options)
 
             return context._handleParseResultDoc(self, result, None)
         finally:
@@ -739,7 +731,6 @@
         """Parse document, share dictionary if possible.
         """
         cdef _ParserContext context
-        cdef python.PyThreadState* state
         cdef xmlDoc* result
         cdef xmlparser.xmlParserCtxt* pctxt
         cdef char* c_encoding
@@ -757,16 +748,15 @@
             else:
                 c_encoding = _cstr(self._default_encoding)
 
-            state = python.PyEval_SaveThread()
-            if self._for_html:
-                result = htmlparser.htmlCtxtReadMemory(
-                    pctxt, c_text, c_len, c_filename,
-                    c_encoding, self._parse_options)
-            else:
-                result = xmlparser.xmlCtxtReadMemory(
-                    pctxt, c_text, c_len, c_filename,
-                    c_encoding, self._parse_options)
-            python.PyEval_RestoreThread(state)
+            with nogil:
+                if self._for_html:
+                    result = htmlparser.htmlCtxtReadMemory(
+                        pctxt, c_text, c_len, c_filename,
+                        c_encoding, self._parse_options)
+                else:
+                    result = xmlparser.xmlCtxtReadMemory(
+                        pctxt, c_text, c_len, c_filename,
+                        c_encoding, self._parse_options)
 
             return context._handleParseResultDoc(self, result, None)
         finally:
@@ -774,7 +764,6 @@
 
     cdef xmlDoc* _parseDocFromFile(self, char* c_filename) except NULL:
         cdef _ParserContext context
-        cdef python.PyThreadState* state
         cdef xmlDoc* result
         cdef xmlparser.xmlParserCtxt* pctxt
         cdef int orig_options
@@ -793,14 +782,13 @@
                 c_encoding = _cstr(self._default_encoding)
 
             orig_options = pctxt.options
-            state = python.PyEval_SaveThread()
-            if self._for_html:
-                result = htmlparser.htmlCtxtReadFile(
-                    pctxt, c_filename, c_encoding, self._parse_options)
-            else:
-                result = xmlparser.xmlCtxtReadFile(
-                    pctxt, c_filename, c_encoding, self._parse_options)
-            python.PyEval_RestoreThread(state)
+            with nogil:
+                if self._for_html:
+                    result = htmlparser.htmlCtxtReadFile(
+                        pctxt, c_filename, c_encoding, self._parse_options)
+                else:
+                    result = xmlparser.xmlCtxtReadFile(
+                        pctxt, c_filename, c_encoding, self._parse_options)
             pctxt.options = orig_options # work around libxml2 problem
 
             return context._handleParseResultDoc(self, result, c_filename)
@@ -1630,13 +1618,12 @@
     return result
 
 cdef xmlDoc* _copyDoc(xmlDoc* c_doc, int recursive) except NULL:
-    cdef python.PyThreadState* state
     cdef xmlDoc* result
     if recursive:
-        state = python.PyEval_SaveThread()
-    result = tree.xmlCopyDoc(c_doc, recursive)
-    if recursive:
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            result = tree.xmlCopyDoc(c_doc, recursive)
+    else:
+        result = tree.xmlCopyDoc(c_doc, 0)
     if result is NULL:
         python.PyErr_NoMemory()
     __GLOBAL_PARSER_CONTEXT.initDocDict(result)
@@ -1644,14 +1631,12 @@
 
 cdef xmlDoc* _copyDocRoot(xmlDoc* c_doc, xmlNode* c_new_root) except NULL:
     "Recursively copy the document and make c_new_root the new root node."
-    cdef python.PyThreadState* state
     cdef xmlDoc* result
     cdef xmlNode* c_node
     result = tree.xmlCopyDoc(c_doc, 0) # non recursive
     __GLOBAL_PARSER_CONTEXT.initDocDict(result)
-    state = python.PyEval_SaveThread()
-    c_node = tree.xmlDocCopyNode(c_new_root, result, 1) # recursive
-    python.PyEval_RestoreThread(state)
+    with nogil:
+        c_node = tree.xmlDocCopyNode(c_new_root, result, 1) # recursive
     if c_node is NULL:
         python.PyErr_NoMemory()
     tree.xmlDocSetRootElement(result, c_node)

Modified: lxml/trunk/src/lxml/relaxng.pxd
==============================================================================
--- lxml/trunk/src/lxml/relaxng.pxd	(original)
+++ lxml/trunk/src/lxml/relaxng.pxd	Sun Dec  2 14:45:01 2007
@@ -49,12 +49,11 @@
         XML_RELAXNG_ERR_ELEMWRONG = 38
         XML_RELAXNG_ERR_TEXTWRONG = 39
         
-    cdef xmlRelaxNGValidCtxt* xmlRelaxNGNewValidCtxt(xmlRelaxNG* schema)
-    cdef int xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxt* ctxt, xmlDoc* doc)
-    cdef xmlRelaxNG* xmlRelaxNGParse(xmlRelaxNGParserCtxt* ctxt)
-    cdef xmlRelaxNGParserCtxt* xmlRelaxNGNewParserCtxt(char* URL)
-    cdef xmlRelaxNGParserCtxt* xmlRelaxNGNewDocParserCtxt(xmlDoc* doc)
-    cdef void xmlRelaxNGFree(xmlRelaxNG* schema)
-    cdef void xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxt* ctxt)
-    cdef void xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxt* ctxt)
-    
+    cdef xmlRelaxNGValidCtxt* xmlRelaxNGNewValidCtxt(xmlRelaxNG* schema) nogil
+    cdef int xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxt* ctxt, xmlDoc* doc) nogil
+    cdef xmlRelaxNG* xmlRelaxNGParse(xmlRelaxNGParserCtxt* ctxt) nogil
+    cdef xmlRelaxNGParserCtxt* xmlRelaxNGNewParserCtxt(char* URL) nogil
+    cdef xmlRelaxNGParserCtxt* xmlRelaxNGNewDocParserCtxt(xmlDoc* doc) nogil
+    cdef void xmlRelaxNGFree(xmlRelaxNG* schema) nogil
+    cdef void xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxt* ctxt) nogil
+    cdef void xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxt* ctxt) nogil

Modified: lxml/trunk/src/lxml/relaxng.pxi
==============================================================================
--- lxml/trunk/src/lxml/relaxng.pxi	(original)
+++ lxml/trunk/src/lxml/relaxng.pxi	Sun Dec  2 14:45:01 2007
@@ -86,7 +86,6 @@
         """Validate doc using Relax NG.
 
         Returns true if document is valid, false if not."""
-        cdef python.PyThreadState* state
         cdef _Document doc
         cdef _Element root_node
         cdef xmlDoc* c_doc
@@ -103,9 +102,8 @@
             python.PyErr_NoMemory()
 
         c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
-        state = python.PyEval_SaveThread()
-        ret = relaxng.xmlRelaxNGValidateDoc(valid_ctxt, c_doc)
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            ret = relaxng.xmlRelaxNGValidateDoc(valid_ctxt, c_doc)
         _destroyFakeDoc(doc._c_doc, c_doc)
 
         relaxng.xmlRelaxNGFreeValidCtxt(valid_ctxt)

Modified: lxml/trunk/src/lxml/schematron.pxd
==============================================================================
--- lxml/trunk/src/lxml/schematron.pxd	(original)
+++ lxml/trunk/src/lxml/schematron.pxd	Sun Dec  2 14:45:01 2007
@@ -14,15 +14,17 @@
         XML_SCHEMATRON_OUT_BUFFER          =  512 # output to a buffer
         XML_SCHEMATRON_OUT_IO              = 1024 # output to I/O mechanism
 
-    cdef xmlSchematronParserCtxt* xmlSchematronNewDocParserCtxt(xmlDoc* doc)
-    cdef xmlSchematronParserCtxt* xmlSchematronNewParserCtxt(char* filename)
-    cdef xmlSchematronValidCtxt* xmlSchematronNewValidCtxt(xmlSchematron* schema,
-                                                           int options)
+    cdef xmlSchematronParserCtxt* xmlSchematronNewDocParserCtxt(
+        xmlDoc* doc) nogil
+    cdef xmlSchematronParserCtxt* xmlSchematronNewParserCtxt(
+        char* filename) nogil
+    cdef xmlSchematronValidCtxt* xmlSchematronNewValidCtxt(
+        xmlSchematron* schema, int options) nogil
 
-    cdef xmlSchematron* xmlSchematronParse(xmlSchematronParserCtxt* ctxt)
+    cdef xmlSchematron* xmlSchematronParse(xmlSchematronParserCtxt* ctxt) nogil
     cdef int xmlSchematronValidateDoc(xmlSchematronValidCtxt* ctxt,
-                                      xmlDoc* instance)
+                                      xmlDoc* instance) nogil
 
-    cdef void xmlSchematronFreeParserCtxt(xmlSchematronParserCtxt* ctxt)
-    cdef void xmlSchematronFreeValidCtxt(xmlSchematronValidCtxt* ctxt)
-    cdef void xmlSchematronFree(xmlSchematron* schema)
+    cdef void xmlSchematronFreeParserCtxt(xmlSchematronParserCtxt* ctxt) nogil
+    cdef void xmlSchematronFreeValidCtxt(xmlSchematronValidCtxt* ctxt) nogil
+    cdef void xmlSchematronFree(xmlSchematron* schema) nogil

Modified: lxml/trunk/src/lxml/schematron.pxi
==============================================================================
--- lxml/trunk/src/lxml/schematron.pxi	(original)
+++ lxml/trunk/src/lxml/schematron.pxi	Sun Dec  2 14:45:01 2007
@@ -117,7 +117,6 @@
         """Validate doc using Schematron.
 
         Returns true if document is valid, false if not."""
-        cdef python.PyThreadState* state
         cdef _Document doc
         cdef _Element root_node
         cdef xmlDoc* c_doc
@@ -140,9 +139,8 @@
             raise SchematronError, "Failed to create validation context"
 
         c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
-        state = python.PyEval_SaveThread()
-        ret = schematron.xmlSchematronValidateDoc(valid_ctxt, c_doc)
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            ret = schematron.xmlSchematronValidateDoc(valid_ctxt, c_doc)
         _destroyFakeDoc(doc._c_doc, c_doc)
 
         schematron.xmlSchematronFreeValidCtxt(valid_ctxt)

Modified: lxml/trunk/src/lxml/serializer.pxi
==============================================================================
--- lxml/trunk/src/lxml/serializer.pxi	(original)
+++ lxml/trunk/src/lxml/serializer.pxi	Sun Dec  2 14:45:01 2007
@@ -18,11 +18,9 @@
     raise ValueError, "unknown output method %r" % method
 
 cdef _textToString(xmlNode* c_node, encoding):
-    cdef python.PyThreadState* state
     cdef char* c_text
-    state = python.PyEval_SaveThread()
-    c_text = tree.xmlNodeGetContent(c_node)
-    python.PyEval_RestoreThread(state)
+    with nogil:
+        c_text = tree.xmlNodeGetContent(c_node)
     if c_text is NULL:
         python.PyErr_NoMemory()
 
@@ -49,7 +47,6 @@
     """Serialize an element to an encoded string representation of its XML
     tree.
     """
-    cdef python.PyThreadState* state
     cdef tree.xmlOutputBuffer* c_buffer
     cdef tree.xmlBuffer* c_result_buffer
     cdef tree.xmlCharEncodingHandler* enchandler
@@ -77,17 +74,17 @@
         tree.xmlCharEncCloseFunc(enchandler)
         raise LxmlError, "Failed to create output buffer"
 
-    try:
-        state = python.PyEval_SaveThread()
+    with nogil:
         _writeNodeToBuffer(c_buffer, element._c_node, c_enc, c_method,
                            write_xml_declaration, write_complete_document,
                            pretty_print)
         tree.xmlOutputBufferFlush(c_buffer)
-        python.PyEval_RestoreThread(state)
         if c_buffer.conv is not NULL:
             c_result_buffer = c_buffer.conv
         else:
             c_result_buffer = c_buffer.buffer
+
+    try:
         result = python.PyString_FromStringAndSize(
             tree.xmlBufferContent(c_result_buffer),
             tree.xmlBufferLength(c_result_buffer))
@@ -100,7 +97,6 @@
     """Serialize an element to the Python unicode representation of its XML
     tree.
     """
-    cdef python.PyThreadState* state
     cdef tree.xmlOutputBuffer* c_buffer
     cdef tree.xmlBuffer* c_result_buffer
     cdef int c_method
@@ -113,16 +109,17 @@
     c_buffer = tree.xmlAllocOutputBuffer(NULL)
     if c_buffer is NULL:
         raise LxmlError, "Failed to create output buffer"
-    try:
-        state = python.PyEval_SaveThread()
+
+    with nogil:
         _writeNodeToBuffer(c_buffer, element._c_node, NULL, c_method, 0,
                            write_complete_document, pretty_print)
         tree.xmlOutputBufferFlush(c_buffer)
-        python.PyEval_RestoreThread(state)
         if c_buffer.conv is not NULL:
             c_result_buffer = c_buffer.conv
         else:
             c_result_buffer = c_buffer.buffer
+
+    try:
         result = python.PyUnicode_DecodeUTF8(
             tree.xmlBufferContent(c_result_buffer),
             tree.xmlBufferLength(c_result_buffer),
@@ -135,7 +132,7 @@
                              xmlNode* c_node, char* encoding, int c_method,
                              bint write_xml_declaration,
                              bint write_complete_document,
-                             bint pretty_print):
+                             bint pretty_print) nogil:
     cdef xmlDoc* c_doc
     cdef xmlNode* c_nsdecl_node
     c_doc = c_node.doc
@@ -177,7 +174,7 @@
         _writeNextSiblings(c_buffer, c_node, encoding, pretty_print)
 
 cdef void _writeDeclarationToBuffer(tree.xmlOutputBuffer* c_buffer,
-                                    char* version, char* encoding):
+                                    char* version, char* encoding) nogil:
     if version is NULL:
         version = "1.0"
     tree.xmlOutputBufferWriteString(c_buffer, "<?xml version='")
@@ -187,7 +184,8 @@
     tree.xmlOutputBufferWriteString(c_buffer, "'?>\n")
 
 cdef void _writeDtdToBuffer(tree.xmlOutputBuffer* c_buffer,
-                            xmlDoc* c_doc, char* c_root_name, char* encoding):
+                            xmlDoc* c_doc, char* c_root_name,
+                            char* encoding) nogil:
     cdef tree.xmlDtd* c_dtd
     cdef xmlNode* c_node
     c_dtd = c_doc.intSubset
@@ -222,7 +220,7 @@
     tree.xmlOutputBufferWrite(c_buffer, 3, "]>\n")
 
 cdef void _writeTail(tree.xmlOutputBuffer* c_buffer, xmlNode* c_node,
-                     char* encoding, bint pretty_print):
+                     char* encoding, bint pretty_print) nogil:
     "Write the element tail."
     c_node = c_node.next
     while c_node is not NULL and c_node.type == tree.XML_TEXT_NODE:
@@ -231,7 +229,7 @@
         c_node = c_node.next
 
 cdef void _writePrevSiblings(tree.xmlOutputBuffer* c_buffer, xmlNode* c_node,
-                             char* encoding, bint pretty_print):
+                             char* encoding, bint pretty_print) nogil:
     cdef xmlNode* c_sibling
     if c_node.parent is not NULL and _isElement(c_node.parent):
         return
@@ -247,7 +245,7 @@
         c_sibling = c_sibling.next
 
 cdef void _writeNextSiblings(tree.xmlOutputBuffer* c_buffer, xmlNode* c_node,
-                             char* encoding, bint pretty_print):
+                             char* encoding, bint pretty_print) nogil:
     cdef xmlNode* c_sibling
     if c_node.parent is not NULL and _isElement(c_node.parent):
         return
@@ -358,7 +356,6 @@
         writer._exc_context._raise_if_stored()
 
 cdef _tofilelikeC14N(f, _Element element):
-    cdef python.PyThreadState* state
     cdef _FilelikeWriter writer
     cdef tree.xmlOutputBuffer* c_buffer
     cdef char* c_filename
@@ -372,9 +369,9 @@
         if _isString(f):
             filename8 = _encodeFilename(f)
             c_filename = _cstr(filename8)
-            state = python.PyEval_SaveThread()
-            bytes = c14n.xmlC14NDocSave(c_doc, NULL, 0, NULL, 1, c_filename, 0)
-            python.PyEval_RestoreThread(state)
+            with nogil:
+                bytes = c14n.xmlC14NDocSave(c_doc, NULL, 0, NULL, 1,
+                                            c_filename, 0)
         elif hasattr(f, 'write'):
             writer   = _FilelikeWriter(f)
             c_buffer = writer._createOutputBuffer(NULL)

Modified: lxml/trunk/src/lxml/tree.pxd
==============================================================================
--- lxml/trunk/src/lxml/tree.pxd	(original)
+++ lxml/trunk/src/lxml/tree.pxd	Sun Dec  2 14:45:01 2007
@@ -35,21 +35,22 @@
         XML_CHAR_ENCODING_ASCII = 22 # pure ASCII
 
     ctypedef struct xmlCharEncodingHandler
-    cdef xmlCharEncodingHandler* xmlFindCharEncodingHandler(char* name)
-    cdef xmlCharEncodingHandler* xmlGetCharEncodingHandler(xmlCharEncoding enc)
-    cdef int xmlCharEncCloseFunc(xmlCharEncodingHandler* handler)
-    cdef xmlCharEncoding xmlDetectCharEncoding(char* text, int len)
-    cdef char* xmlGetCharEncodingName(xmlCharEncoding enc)
-    cdef xmlCharEncoding xmlParseCharEncoding(char* name)
+    cdef xmlCharEncodingHandler* xmlFindCharEncodingHandler(char* name) nogil
+    cdef xmlCharEncodingHandler* xmlGetCharEncodingHandler(
+        xmlCharEncoding enc) nogil
+    cdef int xmlCharEncCloseFunc(xmlCharEncodingHandler* handler) nogil
+    cdef xmlCharEncoding xmlDetectCharEncoding(char* text, int len) nogil
+    cdef char* xmlGetCharEncodingName(xmlCharEncoding enc) nogil
+    cdef xmlCharEncoding xmlParseCharEncoding(char* name) nogil
 
 cdef extern from "libxml/chvalid.h":
-    cdef int xmlIsChar_ch(char c)
+    cdef int xmlIsChar_ch(char c) nogil
 
 cdef extern from "libxml/hash.h":
     ctypedef struct xmlHashTable
-    ctypedef void xmlHashScanner(void* payload, void* data, char* name)
-    void xmlHashScan(xmlHashTable* table, xmlHashScanner f, void* data)
-    void* xmlHashLookup(xmlHashTable* table, char* name)
+    ctypedef void xmlHashScanner(void* payload, void* data, char* name) nogil
+    void xmlHashScan(xmlHashTable* table, xmlHashScanner f, void* data) nogil
+    void* xmlHashLookup(xmlHashTable* table, char* name) nogil
 
 cdef extern from "libxml/tree.h":
 
@@ -167,106 +168,112 @@
         xmlBuffer* buffer
         xmlBuffer* conv
         
-    cdef void xmlFreeDoc(xmlDoc* cur)
-    cdef void xmlFreeDtd(xmlDtd* cur)
-    cdef void xmlFreeNode(xmlNode* cur)
-    cdef void xmlFreeNsList(xmlNs* ns)
-    cdef void xmlFreeNs(xmlNs* ns)
-    cdef void xmlFree(char* buf)
+    cdef void xmlFreeDoc(xmlDoc* cur) nogil
+    cdef void xmlFreeDtd(xmlDtd* cur) nogil
+    cdef void xmlFreeNode(xmlNode* cur) nogil
+    cdef void xmlFreeNsList(xmlNs* ns) nogil
+    cdef void xmlFreeNs(xmlNs* ns) nogil
+    cdef void xmlFree(char* buf) nogil
     
-    cdef xmlNode* xmlNewNode(xmlNs* ns, char* name)
-    cdef xmlNode* xmlNewDocText(xmlDoc* doc, char* content)
-    cdef xmlNode* xmlNewDocComment(xmlDoc* doc, char* content)
-    cdef xmlNode* xmlNewDocPI(xmlDoc* doc, char* name, char* content)
-    cdef xmlNode* xmlNewReference(xmlDoc* doc, char* name)
-    cdef xmlNs* xmlNewNs(xmlNode* node, char* href, char* prefix)
-    cdef xmlNode* xmlAddChild(xmlNode* parent, xmlNode* cur)
-    cdef xmlNode* xmlReplaceNode(xmlNode* old, xmlNode* cur)
-    cdef xmlNode* xmlAddPrevSibling(xmlNode* cur, xmlNode* elem)
-    cdef xmlNode* xmlAddNextSibling(xmlNode* cur, xmlNode* elem)
+    cdef xmlNode* xmlNewNode(xmlNs* ns, char* name) nogil
+    cdef xmlNode* xmlNewDocText(xmlDoc* doc, char* content) nogil
+    cdef xmlNode* xmlNewDocComment(xmlDoc* doc, char* content) nogil
+    cdef xmlNode* xmlNewDocPI(xmlDoc* doc, char* name, char* content) nogil
+    cdef xmlNode* xmlNewReference(xmlDoc* doc, char* name) nogil
+    cdef xmlNs* xmlNewNs(xmlNode* node, char* href, char* prefix) nogil
+    cdef xmlNode* xmlAddChild(xmlNode* parent, xmlNode* cur) nogil
+    cdef xmlNode* xmlReplaceNode(xmlNode* old, xmlNode* cur) nogil
+    cdef xmlNode* xmlAddPrevSibling(xmlNode* cur, xmlNode* elem) nogil
+    cdef xmlNode* xmlAddNextSibling(xmlNode* cur, xmlNode* elem) nogil
     cdef xmlNode* xmlNewDocNode(xmlDoc* doc, xmlNs* ns,
-                                char* name, char* content)
-    cdef xmlDoc* xmlNewDoc(char* version)
-    cdef xmlAttr* xmlNewProp(xmlNode* node, char* name, char* value)
+                                char* name, char* content) nogil
+    cdef xmlDoc* xmlNewDoc(char* version) nogil
+    cdef xmlAttr* xmlNewProp(xmlNode* node, char* name, char* value) nogil
     cdef xmlAttr* xmlNewNsProp(xmlNode* node, xmlNs* ns,
-                               char* name, char* value)
-    cdef char* xmlGetNoNsProp(xmlNode* node, char* name)
-    cdef char* xmlGetNsProp(xmlNode* node, char* name, char* nameSpace)
-    cdef void xmlSetNs(xmlNode* node, xmlNs* ns)
-    cdef xmlAttr* xmlSetProp(xmlNode* node, char* name, char* value)
+                               char* name, char* value) nogil
+    cdef char* xmlGetNoNsProp(xmlNode* node, char* name) nogil
+    cdef char* xmlGetNsProp(xmlNode* node, char* name, char* nameSpace) nogil
+    cdef void xmlSetNs(xmlNode* node, xmlNs* ns) nogil
+    cdef xmlAttr* xmlSetProp(xmlNode* node, char* name, char* value) nogil
     cdef xmlAttr* xmlSetNsProp(xmlNode* node, xmlNs* ns,
-                               char* name, char* value)
-    cdef int xmlRemoveProp(xmlAttr* cur)
-    cdef char* xmlGetNodePath(xmlNode* node)
-    cdef void xmlDocDumpMemory(xmlDoc* cur, char** mem, int* size)
+                               char* name, char* value) nogil
+    cdef int xmlRemoveProp(xmlAttr* cur) nogil
+    cdef char* xmlGetNodePath(xmlNode* node) nogil
+    cdef void xmlDocDumpMemory(xmlDoc* cur, char** mem, int* size) nogil
     cdef void xmlDocDumpMemoryEnc(xmlDoc* cur, char** mem, int* size,
-                                  char* encoding)
-    cdef int xmlSaveFileTo(xmlOutputBuffer* out, xmlDoc* cur, char* encoding)
-
-    cdef void xmlUnlinkNode(xmlNode* cur)
-    cdef xmlNode* xmlDocSetRootElement(xmlDoc* doc, xmlNode* root)
-    cdef xmlNode* xmlDocGetRootElement(xmlDoc* doc)
-    cdef void xmlSetTreeDoc(xmlNode* tree, xmlDoc* doc)
-    cdef xmlAttr* xmlHasProp(xmlNode* node, char* name)
-    cdef xmlAttr* xmlHasNsProp(xmlNode* node, char* name, char* nameSpace)
-    cdef char* xmlNodeGetContent(xmlNode* cur)
-    cdef xmlNs* xmlSearchNs(xmlDoc* doc, xmlNode* node, char* prefix)
-    cdef xmlNs* xmlSearchNsByHref(xmlDoc* doc, xmlNode* node, char* href)
-    cdef int xmlIsBlankNode(xmlNode* node)
-    cdef long xmlGetLineNo(xmlNode* node)
-    cdef void xmlElemDump(FILE* f, xmlDoc* doc, xmlNode* cur)
+                                  char* encoding) nogil
+    cdef int xmlSaveFileTo(xmlOutputBuffer* out, xmlDoc* cur,
+                           char* encoding) nogil
+
+    cdef void xmlUnlinkNode(xmlNode* cur) nogil
+    cdef xmlNode* xmlDocSetRootElement(xmlDoc* doc, xmlNode* root) nogil
+    cdef xmlNode* xmlDocGetRootElement(xmlDoc* doc) nogil
+    cdef void xmlSetTreeDoc(xmlNode* tree, xmlDoc* doc) nogil
+    cdef xmlAttr* xmlHasProp(xmlNode* node, char* name) nogil
+    cdef xmlAttr* xmlHasNsProp(xmlNode* node, char* name, char* nameSpace) nogil
+    cdef char* xmlNodeGetContent(xmlNode* cur) nogil
+    cdef xmlNs* xmlSearchNs(xmlDoc* doc, xmlNode* node, char* prefix) nogil
+    cdef xmlNs* xmlSearchNsByHref(xmlDoc* doc, xmlNode* node, char* href) nogil
+    cdef int xmlIsBlankNode(xmlNode* node) nogil
+    cdef long xmlGetLineNo(xmlNode* node) nogil
+    cdef void xmlElemDump(FILE* f, xmlDoc* doc, xmlNode* cur) nogil
     cdef void xmlNodeDumpOutput(xmlOutputBuffer* buf,
                                 xmlDoc* doc, xmlNode* cur, int level,
-                                int format, char* encoding)
-    cdef void xmlNodeSetName(xmlNode* cur, char* name)
-    cdef void xmlNodeSetContent(xmlNode* cur, char* content)
-    cdef xmlDtd* xmlCopyDtd(xmlDtd* dtd)
-    cdef xmlDoc* xmlCopyDoc(xmlDoc* doc, int recursive)
-    cdef xmlNode* xmlCopyNode(xmlNode* node, int extended)
-    cdef xmlNode* xmlDocCopyNode(xmlNode* node, xmlDoc* doc, int extended)
-    cdef int xmlReconciliateNs(xmlDoc* doc, xmlNode* tree)
-    cdef xmlNs* xmlNewReconciliedNs(xmlDoc* doc, xmlNode* tree, xmlNs* ns)
-    cdef xmlBuffer* xmlBufferCreate()
-    cdef void xmlBufferFree(xmlBuffer* buf)
-    cdef char* xmlBufferContent(xmlBuffer* buf)
-    cdef int xmlBufferLength(xmlBuffer* buf)
-    cdef int xmlKeepBlanksDefault(int val)
-    cdef char* xmlNodeGetBase(xmlDoc* doc, xmlNode* node)
-    cdef char* xmlBuildURI(char* href, char* base)
-    cdef int xmlValidateNCName(char* value, int space)
+                                int format, char* encoding) nogil
+    cdef void xmlNodeSetName(xmlNode* cur, char* name) nogil
+    cdef void xmlNodeSetContent(xmlNode* cur, char* content) nogil
+    cdef xmlDtd* xmlCopyDtd(xmlDtd* dtd) nogil
+    cdef xmlDoc* xmlCopyDoc(xmlDoc* doc, int recursive) nogil
+    cdef xmlNode* xmlCopyNode(xmlNode* node, int extended) nogil
+    cdef xmlNode* xmlDocCopyNode(xmlNode* node, xmlDoc* doc, int extended) nogil
+    cdef int xmlReconciliateNs(xmlDoc* doc, xmlNode* tree) nogil
+    cdef xmlNs* xmlNewReconciliedNs(xmlDoc* doc, xmlNode* tree, xmlNs* ns) nogil
+    cdef xmlBuffer* xmlBufferCreate() nogil
+    cdef void xmlBufferFree(xmlBuffer* buf) nogil
+    cdef char* xmlBufferContent(xmlBuffer* buf) nogil
+    cdef int xmlBufferLength(xmlBuffer* buf) nogil
+    cdef int xmlKeepBlanksDefault(int val) nogil
+    cdef char* xmlNodeGetBase(xmlDoc* doc, xmlNode* node) nogil
+    cdef char* xmlBuildURI(char* href, char* base) nogil
+    cdef int xmlValidateNCName(char* value, int space) nogil
 
 cdef extern from "libxml/HTMLtree.h":
     cdef void htmlNodeDumpFormatOutput(xmlOutputBuffer* buf,
                                        xmlDoc* doc, xmlNode* cur,
-                                       char* encoding, int format)
+                                       char* encoding, int format) nogil
 
 cdef extern from "libxml/valid.h":
-    cdef xmlAttr* xmlGetID(xmlDoc* doc, char* ID)
-    cdef void xmlDumpNotationTable(xmlBuffer* buffer, xmlNotationTable* table)
+    cdef xmlAttr* xmlGetID(xmlDoc* doc, char* ID) nogil
+    cdef void xmlDumpNotationTable(xmlBuffer* buffer,
+                                   xmlNotationTable* table) nogil
 
 cdef extern from "libxml/xmlIO.h":
-    cdef void xmlBufferWriteQuotedString(xmlOutputBuffer* out, char* str)
-    cdef int xmlOutputBufferWriteString(xmlOutputBuffer* out, char* str)
-    cdef int xmlOutputBufferWrite(xmlOutputBuffer* out, int len, char* str)
-    cdef int xmlOutputBufferFlush(xmlOutputBuffer* out)
-    cdef int xmlOutputBufferClose(xmlOutputBuffer* out)
-
-    ctypedef int (*xmlInputReadCallback)(void* context, char* buffer, int len)
-    ctypedef int (*xmlInputCloseCallback)(void* context)
-
-    ctypedef int (*xmlOutputWriteCallback)(void* context, char* buffer, int len)
-    ctypedef int (*xmlOutputCloseCallback)(void* context)
+    cdef void xmlBufferWriteQuotedString(xmlOutputBuffer* out, char* str) nogil
+    cdef int xmlOutputBufferWriteString(xmlOutputBuffer* out, char* str) nogil
+    cdef int xmlOutputBufferWrite(xmlOutputBuffer* out,
+                                  int len, char* str) nogil
+    cdef int xmlOutputBufferFlush(xmlOutputBuffer* out) nogil
+    cdef int xmlOutputBufferClose(xmlOutputBuffer* out) nogil
+
+    ctypedef int (*xmlInputReadCallback)(void* context,
+                                         char* buffer, int len) nogil
+    ctypedef int (*xmlInputCloseCallback)(void* context) nogil
+
+    ctypedef int (*xmlOutputWriteCallback)(void* context,
+                                           char* buffer, int len) nogil
+    ctypedef int (*xmlOutputCloseCallback)(void* context) nogil
 
-    cdef xmlOutputBuffer* xmlAllocOutputBuffer(xmlCharEncodingHandler* encoder)
+    cdef xmlOutputBuffer* xmlAllocOutputBuffer(
+        xmlCharEncodingHandler* encoder) nogil
     cdef xmlOutputBuffer* xmlOutputBufferCreateIO(
         xmlOutputWriteCallback iowrite,
         xmlOutputCloseCallback ioclose,
         void * ioctx, 
-        xmlCharEncodingHandler* encoder)
+        xmlCharEncodingHandler* encoder) nogil
     cdef xmlOutputBuffer* xmlOutputBufferCreateFile(
-        FILE* file, xmlCharEncodingHandler* encoder)
+        FILE* file, xmlCharEncodingHandler* encoder) nogil
     cdef xmlOutputBuffer* xmlOutputBufferCreateFilename(
-        char* URI, xmlCharEncodingHandler* encoder, int compression)
+        char* URI, xmlCharEncodingHandler* encoder, int compression) nogil
 
 cdef extern from "libxml/xmlsave.h":
     ctypedef struct xmlSaveCtxt
@@ -278,31 +285,32 @@
         XML_SAVE_NO_XHTML = 8   # disable XHTML1 specific rules (2.6.22)
 
     cdef xmlSaveCtxt* xmlSaveToFilename(char* filename, char* encoding,
-                                        int options)
+                                        int options) nogil
     cdef xmlSaveCtxt* xmlSaveToBuffer(xmlBuffer* buffer, char* encoding,
-                                      int options) # libxml2 2.6.23
-    cdef long xmlSaveDoc(xmlSaveCtxt* ctxt, xmlDoc* doc)
-    cdef long xmlSaveTree(xmlSaveCtxt* ctxt, xmlNode* node)
-    cdef int xmlSaveClose(xmlSaveCtxt* ctxt)
-    cdef int xmlSaveFlush(xmlSaveCtxt* ctxt)
-    cdef int xmlSaveSetAttrEscape(xmlSaveCtxt* ctxt, void* escape_func)
-    cdef int xmlSaveSetEscape(xmlSaveCtxt* ctxt, void* escape_func)
+                                      int options) nogil # libxml2 2.6.23
+    cdef long xmlSaveDoc(xmlSaveCtxt* ctxt, xmlDoc* doc) nogil
+    cdef long xmlSaveTree(xmlSaveCtxt* ctxt, xmlNode* node) nogil
+    cdef int xmlSaveClose(xmlSaveCtxt* ctxt) nogil
+    cdef int xmlSaveFlush(xmlSaveCtxt* ctxt) nogil
+    cdef int xmlSaveSetAttrEscape(xmlSaveCtxt* ctxt, void* escape_func) nogil
+    cdef int xmlSaveSetEscape(xmlSaveCtxt* ctxt, void* escape_func) nogil
 
 cdef extern from "libxml/globals.h":
-    cdef int xmlThrDefKeepBlanksDefaultValue(int onoff)
-    cdef int xmlThrDefLineNumbersDefaultValue(int onoff)
-    cdef int xmlThrDefIndentTreeOutput(int onoff)
+    cdef int xmlThrDefKeepBlanksDefaultValue(int onoff) nogil
+    cdef int xmlThrDefLineNumbersDefaultValue(int onoff) nogil
+    cdef int xmlThrDefIndentTreeOutput(int onoff) nogil
     
 cdef extern from "libxml/xmlstring.h":
-    cdef char* xmlStrdup(char* cur)
+    cdef char* xmlStrdup(char* cur) nogil
 
 cdef extern from "libxml/xmlmemory.h":
-    cdef void* xmlMalloc(size_t size)
+    cdef void* xmlMalloc(size_t size) nogil
 
 cdef extern from "etree_defs.h":
-    cdef bint _isElement(xmlNode* node)
-    cdef bint _isElementOrXInclude(xmlNode* node)
-    cdef char* _getNs(xmlNode* node)
+    cdef bint _isElement(xmlNode* node) nogil
+    cdef bint _isElementOrXInclude(xmlNode* node) nogil
+    cdef char* _getNs(xmlNode* node) nogil
     cdef void BEGIN_FOR_EACH_ELEMENT_FROM(xmlNode* tree_top,
-                                          xmlNode* start_node, bint inclusive)
-    cdef void END_FOR_EACH_ELEMENT_FROM(xmlNode* start_node)
+                                          xmlNode* start_node,
+                                          bint inclusive) nogil
+    cdef void END_FOR_EACH_ELEMENT_FROM(xmlNode* start_node) nogil

Modified: lxml/trunk/src/lxml/xinclude.pxd
==============================================================================
--- lxml/trunk/src/lxml/xinclude.pxd	(original)
+++ lxml/trunk/src/lxml/xinclude.pxd	Sun Dec  2 14:45:01 2007
@@ -4,14 +4,15 @@
 
     ctypedef struct xmlXIncludeCtxt
 
-    cdef int xmlXIncludeProcess(xmlDoc* doc)
-    cdef int xmlXIncludeProcessFlags(xmlDoc* doc, int parser_opts)
-    cdef int xmlXIncludeProcessTree(xmlNode* doc)
-    cdef int xmlXIncludeProcessTreeFlags(xmlNode* doc, int parser_opts)
+    cdef int xmlXIncludeProcess(xmlDoc* doc) nogil
+    cdef int xmlXIncludeProcessFlags(xmlDoc* doc, int parser_opts) nogil
+    cdef int xmlXIncludeProcessTree(xmlNode* doc) nogil
+    cdef int xmlXIncludeProcessTreeFlags(xmlNode* doc, int parser_opts) nogil
 
-    cdef xmlXIncludeCtxt* xmlXIncludeNewContext(xmlDoc* doc)
-    cdef int xmlXIncludeProcessNode(xmlXIncludeCtxt* ctxt, xmlNode* node)
-    cdef int xmlXIncludeSetFlags(xmlXIncludeCtxt* ctxt, int flags)
+    cdef xmlXIncludeCtxt* xmlXIncludeNewContext(xmlDoc* doc) nogil
+    cdef int xmlXIncludeProcessNode(xmlXIncludeCtxt* ctxt, xmlNode* node) nogil
+    cdef int xmlXIncludeSetFlags(xmlXIncludeCtxt* ctxt, int flags) nogil
 
     # libxml2 >= 2.6.27
-    cdef int xmlXIncludeProcessFlagsData(xmlDoc* doc, int flags, void* data)
+    cdef int xmlXIncludeProcessFlagsData(
+        xmlDoc* doc, int flags, void* data) nogil

Modified: lxml/trunk/src/lxml/xmlerror.pxd
==============================================================================
--- lxml/trunk/src/lxml/xmlerror.pxd	(original)
+++ lxml/trunk/src/lxml/xmlerror.pxd	Sun Dec  2 14:45:01 2007
@@ -783,14 +783,17 @@
         int int1
         int int2
 
-    ctypedef void (*xmlGenericErrorFunc)(void* ctxt, char* msg, ...)
-    ctypedef void (*xmlStructuredErrorFunc)(void* userData, xmlError* error)
+    ctypedef void (*xmlGenericErrorFunc)(void* ctxt, char* msg, ...) nogil
+    ctypedef void (*xmlStructuredErrorFunc)(void* userData,
+                                            xmlError* error) nogil
 
-    cdef void xmlSetGenericErrorFunc(void* ctxt, xmlGenericErrorFunc func)
-    cdef void xmlSetStructuredErrorFunc(void* ctxt, xmlStructuredErrorFunc func)
+    cdef void xmlSetGenericErrorFunc(
+        void* ctxt, xmlGenericErrorFunc func) nogil
+    cdef void xmlSetStructuredErrorFunc(
+        void* ctxt, xmlStructuredErrorFunc func) nogil
 
 cdef extern from "libxml/globals.h":
-    cdef void xmlThrDefSetGenericErrorFunc(void* ctx,
-                                           xmlGenericErrorFunc handler)
-    cdef void xmlThrDefSetStructuredErrorFunc(void* ctx,
-                                              xmlStructuredErrorFunc handler)
+    cdef void xmlThrDefSetGenericErrorFunc(
+        void* ctx, xmlGenericErrorFunc handler) nogil
+    cdef void xmlThrDefSetStructuredErrorFunc(
+        void* ctx, xmlStructuredErrorFunc handler) nogil

Modified: lxml/trunk/src/lxml/xmlparser.pxd
==============================================================================
--- lxml/trunk/src/lxml/xmlparser.pxd	(original)
+++ lxml/trunk/src/lxml/xmlparser.pxd	Sun Dec  2 14:45:01 2007
@@ -65,14 +65,14 @@
         int                             initialized
 
 cdef extern from "libxml/xmlIO.h":
-    cdef xmlParserInputBuffer* xmlAllocParserInputBuffer(int enc)
+    cdef xmlParserInputBuffer* xmlAllocParserInputBuffer(int enc) nogil
 
 cdef extern from "libxml/parser.h":
 
-    cdef xmlDict* xmlDictCreate()
-    cdef xmlDict* xmlDictCreateSub(xmlDict* subdict)
-    cdef void xmlDictFree(xmlDict* sub)
-    cdef int xmlDictReference(xmlDict* dict)
+    cdef xmlDict* xmlDictCreate() nogil
+    cdef xmlDict* xmlDictCreateSub(xmlDict* subdict) nogil
+    cdef void xmlDictFree(xmlDict* sub) nogil
+    cdef int xmlDictReference(xmlDict* dict) nogil
     
     cdef int XML_COMPLETE_ATTRS # SAX option for adding DTD default attributes
 
@@ -118,31 +118,34 @@
         # libxml2 2.6.21+ only:
         XML_PARSE_COMPACT = 65536 # compact small text nodes
 
-    cdef void xmlInitParser()
-    cdef int xmlLineNumbersDefault(int onoff)
-    cdef xmlParserCtxt* xmlNewParserCtxt()
+    cdef void xmlInitParser() nogil
+    cdef int xmlLineNumbersDefault(int onoff) nogil
+    cdef xmlParserCtxt* xmlNewParserCtxt() nogil
     cdef xmlParserInput* xmlNewIOInputStream(xmlParserCtxt* ctxt,
                                              xmlParserInputBuffer* input,
-                                             int enc)
-    cdef int xmlCtxtUseOptions(xmlParserCtxt* ctxt, int options)
-    cdef void xmlFreeParserCtxt(xmlParserCtxt* ctxt)
-    cdef void xmlCtxtReset(xmlParserCtxt* ctxt)
-    cdef void xmlClearParserCtxt(xmlParserCtxt* ctxt)
+                                             int enc) nogil
+    cdef int xmlCtxtUseOptions(xmlParserCtxt* ctxt, int options) nogil
+    cdef void xmlFreeParserCtxt(xmlParserCtxt* ctxt) nogil
+    cdef void xmlCtxtReset(xmlParserCtxt* ctxt) nogil
+    cdef void xmlClearParserCtxt(xmlParserCtxt* ctxt) nogil
     cdef int xmlParseChunk(xmlParserCtxt* ctxt,
-                           char* chunk, int size, int terminate)
+                           char* chunk, int size, int terminate) nogil
     cdef xmlDoc* xmlCtxtReadDoc(xmlParserCtxt* ctxt,
                                 char* cur, char* URL, char* encoding,
-                                int options)
+                                int options) nogil
     cdef xmlDoc* xmlCtxtReadFile(xmlParserCtxt* ctxt,
-                                 char* filename, char* encoding, int options)
+                                 char* filename, char* encoding,
+                                 int options) nogil
     cdef xmlDoc* xmlCtxtReadIO(xmlParserCtxt* ctxt, 
                                xmlInputReadCallback ioread, 
                                xmlInputCloseCallback ioclose, 
                                void* ioctx,
-                               char* URL, char* encoding, int options)
+                               char* URL, char* encoding,
+                               int options) nogil
     cdef xmlDoc* xmlCtxtReadMemory(xmlParserCtxt* ctxt,
                                    char* buffer, int size,
-                                   char* filename, char* encoding, int options)
+                                   char* filename, char* encoding,
+                                   int options) nogil
 
 # iterparse:
 
@@ -150,33 +153,32 @@
                                                 void* user_data,
                                                 char* chunk,
                                                 int size,
-                                                char* filename)
+                                                char* filename) nogil
 
     cdef int xmlCtxtResetPush(xmlParserCtxt* ctxt,
                               char* chunk,
                               int size,
                               char* filename,
-                              char* encoding)
+                              char* encoding) nogil
 
 # entity loaders:
 
-    ctypedef xmlParserInput* (*xmlExternalEntityLoader)(char * URL,
-                                                        char * ID, 
-                                                        xmlParserCtxt* context)
-    cdef xmlExternalEntityLoader xmlGetExternalEntityLoader()
-    cdef void xmlSetExternalEntityLoader(xmlExternalEntityLoader f)
+    ctypedef xmlParserInput* (*xmlExternalEntityLoader)(
+        char * URL, char * ID, xmlParserCtxt* context) nogil
+    cdef xmlExternalEntityLoader xmlGetExternalEntityLoader() nogil
+    cdef void xmlSetExternalEntityLoader(xmlExternalEntityLoader f) nogil
 
 # DTDs:
 
-    cdef xmlDtd* xmlParseDTD(char* ExternalID, char* SystemID)
+    cdef xmlDtd* xmlParseDTD(char* ExternalID, char* SystemID) nogil
     cdef xmlDtd* xmlIOParseDTD(xmlSAXHandler* sax,
                                xmlParserInputBuffer* input,
-                               int enc)
+                               int enc) nogil
 
 cdef extern from "libxml/parserInternals.h":
     cdef xmlParserInput* xmlNewStringInputStream(xmlParserCtxt* ctxt, 
-                                                 char* buffer)
+                                                 char* buffer) nogil
     cdef xmlParserInput* xmlNewInputFromFile(xmlParserCtxt* ctxt, 
-                                             char* filename)
-    cdef void xmlFreeInputStream(xmlParserInput* input)
-    cdef int xmlSwitchEncoding(xmlParserCtxt* ctxt, int enc)
+                                             char* filename) nogil
+    cdef void xmlFreeInputStream(xmlParserInput* input) nogil
+    cdef int xmlSwitchEncoding(xmlParserCtxt* ctxt, int enc) nogil

Modified: lxml/trunk/src/lxml/xmlschema.pxd
==============================================================================
--- lxml/trunk/src/lxml/xmlschema.pxd	(original)
+++ lxml/trunk/src/lxml/xmlschema.pxd	Sun Dec  2 14:45:01 2007
@@ -4,14 +4,14 @@
 cdef extern from "libxml/xmlschemas.h":
     ctypedef struct xmlSchema
     ctypedef struct xmlSchemaParserCtxt
-    
+
     ctypedef struct xmlSchemaValidCtxt
-        
-    cdef xmlSchemaValidCtxt* xmlSchemaNewValidCtxt(xmlSchema* schema)
-    cdef int xmlSchemaValidateDoc(xmlSchemaValidCtxt* ctxt, xmlDoc* doc)
-    cdef xmlSchema* xmlSchemaParse(xmlSchemaParserCtxt* ctxt)
-    cdef xmlSchemaParserCtxt* xmlSchemaNewParserCtxt(char* URL)
-    cdef xmlSchemaParserCtxt* xmlSchemaNewDocParserCtxt(xmlDoc* doc)
-    cdef void xmlSchemaFree(xmlSchema* schema)
-    cdef void xmlSchemaFreeParserCtxt(xmlSchemaParserCtxt* ctxt)
-    cdef void xmlSchemaFreeValidCtxt(xmlSchemaValidCtxt* ctxt)
+
+    cdef xmlSchemaValidCtxt* xmlSchemaNewValidCtxt(xmlSchema* schema) nogil
+    cdef int xmlSchemaValidateDoc(xmlSchemaValidCtxt* ctxt, xmlDoc* doc) nogil
+    cdef xmlSchema* xmlSchemaParse(xmlSchemaParserCtxt* ctxt) nogil
+    cdef xmlSchemaParserCtxt* xmlSchemaNewParserCtxt(char* URL) nogil
+    cdef xmlSchemaParserCtxt* xmlSchemaNewDocParserCtxt(xmlDoc* doc) nogil
+    cdef void xmlSchemaFree(xmlSchema* schema) nogil
+    cdef void xmlSchemaFreeParserCtxt(xmlSchemaParserCtxt* ctxt) nogil
+    cdef void xmlSchemaFreeValidCtxt(xmlSchemaValidCtxt* ctxt) nogil

Modified: lxml/trunk/src/lxml/xmlschema.pxi
==============================================================================
--- lxml/trunk/src/lxml/xmlschema.pxi	(original)
+++ lxml/trunk/src/lxml/xmlschema.pxi	Sun Dec  2 14:45:01 2007
@@ -81,7 +81,6 @@
 
         Returns true if document is valid, false if not.
         """
-        cdef python.PyThreadState* state
         cdef xmlschema.xmlSchemaValidCtxt* valid_ctxt
         cdef _Document doc
         cdef _Element root_node
@@ -98,9 +97,8 @@
             raise XMLSchemaError, "Failed to create validation context"
 
         c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
-        state = python.PyEval_SaveThread()
-        ret = xmlschema.xmlSchemaValidateDoc(valid_ctxt, c_doc)
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            ret = xmlschema.xmlSchemaValidateDoc(valid_ctxt, c_doc)
         _destroyFakeDoc(doc._c_doc, c_doc)
 
         xmlschema.xmlSchemaFreeValidCtxt(valid_ctxt)

Modified: lxml/trunk/src/lxml/xpath.pxd
==============================================================================
--- lxml/trunk/src/lxml/xpath.pxd	(original)
+++ lxml/trunk/src/lxml/xpath.pxd	Sun Dec  2 14:45:01 2007
@@ -68,66 +68,65 @@
         tree.xmlNode* ancestor
         int error
 
-    ctypedef struct xmlXPathCompExpr:
-        pass
+    ctypedef struct xmlXPathCompExpr
 
     ctypedef void (*xmlXPathFunction)(xmlXPathParserContext* ctxt, int nargs)
     ctypedef xmlXPathFunction (*xmlXPathFuncLookupFunc)(void* ctxt,
                                                         char* name,
                                                         char* ns_uri)
     
-    cdef xmlXPathContext* xmlXPathNewContext(tree.xmlDoc* doc)
+    cdef xmlXPathContext* xmlXPathNewContext(tree.xmlDoc* doc) nogil
     cdef xmlXPathObject* xmlXPathEvalExpression(char* str,
-                                                xmlXPathContext* ctxt)
+                                                xmlXPathContext* ctxt) nogil
     cdef xmlXPathObject* xmlXPathCompiledEval(xmlXPathCompExpr* comp,
-                                              xmlXPathContext* ctxt)
-    cdef xmlXPathCompExpr* xmlXPathCompile(char* str)
+                                              xmlXPathContext* ctxt) nogil
+    cdef xmlXPathCompExpr* xmlXPathCompile(char* str) nogil
     cdef xmlXPathCompExpr* xmlXPathCtxtCompile(xmlXPathContext* ctxt,
-                                               char* str)
-    cdef void xmlXPathFreeContext(xmlXPathContext* ctxt)
-    cdef void xmlXPathFreeCompExpr(xmlXPathCompExpr* comp)
-    cdef void xmlXPathFreeObject(xmlXPathObject* obj)
+                                               char* str) nogil
+    cdef void xmlXPathFreeContext(xmlXPathContext* ctxt) nogil
+    cdef void xmlXPathFreeCompExpr(xmlXPathCompExpr* comp) nogil
+    cdef void xmlXPathFreeObject(xmlXPathObject* obj) nogil
     cdef int xmlXPathRegisterNs(xmlXPathContext* ctxt,
-                                char* prefix, char* ns_uri)
+                                char* prefix, char* ns_uri) nogil
     
-    cdef xmlNodeSet* xmlXPathNodeSetCreate(tree.xmlNode* val)
-    cdef void xmlXPathFreeNodeSet(xmlNodeSet* val)
+    cdef xmlNodeSet* xmlXPathNodeSetCreate(tree.xmlNode* val) nogil
+    cdef void xmlXPathFreeNodeSet(xmlNodeSet* val) nogil
 
 
 cdef extern from "libxml/xpathInternals.h":
     cdef int xmlXPathRegisterFunc(xmlXPathContext* ctxt,
                                   char* name,
-                                  xmlXPathFunction f)
+                                  xmlXPathFunction f) nogil
     cdef int xmlXPathRegisterFuncNS(xmlXPathContext* ctxt,
                                     char* name,
                                     char* ns_uri,
-                                    xmlXPathFunction f)
+                                    xmlXPathFunction f) nogil
     cdef void xmlXPathRegisterFuncLookup(xmlXPathContext *ctxt,
                                          xmlXPathFuncLookupFunc f,
-                                         void *funcCtxt)
+                                         void *funcCtxt) nogil
     cdef int xmlXPathRegisterVariable(xmlXPathContext *ctxt, 
                                       char* name,
-                                      xmlXPathObject* value)
+                                      xmlXPathObject* value) nogil
     cdef int xmlXPathRegisterVariableNS(xmlXPathContext *ctxt, 
                                         char* name, 
                                         char* ns_uri, 
-                                        xmlXPathObject* value)
-    cdef void xmlXPathRegisteredVariablesCleanup(xmlXPathContext *ctxt)
-    cdef void xmlXPathRegisteredNsCleanup(xmlXPathContext *ctxt)
-    cdef xmlXPathObject* valuePop (xmlXPathParserContext *ctxt)
-    cdef int valuePush(xmlXPathParserContext* ctxt, xmlXPathObject *value)
+                                        xmlXPathObject* value) nogil
+    cdef void xmlXPathRegisteredVariablesCleanup(xmlXPathContext *ctxt) nogil
+    cdef void xmlXPathRegisteredNsCleanup(xmlXPathContext *ctxt) nogil
+    cdef xmlXPathObject* valuePop (xmlXPathParserContext *ctxt) nogil
+    cdef int valuePush(xmlXPathParserContext* ctxt, xmlXPathObject *value) nogil
     
-    cdef xmlXPathObject* xmlXPathNewCString(char *val)
-    cdef xmlXPathObject* xmlXPathWrapCString(char * val)
-    cdef xmlXPathObject* xmlXPathNewString(char *val)
-    cdef xmlXPathObject* xmlXPathWrapString(char * val)
-    cdef xmlXPathObject* xmlXPathNewFloat(double val)
-    cdef xmlXPathObject* xmlXPathNewBoolean(int val)
-    cdef xmlXPathObject* xmlXPathNewNodeSet(tree.xmlNode* val)
-    cdef xmlXPathObject* xmlXPathNewValueTree(tree.xmlNode* val)
+    cdef xmlXPathObject* xmlXPathNewCString(char *val) nogil
+    cdef xmlXPathObject* xmlXPathWrapCString(char * val) nogil
+    cdef xmlXPathObject* xmlXPathNewString(char *val) nogil
+    cdef xmlXPathObject* xmlXPathWrapString(char * val) nogil
+    cdef xmlXPathObject* xmlXPathNewFloat(double val) nogil
+    cdef xmlXPathObject* xmlXPathNewBoolean(int val) nogil
+    cdef xmlXPathObject* xmlXPathNewNodeSet(tree.xmlNode* val) nogil
+    cdef xmlXPathObject* xmlXPathNewValueTree(tree.xmlNode* val) nogil
     cdef void xmlXPathNodeSetAdd(xmlNodeSet* cur,
-                                  tree.xmlNode* val)
+                                  tree.xmlNode* val) nogil
     cdef void xmlXPathNodeSetAddUnique(xmlNodeSet* cur,
-                                        tree.xmlNode* val)
-    cdef xmlXPathObject* xmlXPathWrapNodeSet(xmlNodeSet* val)
-    cdef void xmlXPathErr(xmlXPathParserContext* ctxt, int error)
+                                        tree.xmlNode* val) nogil
+    cdef xmlXPathObject* xmlXPathWrapNodeSet(xmlNodeSet* val) nogil
+    cdef void xmlXPathErr(xmlXPathParserContext* ctxt, int error) nogil

Modified: lxml/trunk/src/lxml/xpath.pxi
==============================================================================
--- lxml/trunk/src/lxml/xpath.pxi	(original)
+++ lxml/trunk/src/lxml/xpath.pxi	Sun Dec  2 14:45:01 2007
@@ -248,7 +248,6 @@
         Absolute XPath expressions (starting with '/') will be evaluated
         against the ElementTree as returned by getroottree().
         """
-        cdef python.PyThreadState* state
         cdef xpath.xmlXPathObject*  xpathObj
         cdef _Document doc
         cdef char* c_path
@@ -261,10 +260,10 @@
         try:
             self._context.register_context(doc)
             self._context.registerVariables(_variables)
-            state = python.PyEval_SaveThread()
-            xpathObj = xpath.xmlXPathEvalExpression(
-                _cstr(path), self._xpathCtxt)
-            python.PyEval_RestoreThread(state)
+            c_path = _cstr(path)
+            with nogil:
+                xpathObj = xpath.xmlXPathEvalExpression(
+                    c_path, self._xpathCtxt)
             result = self._handle_result(xpathObj, doc)
         finally:
             self._error_log.disconnect()
@@ -292,10 +291,10 @@
         Variables may be provided as keyword arguments.  Note that namespaces
         are currently not supported for variables.
         """
-        cdef python.PyThreadState* state
         cdef xpath.xmlXPathObject*  xpathObj
         cdef xmlDoc* c_doc
         cdef _Document doc
+        cdef char* c_path
         path = _utf8(_path)
         doc = self._element._doc
 
@@ -306,12 +305,12 @@
             c_doc = _fakeRootDoc(doc._c_doc, self._element._c_node)
             try:
                 self._context.registerVariables(_variables)
-                state = python.PyEval_SaveThread()
-                self._xpathCtxt.doc  = c_doc
-                self._xpathCtxt.node = tree.xmlDocGetRootElement(c_doc)
-                xpathObj = xpath.xmlXPathEvalExpression(
-                    _cstr(path), self._xpathCtxt)
-                python.PyEval_RestoreThread(state)
+                c_path = _cstr(path)
+                with nogil:
+                    self._xpathCtxt.doc  = c_doc
+                    self._xpathCtxt.node = tree.xmlDocGetRootElement(c_doc)
+                    xpathObj = xpath.xmlXPathEvalExpression(
+                        c_path, self._xpathCtxt)
                 result = self._handle_result(xpathObj, doc)
             finally:
                 _destroyFakeDoc(doc._c_doc, c_doc)
@@ -370,7 +369,6 @@
             self._raise_parse_error()
 
     def __call__(self, _etree_or_element, **_variables):
-        cdef python.PyThreadState* state
         cdef xpath.xmlXPathObject*  xpathObj
         cdef _Document document
         cdef _Element element
@@ -387,10 +385,9 @@
         try:
             self._context.register_context(document)
             self._context.registerVariables(_variables)
-            state = python.PyEval_SaveThread()
-            xpathObj = xpath.xmlXPathCompiledEval(
-                self._xpath, self._xpathCtxt)
-            python.PyEval_RestoreThread(state)
+            with nogil:
+                xpathObj = xpath.xmlXPathCompiledEval(
+                    self._xpath, self._xpathCtxt)
             result = self._handle_result(xpathObj, document)
         finally:
             self._error_log.disconnect()

Modified: lxml/trunk/src/lxml/xslt.pxd
==============================================================================
--- lxml/trunk/src/lxml/xslt.pxd	(original)
+++ lxml/trunk/src/lxml/xslt.pxd	Sun Dec  2 14:45:01 2007
@@ -23,20 +23,21 @@
         xmlDict* dict
         int profile
 
-    cdef xsltStylesheet* xsltParseStylesheetDoc(xmlDoc* doc)
-    cdef void xsltFreeStylesheet(xsltStylesheet* sheet)
+    cdef xsltStylesheet* xsltParseStylesheetDoc(xmlDoc* doc) nogil
+    cdef void xsltFreeStylesheet(xsltStylesheet* sheet) nogil
 
 cdef extern from "libxslt/extensions.h":
     cdef int xsltRegisterExtFunction(xsltTransformContext* ctxt,
                                      char* name,
                                      char* URI,
-                                     xmlXPathFunction function)
+                                     xmlXPathFunction function) nogil
     cdef int xsltRegisterExtModuleFunction(char* name, char* URI,
-                                           xmlXPathFunction function)
+                                           xmlXPathFunction function) nogil
     cdef int xsltUnregisterExtModuleFunction(char* name, char* URI)
-    cdef xmlXPathFunction xsltExtModuleFunctionLookup(char* name, char* URI)
+    cdef xmlXPathFunction xsltExtModuleFunctionLookup(
+        char* name, char* URI) nogil
     cdef int xsltRegisterExtPrefix(xsltStylesheet* style, 
-                                   char* prefix, char* URI)
+                                   char* prefix, char* URI) nogil
 
 cdef extern from "libxslt/documents.h":
     ctypedef enum xsltLoadType:
@@ -49,30 +50,30 @@
                                           void* ctxt,
                                           xsltLoadType type)
     cdef xsltDocLoaderFunc xsltDocDefaultLoader
-    cdef void xsltSetLoaderFunc(xsltDocLoaderFunc f)
+    cdef void xsltSetLoaderFunc(xsltDocLoaderFunc f) nogil
 
 cdef extern from "libxslt/transform.h":
     cdef xmlDoc* xsltApplyStylesheet(xsltStylesheet* style, xmlDoc* doc,
-                                     char** params)
+                                     char** params) nogil
     cdef xmlDoc* xsltApplyStylesheetUser(xsltStylesheet* style, xmlDoc* doc,
                                          char** params, char* output,
                                          void* profile,
-                                         xsltTransformContext* context)
+                                         xsltTransformContext* context) nogil
     cdef xsltTransformContext* xsltNewTransformContext(xsltStylesheet* style,
-                                                       xmlDoc* doc)
-    cdef void xsltFreeTransformContext(xsltTransformContext* context)
+                                                       xmlDoc* doc) nogil
+    cdef void xsltFreeTransformContext(xsltTransformContext* context) nogil
 
 cdef extern from "libxslt/xsltutils.h":
     cdef int xsltSaveResultToString(char** doc_txt_ptr,
                                     int* doc_txt_len,
                                     xmlDoc* result,
-                                    xsltStylesheet* style)
+                                    xsltStylesheet* style) nogil
     
-    cdef void xsltSetGenericErrorFunc(void* ctxt,
-                                      void (*handler)(void* ctxt, char* msg, ...))
-    cdef void xsltSetTransformErrorFunc(xsltTransformContext*,
-                                        void* ctxt,
-                                        void (*handler)(void* ctxt, char* msg, ...))
+    cdef void xsltSetGenericErrorFunc(
+        void* ctxt, void (*handler)(void* ctxt, char* msg, ...)) nogil
+    cdef void xsltSetTransformErrorFunc(
+        xsltTransformContext*, void* ctxt,
+        void (*handler)(void* ctxt, char* msg, ...)) nogil
 
 cdef extern from "libxslt/security.h":
     ctypedef struct xsltSecurityPrefs
@@ -87,20 +88,20 @@
                                       xsltTransformContext* ctxt,
                                       char* value)
 
-    cdef xsltSecurityPrefs* xsltNewSecurityPrefs()
-    cdef void xsltFreeSecurityPrefs(xsltSecurityPrefs* sec)
+    cdef xsltSecurityPrefs* xsltNewSecurityPrefs() nogil
+    cdef void xsltFreeSecurityPrefs(xsltSecurityPrefs* sec) nogil
     cdef int xsltSecurityForbid(xsltSecurityPrefs* sec,
                                 xsltTransformContext* ctxt,
-                                char* value)
+                                char* value) nogil
     cdef int xsltSecurityAllow(xsltSecurityPrefs* sec,
                                 xsltTransformContext* ctxt,
-                                char* value)
+                                char* value) nogil
     cdef int xsltSetSecurityPrefs(xsltSecurityPrefs* sec,
                                   xsltSecurityOption option,
-                                  xsltSecurityCheck func)
+                                  xsltSecurityCheck func) nogil
     cdef int xsltSetCtxtSecurityPrefs(xsltSecurityPrefs* sec,
-                                      xsltTransformContext* ctxt)
-    cdef xmlDoc* xsltGetProfileInformation(xsltTransformContext* ctxt)
+                                      xsltTransformContext* ctxt) nogil
+    cdef xmlDoc* xsltGetProfileInformation(xsltTransformContext* ctxt) nogil
 
 cdef extern from "libxslt/extra.h":
     cdef char* XSLT_LIBXSLT_NAMESPACE
@@ -109,7 +110,7 @@
     cdef char* XSLT_XT_NAMESPACE
 
     cdef xmlXPathFunction xsltFunctionNodeSet
-    cdef void xsltRegisterAllExtras()
+    cdef void xsltRegisterAllExtras() nogil
 
 cdef extern from "libexslt/exslt.h":
-    cdef void exsltRegisterAll()
+    cdef void exsltRegisterAll() nogil

Modified: lxml/trunk/src/lxml/xslt.pxi
==============================================================================
--- lxml/trunk/src/lxml/xslt.pxi	(original)
+++ lxml/trunk/src/lxml/xslt.pxi	Sun Dec  2 14:45:01 2007
@@ -271,7 +271,6 @@
 
     def __init__(self, xslt_input, extensions=None, regexp=True,
                  access_control=None):
-        cdef python.PyThreadState* state
         cdef xslt.xsltStylesheet* c_style
         cdef xmlDoc* c_doc
         cdef xmlDoc* fake_c_doc
@@ -301,9 +300,8 @@
         c_doc._private = <python.PyObject*>self._xslt_resolver_context
 
         self._error_log.connect()
-        state = python.PyEval_SaveThread()
-        c_style = xslt.xsltParseStylesheetDoc(c_doc)
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            c_style = xslt.xsltParseStylesheetDoc(c_doc)
         self._error_log.disconnect()
 
         if c_style is NULL:
@@ -443,7 +441,6 @@
     cdef xmlDoc* _run_transform(self, _Document input_doc, xmlDoc* c_input_doc,
                                 parameters, _XSLTContext context,
                                 xslt.xsltTransformContext* transform_ctxt):
-        cdef python.PyThreadState* state
         cdef xmlDoc* c_result
         cdef char** params
         cdef Py_ssize_t i, parameter_count
@@ -480,10 +477,9 @@
         else:
             params = NULL
 
-        state = python.PyEval_SaveThread()
-        c_result = xslt.xsltApplyStylesheetUser(
-            self._c_style, c_input_doc, params, NULL, NULL, transform_ctxt)
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            c_result = xslt.xsltApplyStylesheetUser(
+                self._c_style, c_input_doc, params, NULL, NULL, transform_ctxt)
 
         if params is not NULL:
             # deallocate space for parameters
@@ -499,7 +495,6 @@
     cdef XSLT _xslt
     cdef _Document _profile
     cdef _saveToStringAndSize(self, char** s, int* l):
-        cdef python.PyThreadState* state
         cdef _Document doc
         cdef int r
         if self._context_node is not None:
@@ -509,9 +504,9 @@
             if doc is None:
                 s[0] = NULL
                 return
-        state = python.PyEval_SaveThread()
-        r = xslt.xsltSaveResultToString(s, l, doc._c_doc, self._xslt._c_style)
-        python.PyEval_RestoreThread(state)
+        with nogil:
+            r = xslt.xsltSaveResultToString(s, l, doc._c_doc,
+                                            self._xslt._c_style)
         if r == -1:
             raise XSLTSaveError, "Error saving XSLT result to string"
 


More information about the lxml-checkins mailing list