bdiff.bdiff: release the GIL before doing expensive diff operations stable
authorAugie Fackler <raf@durin42.com>
Fri, 20 Apr 2012 11:08:14 -0500
branchstable
changeset 16477 70b5e25f1598
parent 16476 83622954b64d
child 16478 cbf2ea2f5ca1
bdiff.bdiff: release the GIL before doing expensive diff operations This means that threaded webservers will have more of a chance of doing something useful while the C extension is busy computing a delta. Not doing this was causing problems for Google Code with a 25 meg text file that takes O(7 minutes) to deltify.
mercurial/bdiff.c
--- a/mercurial/bdiff.c	Fri Apr 20 11:57:14 2012 -0500
+++ b/mercurial/bdiff.c	Fri Apr 20 11:08:14 2012 -0500
@@ -339,10 +339,12 @@
 	struct line *al, *bl;
 	struct hunk l, *h;
 	int an, bn, len = 0, la, lb, count;
+	PyThreadState *_save;
 
 	if (!PyArg_ParseTuple(args, "s#s#:bdiff", &sa, &la, &sb, &lb))
 		return NULL;
 
+	_save = PyEval_SaveThread();
 	an = splitlines(sa, la, &al);
 	bn = splitlines(sb, lb, &bl);
 	if (!al || !bl)
@@ -361,6 +363,8 @@
 		la = h->a2;
 		lb = h->b2;
 	}
+	PyEval_RestoreThread(_save);
+	_save = NULL;
 
 	result = PyBytes_FromStringAndSize(NULL, len);
 
@@ -385,6 +389,8 @@
 	}
 
 nomem:
+	if (_save)
+		PyEval_RestoreThread(_save);
 	free(al);
 	free(bl);
 	freehunks(l.next);