diff -ub Python-2.4.1-orig/Modules/_sre.c Python-2.4.1/Modules/_sre.c --- Python-2.4.1-orig/Modules/_sre.c 2004-12-02 16:36:29.000000000 +0000 +++ Python-2.4.1/Modules/_sre.c 2005-11-28 13:32:46.000000000 +0000 @@ -23,6 +23,11 @@ * 2003-04-18 mvl fully support 4-byte codes * 2003-10-17 gn implemented non recursive scheme * + * 2005-11-28: Eric Noyau + * Made the search routines release the GIL when possible, aka when the + * string it is working on is coming from a python string or unicode object. + * + * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * This version of the SRE library can be redistributed under CNRI's @@ -1472,6 +1477,7 @@ return ret; /* should never get here */ } + LOCAL(int) SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern) { @@ -1719,14 +1725,14 @@ } static void* -getstring(PyObject* string, int* p_length, int* p_charsize) +getstring(PyObject* string, int* p_length, int* p_charsize, int* p_is_read_only) { /* given a python object, return a data pointer, a length (in characters), and a character size. return NULL if the object is not a string (or not compatible) */ PyBufferProcs *buffer; - int size, bytes, charsize; + int size, bytes, charsize, is_read_only; void* ptr; #if defined(HAVE_UNICODE) @@ -1736,7 +1742,7 @@ bytes = PyUnicode_GET_DATA_SIZE(string); size = PyUnicode_GET_SIZE(string); charsize = sizeof(Py_UNICODE); - + is_read_only = 1; } else { #endif @@ -1762,6 +1768,8 @@ size = PyObject_Length(string); #endif + is_read_only = PyString_Check(string); /*|| !buffer->bf_getwritebuffer*/ + if (PyString_Check(string) || bytes == size) charsize = 1; #if defined(HAVE_UNICODE) @@ -1779,7 +1787,7 @@ *p_length = size; *p_charsize = charsize; - + *p_is_read_only = is_read_only; return ptr; } @@ -1791,6 +1799,7 @@ int length; int charsize; + int readonly; void* ptr; memset(state, 0, sizeof(SRE_STATE)); @@ -1798,7 +1807,7 @@ state->lastmark = -1; state->lastindex = -1; - ptr = getstring(string, &length, &charsize); + ptr = getstring(string, &length, &charsize, &readonly); if (!ptr) return NULL; @@ -1824,6 +1833,7 @@ state->string = string; state->pos = start; state->endpos = end; + state->readonly = readonly; if (pattern->flags & SRE_FLAG_LOCALE) state->lower = sre_lower_locale; @@ -1981,6 +1991,7 @@ return NULL; } + self->state.readonly = 1; Py_INCREF(pattern); self->pattern = (PyObject*) pattern; @@ -2003,6 +2014,7 @@ { SRE_STATE state; int status; + PyThreadState *_save = NULL; PyObject* string; int start = 0; @@ -2020,6 +2032,10 @@ TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr)); + if (state.readonly) { + _save = PyEval_SaveThread(); + } + if (state.charsize == 1) { status = sre_match(&state, PatternObject_GetCode(self)); } else { @@ -2028,6 +2044,10 @@ #endif } + if (state.readonly) { + PyEval_RestoreThread(_save); + } + TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); state_fini(&state); @@ -2045,6 +2065,8 @@ int start = 0; int end = INT_MAX; static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; + PyThreadState *_save = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kw, "O|ii:search", kwlist, &string, &start, &end)) return NULL; @@ -2055,6 +2077,10 @@ TRACE(("|%p|%p|SEARCH\n", PatternObject_GetCode(self), state.ptr)); + if (state.readonly) { + _save = PyEval_SaveThread(); + } + if (state.charsize == 1) { status = sre_search(&state, PatternObject_GetCode(self)); } else { @@ -2063,6 +2089,10 @@ #endif } + if (state.readonly) { + PyEval_RestoreThread(_save); + } + TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); state_fini(&state); @@ -2203,11 +2233,16 @@ while (state.start <= state.end) { PyObject* item; + PyThreadState *_save = NULL; state_reset(&state); state.ptr = state.start; + if (state.readonly) { + _save = PyEval_SaveThread(); + } + if (state.charsize == 1) { status = sre_search(&state, PatternObject_GetCode(self)); } else { @@ -2216,6 +2251,10 @@ #endif } + if (state.readonly) { + PyEval_RestoreThread(_save); + } + if (status <= 0) { if (status == 0) break; @@ -2330,11 +2369,14 @@ last = state.start; while (!maxsplit || n < maxsplit) { - + PyThreadState *_save = NULL; state_reset(&state); state.ptr = state.start; + if (state.readonly) { + _save = PyEval_SaveThread(); + } if (state.charsize == 1) { status = sre_search(&state, PatternObject_GetCode(self)); } else { @@ -2343,6 +2385,10 @@ #endif } + if (state.readonly) { + PyEval_RestoreThread(_save); + } + if (status <= 0) { if (status == 0) break; @@ -2422,6 +2468,7 @@ int status; int n; int i, b, e; + int readonly; int filter_is_callable; if (PyCallable_Check(template)) { @@ -2432,7 +2479,7 @@ } else { /* if not callable, check if it's a literal string */ int literal; - ptr = getstring(template, &n, &b); + ptr = getstring(template, &n, &b, &readonly); if (ptr) { if (b == 1) { literal = sre_literal_template(ptr, n); @@ -2477,11 +2524,17 @@ n = i = 0; while (!count || n < count) { + PyThreadState *_save = NULL; state_reset(&state); state.ptr = state.start; + if (state.readonly) { + _save = PyEval_SaveThread(); + } + + if (state.charsize == 1) { status = sre_search(&state, PatternObject_GetCode(self)); } else { @@ -2490,6 +2543,11 @@ #endif } + + if (state.readonly) { + PyEval_RestoreThread(_save); + } + if (status <= 0) { if (status == 0) break; Common subdirectories: Python-2.4.1-orig/Modules/cjkcodecs and Python-2.4.1/Modules/cjkcodecs Common subdirectories: Python-2.4.1-orig/Modules/expat and Python-2.4.1/Modules/expat diff -ub Python-2.4.1-orig/Modules/sre.h Python-2.4.1/Modules/sre.h --- Python-2.4.1-orig/Modules/sre.h 2004-05-31 04:09:24.000000000 +0100 +++ Python-2.4.1/Modules/sre.h 2005-11-25 12:19:34.000000000 +0000 @@ -69,6 +69,7 @@ /* attributes for the match object */ PyObject* string; int pos, endpos; + int readonly; /* character size */ int charsize; /* registers */