Permalink
Browse files

Initial commit.

Not much, just timer and TCP server support, but I need to start
using version control here :-)
  • Loading branch information...
saghul committed Sep 3, 2011
0 parents commit bb2f86e657ed577b3b2c8722d68fc7bd98c0e953
Showing with 1,375 additions and 0 deletions.
  1. +12 −0 TODO
  2. +6 −0 build_inplace
  3. +22 −0 patches/compile_with_fpic.patch
  4. +10 −0 patches/old/use_fpic.patch
  5. +52 −0 patches/use_lib_prefix.patch
  6. +91 −0 setup.py
  7. +142 −0 src/Loop.c
  8. +358 −0 src/TCPConnection.c
  9. +302 −0 src/TCPServer.c
  10. +257 −0 src/Timer.c
  11. +38 −0 src/pyuv.c
  12. +68 −0 src/pyuv.h
  13. +17 −0 src/utils.c
12 TODO
@@ -0,0 +1,12 @@
- Evaluate if allocating memory from the Python heap would reduce performance
- What about the mallocs libuv may do on its own?
- Set version on setup.py and pass it so that we have pyuv.__version__
- UDP support
- Timer fixes
- Loop must not be a singleton
@@ -0,0 +1,6 @@
#!/bin/bash
rm -f core.* pyuv*.so
rm -rf build
python setup.py build_ext --inplace -g
@@ -0,0 +1,22 @@
--- config-mingw.mk
+++ config-mingw.mk
@@ -24,7 +24,7 @@ CC = $(PREFIX)gcc
AR = $(PREFIX)ar
E=.exe
-CFLAGS=$(CPPFLAGS) -g --std=gnu89 -D_WIN32_WINNT=0x0501 -Isrc/ares/config_win32
+CFLAGS=$(CPPFLAGS) -g -fPIC --std=gnu89 -D_WIN32_WINNT=0x0501 -Isrc/ares/config_win32
LINKFLAGS=-lm
CARES_OBJS += src/ares/windows_port.o
--- config-unix.mk
+++ config-unix.mk
@@ -22,7 +22,7 @@ CC = $(PREFIX)gcc
AR = $(PREFIX)ar
E=
CSTDFLAG=--std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter
-CFLAGS=-g
+CFLAGS=-g -fPIC
CPPFLAGS += -Isrc/unix/ev
LINKFLAGS=-lm
@@ -0,0 +1,10 @@
--- build/all.gyp
+++ build/all.gyp
@@ -127,6 +127,7 @@
]
}, { # Not Windows i.e. POSIX
'cflags': [
+ '-fPIC',
'-g',
'--std=gnu89',
'-pedantic',
@@ -0,0 +1,52 @@
--- Makefile
+++ Makefile
@@ -80,18 +80,18 @@ endif
TESTS=test/echo-server.c test/test-*.c
BENCHMARKS=test/echo-server.c test/dns-server.c test/benchmark-*.c
-all: uv.a test/run-tests test/run-benchmarks
+all: libuv.a test/run-tests test/run-benchmarks
$(CARES_OBJS): %.o: %.c
$(CC) -o $*.o -c $(CFLAGS) $(CPPFLAGS) $< -DHAVE_CONFIG_H
-test/run-tests$(E): test/*.h test/run-tests.c $(RUNNER_SRC) test/runner-unix.c $(TESTS) uv.a
+test/run-tests$(E): test/*.h test/run-tests.c $(RUNNER_SRC) test/runner-unix.c $(TESTS) libuv.a
$(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o test/run-tests test/run-tests.c \
- test/runner.c $(RUNNER_SRC) $(TESTS) uv.a $(RUNNER_LIBS) $(RUNNER_LINKFLAGS)
+ test/runner.c $(RUNNER_SRC) $(TESTS) libuv.a $(RUNNER_LIBS) $(RUNNER_LINKFLAGS)
-test/run-benchmarks$(E): test/*.h test/run-benchmarks.c test/runner.c $(RUNNER_SRC) $(BENCHMARKS) uv.a
+test/run-benchmarks$(E): test/*.h test/run-benchmarks.c test/runner.c $(RUNNER_SRC) $(BENCHMARKS) libuv.a
$(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o test/run-benchmarks test/run-benchmarks.c \
- test/runner.c $(RUNNER_SRC) $(BENCHMARKS) uv.a $(RUNNER_LIBS) $(RUNNER_LINKFLAGS)
+ test/runner.c $(RUNNER_SRC) $(BENCHMARKS) libuv.a $(RUNNER_LIBS) $(RUNNER_LINKFLAGS)
test/echo.o: test/echo.c test/echo.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c test/echo.c -o test/echo.o
--- config-mingw.mk
+++ config-mingw.mk
@@ -36,8 +36,8 @@ RUNNER_LINKFLAGS=$(LINKFLAGS)
RUNNER_LIBS=-lws2_32
RUNNER_SRC=test/runner-win.c
-uv.a: $(WIN_OBJS) src/uv-common.o src/uv-eio.o src/eio/eio.o $(CARES_OBJS)
- $(AR) rcs uv.a src/win/*.o src/uv-common.o src/uv-eio.o src/eio/eio.o $(CARES_OBJS)
+libuv.a: $(WIN_OBJS) src/uv-common.o src/uv-eio.o src/eio/eio.o $(CARES_OBJS)
+ $(AR) rcs libuv.a src/win/*.o src/uv-common.o src/uv-eio.o src/eio/eio.o $(CARES_OBJS)
src/win/%.o: src/win/%.c src/win/internal.h
$(CC) $(CFLAGS) -o $@ -c $<
--- config-unix.mk
+++ config-unix.mk
@@ -95,8 +95,8 @@ endif
RUNNER_LIBS=
RUNNER_SRC=test/runner-unix.c
-uv.a: $(OBJS) src/uv-common.o src/unix/ev/ev.o src/unix/uv-eio.o src/unix/eio/eio.o $(CARES_OBJS)
- $(AR) rcs uv.a $(OBJS) src/uv-common.o src/unix/uv-eio.o src/unix/ev/ev.o src/unix/eio/eio.o $(CARES_OBJS)
+libuv.a: $(OBJS) src/uv-common.o src/unix/ev/ev.o src/unix/uv-eio.o src/unix/eio/eio.o $(CARES_OBJS)
+ $(AR) rcs libuv.a $(OBJS) src/uv-common.o src/unix/uv-eio.o src/unix/ev/ev.o src/unix/eio/eio.o $(CARES_OBJS)
src/unix/%.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) -Isrc $(CFLAGS) -c $< -o $@
@@ -0,0 +1,91 @@
import os
import shutil
import subprocess
import sys
from distutils import log
from distutils.command.build_ext import build_ext
from distutils.core import setup, Extension
from distutils.errors import DistutilsError
class pyuv_build_ext(build_ext):
libuv_repo = 'https://github.com/joyent/libuv.git'
libuv_revision = 'b89f4f34a48594dbb36e1c45eb7879bf5a6ee77f'
libuv_patches = ['patches/compile_with_fpic.patch',
'patches/use_lib_prefix.patch']
@staticmethod
def exec_process(cmdline, silent=True, input=None, **kwargs):
"""Execute a subprocess and returns the returncode, stdout buffer and stderr buffer.
Optionally prints stdout and stderr while running."""
try:
sub = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
stdout, stderr = sub.communicate(input=input)
returncode = sub.returncode
if not silent:
sys.stdout.write(stdout)
sys.stderr.write(stderr)
except OSError,e:
if e.errno == 2:
raise DistutilsError('"%s" is not present on this system' % cmdline[0])
else:
raise
if returncode != 0:
raise DistutilsError('Got return value %d while executing "%s", stderr output was:\n%s' % (returncode, " ".join(cmdline), stderr.rstrip("\n")))
return stdout
def finalize_options(self):
build_ext.finalize_options(self)
self.get_libuv()
self.include_dirs.append(os.path.join(self.libuv_dir, 'include'))
self.library_dirs.append(self.libuv_dir)
self.libraries.append(os.path.join(self.libuv_dir, 'uv'))
self.libraries.append('rt')
self.extra_compile_args = ['-fPIC']
def get_libuv(self):
self.libuv_dir = os.path.join(self.build_temp, 'libuv')
#self.debug_mode = bool(self.debug) or hasattr(sys, 'gettotalrefcount')
def download_libuv():
log.info('Downloading libuv...')
self.exec_process(['git', 'clone', self.libuv_repo, self.libuv_dir])
self.exec_process(['git', 'checkout', self.libuv_revision], cwd=self.libuv_dir)
def patch_libuv():
log.info('Patching libuv...')
for patch_file in self.libuv_patches:
self.exec_process(['patch', '--forward', '-d', self.libuv_dir, '-p0', '-i', os.path.abspath(patch_file)])
def build_libuv():
log.info('Building libuv...')
self.exec_process(['make', 'libuv.a'], cwd=self.libuv_dir)
def update_libuv():
shutil.rmtree(self.libuv_dir)
download_libuv()
patch_libuv()
build_libuv()
if not os.path.exists(self.libuv_dir):
download_libuv()
patch_libuv()
build_libuv()
else:
if not os.path.exists(os.path.join(self.libuv_dir, 'libuv.a')):
log.info('libuv needs to be compiled.')
update_libuv()
else:
rev = self.exec_process(['git', 'rev-list', '--max-count=1', 'HEAD'], cwd=self.libuv_dir)
if rev.strip() == self.libuv_revision:
log.info('No need to download libuv.')
else:
# TODO: implement a command line switch to force rebuild
log.info('libuv needs to be updated.')
update_libuv()
setup(name = 'pyuv',
version = '0.0.0',
description = 'Python bindings for libuv',
cmdclass={'build_ext': pyuv_build_ext},
ext_modules = [Extension('pyuv', sources = ['src/pyuv.c'])]
)
@@ -0,0 +1,142 @@
/*
* TODO:
* - do we need to call uv_init with multiple loops?
* - Loop is not a singleton anymore!
*
*/
static PyObject *
Loop_func_run(Loop *self)
{
Py_BEGIN_ALLOW_THREADS
uv_run(self->uv_loop);
Py_END_ALLOW_THREADS
/* TODO: check for some error? */
Py_RETURN_NONE;
}
static PyObject *
Loop_func_ref(Loop *self)
{
uv_ref(self->uv_loop);
Py_RETURN_NONE;
}
static PyObject *
Loop_func_unref(Loop *self)
{
uv_unref(self->uv_loop);
Py_RETURN_NONE;
}
static int
Loop_tp_init(PyObject *self, PyObject *args, PyObject *kwargs)
{
if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_Check(kwargs) && PyDict_Size(kwargs))) {
PyErr_SetString(PyExc_TypeError, "Loop.__init__() takes no parameters");
return -1;
}
return 0;
}
static PyObject *
Loop_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
static Loop *self = NULL; /* Loop is a singleton */
if (!self) {
self = (Loop *)PyType_GenericNew(type, args, kwargs);
if (!self) {
return NULL;
}
self->uv_loop = uv_loop_new();
/* Initialize libuv */
uv_init();
} else {
Py_INCREF(self);
}
return (PyObject *)self;
}
static int
Loop_tp_traverse(Loop *self, visitproc visit, void *arg)
{
return 0;
}
static int
Loop_tp_clear(Loop *self)
{
return 0;
}
static void
Loop_tp_dealloc(Loop *self)
{
Loop_tp_clear(self);
if (self->uv_loop) {
uv_loop_delete(self->uv_loop);
}
Py_TYPE(self)->tp_free((PyObject *)self);
}
static PyMethodDef
Loop_tp_methods[] = {
{ "run", (PyCFunction)Loop_func_run, METH_NOARGS, "Run the event loop." },
{ "ref", (PyCFunction)Loop_func_ref, METH_NOARGS, "Increase the event loop reference count." },
{ "unref", (PyCFunction)Loop_func_unref, METH_NOARGS, "Decrease the event loop reference count." },
{ NULL }
};
static PyTypeObject LoopType = {
PyVarObject_HEAD_INIT(NULL, 0)
"pyuv.Loop", /*tp_name*/
sizeof(Loop), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Loop_tp_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
0, /*tp_doc*/
(traverseproc)Loop_tp_traverse, /*tp_traverse*/
(inquiry)Loop_tp_clear, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
Loop_tp_methods, /*tp_methods*/
0, /*tp_members*/
0, /*tp_getsets*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
(initproc)Loop_tp_init, /*tp_init*/
0, /*tp_alloc*/
Loop_tp_new, /*tp_new*/
};
Oops, something went wrong.

0 comments on commit bb2f86e

Please sign in to comment.