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 */