]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Replace cython-based extension module with a hand-written one.
authorBen Darnell <ben@bendarnell.com>
Tue, 5 Nov 2013 22:39:03 +0000 (17:39 -0500)
committerBen Darnell <ben@bendarnell.com>
Tue, 5 Nov 2013 22:58:31 +0000 (17:58 -0500)
This avoids the complexity of ensuring that cython is installed
at build time.

.gitignore
MANIFEST.in
setup.py
tornado/speedups.c [new file with mode: 0644]
tornado/speedups.pyx [deleted file]
tornado/websocket.py
tox.ini

index 63672ee825efdb030ab293f5f207278e5f496dd3..4d7fa457a409848af6e0a5b7151930bfb59cde24 100644 (file)
@@ -14,6 +14,3 @@ MANIFEST
 /env/
 # Used in demo apps
 secrets.cfg
-
-# cython-generated
-tornado/speedups.c
index 206ea270071bc7d6b923eed9b0386c26f0f210cd..1811a9cb203067f1ff343be8c6a17ddd69ddaaca 100644 (file)
@@ -1,5 +1,5 @@
 recursive-include demos *.py *.yaml *.html *.css *.js *.xml *.sql README
-include tornado/speedups.pyx
+include tornado/speedups.c
 include tornado/ca-certificates.crt
 include tornado/test/README
 include tornado/test/csv_translations/fr_FR.csv
index 5d6032277854b9df6248e8b1dfb375acbed61e21..6fba3988523246c1166407c0e2ec2f023cc346f1 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -14,6 +14,7 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
+import platform
 import sys
 
 try:
@@ -24,10 +25,7 @@ except ImportError:
     setuptools = None
     from distutils.core import setup
 
-try:
-    from Cython.Build import cythonize
-except ImportError:
-    cythonize = None
+from distutils.core import Extension
 
 kwargs = {}
 
@@ -36,8 +34,13 @@ version = "3.2.dev2"
 with open('README.rst') as f:
     kwargs['long_description'] = f.read()
 
-if cythonize is not None:
-    kwargs['ext_modules'] = cythonize('tornado/speedups.pyx')
+if platform.python_implementation() == 'CPython':
+    # This extension builds and works on pypy as well, although pypy's jit
+    # produces equivalent performance.
+    kwargs['ext_modules'] = [
+        Extension('tornado.speedups',
+                  sources=['tornado/speedups.c']),
+    ]
 
 if setuptools is not None:
     # If setuptools is not available, you're on your own for dependencies.
diff --git a/tornado/speedups.c b/tornado/speedups.c
new file mode 100644 (file)
index 0000000..163023c
--- /dev/null
@@ -0,0 +1,48 @@
+#include <Python.h>
+
+static PyObject* websocket_mask(PyObject* self, PyObject* args) {
+    const char* mask;
+    int mask_len;
+    const char* data;
+    int data_len;
+
+    if (!PyArg_ParseTuple(args, "s#s#", &mask, &mask_len, &data, &data_len)) {
+        return NULL;
+    }
+
+    PyObject* result = PyBytes_FromStringAndSize(NULL, data_len);
+    if (!result) {
+        return NULL;
+    }
+    char* buf = PyBytes_AsString(result);
+    for (int i = 0; i < data_len; i++) {
+        buf[i] = data[i] ^ mask[i % 4];
+    }
+
+    return result;
+}
+
+static PyMethodDef methods[] = {
+    {"websocket_mask",  websocket_mask, METH_VARARGS, ""},
+    {NULL, NULL, 0, NULL}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef speedupsmodule = {
+   PyModuleDef_HEAD_INIT,
+   "speedups",
+   NULL,
+   -1,
+   methods
+};
+
+PyMODINIT_FUNC
+PyInit_speedups() {
+    return PyModule_Create(&speedupsmodule);
+}
+#else  // Python 2.x
+PyMODINIT_FUNC
+initspeedups() {
+    Py_InitModule("tornado.speedups", methods);
+}
+#endif
diff --git a/tornado/speedups.pyx b/tornado/speedups.pyx
deleted file mode 100644 (file)
index 4634445..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- python -*-
-from cpython.mem cimport PyMem_Malloc, PyMem_Free
-
-def websocket_mask(bytes mask_bytes, bytes data_bytes):
-    cdef size_t data_len = len(data_bytes)
-    cdef char* data = data_bytes
-    cdef char* mask = mask_bytes
-    cdef size_t i
-    cdef char* buf = <char*> PyMem_Malloc(data_len)
-    try:
-        for i in xrange(data_len):
-            buf[i] = data[i] ^ mask[i % 4]
-        # Is there a zero-copy equivalent of this?
-        return <bytes>(buf[:data_len])
-    finally:
-        PyMem_Free(buf)
index e394242408df8c3298db3c6ed5dc702e36eb01e3..3a83994c0d82b11e955d9469612d5672f6ffa679 100644 (file)
@@ -908,7 +908,12 @@ def _websocket_mask_python(mask, data):
     else:
         return unmasked.tostring()
 
-try:
-    from tornado.speedups import websocket_mask as _websocket_mask
-except ImportError:
+if os.environ.get('TORNADO_NO_EXTENSION'):
+    # This environment variable exists to make it easier to do performance comparisons;
+    # it's not guaranteed to remain supported in the future.
     _websocket_mask = _websocket_mask_python
+else:
+    try:
+        from tornado.speedups import websocket_mask as _websocket_mask
+    except ImportError:
+        _websocket_mask = _websocket_mask_python
diff --git a/tox.ini b/tox.ini
index 2d9afaffd0ab417806814144fb34e3027287405d..77918ef08ddc4ebffd3c2fea9a147d448f9cfef0 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -30,7 +30,6 @@ deps = unittest2
 [testenv:py26-full]
 basepython = python2.6
 deps =
-     Cython
      futures
      mock
      pycurl
@@ -40,7 +39,6 @@ deps =
 [testenv:py27-full]
 basepython = python2.7
 deps =
-     Cython
      futures
      mock
      pycurl
@@ -150,7 +148,6 @@ commands = python -m tornado.test.runtests --locale=zh_TW {posargs:}
 # there.
 basepython = pypy
 deps =
-     Cython
      futures
      mock
 
@@ -171,7 +168,6 @@ setenv = LANG=en_US.utf-8
 [testenv:py32-full]
 basepython = python3.2
 deps =
-     Cython
      mock
 
 [testenv:py33]