diff --git a/src/python-lz4.c b/src/python-lz4.c index 45fe995..9290918 100644 --- a/src/python-lz4.c +++ b/src/python-lz4.c @@ -73,7 +73,10 @@ static PyObject *compress_with(compressor compress, PyObject *self, PyObject *ar dest = PyBytes_AS_STRING(result); store_le32(dest, source_size); if (source_size > 0) { - int osize = compress(source, dest + hdr_size, source_size); + int osize = -1; + Py_BEGIN_ALLOW_THREADS + osize = compress(source, dest + hdr_size, source_size); + Py_END_ALLOW_THREADS int actual_size = hdr_size + osize; /* Resizes are expensive; tolerate some slop to avoid. */ if (actual_size < (dest_size / 4) * 3) { @@ -115,7 +118,10 @@ static PyObject *py_lz4_uncompress(PyObject *self, PyObject *args) { result = PyBytes_FromStringAndSize(NULL, dest_size); if (result != NULL && dest_size > 0) { char *dest = PyBytes_AS_STRING(result); - int osize = LZ4_decompress_safe(source + hdr_size, dest, source_size - hdr_size, dest_size); + int osize = -1; + Py_BEGIN_ALLOW_THREADS + osize = LZ4_decompress_safe(source + hdr_size, dest, source_size - hdr_size, dest_size); + Py_END_ALLOW_THREADS if (osize < 0) { PyErr_Format(PyExc_ValueError, "corrupt input at byte %d", -osize); Py_CLEAR(result); diff --git a/tests/test.py b/tests/test.py index 9469a03..5b099bb 100644 --- a/tests/test.py +++ b/tests/test.py @@ -2,6 +2,7 @@ import sys +from multiprocessing.pool import ThreadPool import unittest import os @@ -11,6 +12,17 @@ def test_random(self): DATA = os.urandom(128 * 1024) # Read 128kb self.assertEqual(DATA, lz4.loads(lz4.dumps(DATA))) + def test_threads(self): + data = [os.urandom(128 * 1024) for i in range(100)] + def roundtrip(x): + return lz4.loads(lz4.dumps(x)) + + pool = ThreadPool(8) + out = pool.map(roundtrip, data) + assert data == out + pool.close() + + if __name__ == '__main__': unittest.main()