[pypy-svn] pypy kqueue: merged upstream

alex_gaynor commits-noreply at bitbucket.org
Sat Apr 9 20:55:11 CEST 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: kqueue
Changeset: r43256:0b624568902e
Date: 2011-04-09 14:33 -0400
http://bitbucket.org/pypy/pypy/changeset/0b624568902e/

Log:	merged upstream

diff --git a/pypy/module/select/test/test_kqueue.py b/pypy/module/select/test/test_kqueue.py
--- a/pypy/module/select/test/test_kqueue.py
+++ b/pypy/module/select/test/test_kqueue.py
@@ -168,4 +168,4 @@
 
         a.close()
         b.close()
-        kq.close()
\ No newline at end of file
+        kq.close()

diff --git a/.hgsubstate b/.hgsubstate
new file mode 100644

diff --git a/pypy/module/select/__init__.py b/pypy/module/select/__init__.py
--- a/pypy/module/select/__init__.py
+++ b/pypy/module/select/__init__.py
@@ -17,18 +17,21 @@
 
     # TODO: this doesn't feel right...
     if hasattr(select, "epoll"):
-        interpleveldefs['epoll'] = 'interp_epoll.W_Epoll'
-        symbols = [
+        interpleveldefs["epoll"] = "interp_epoll.W_Epoll"
+        for symbol in [
             "EPOLLIN", "EPOLLOUT", "EPOLLPRI", "EPOLLERR", "EPOLLHUP",
             "EPOLLET", "EPOLLONESHOT", "EPOLLRDNORM", "EPOLLRDBAND",
             "EPOLLWRNORM", "EPOLLWRBAND", "EPOLLMSG"
-        ]
-        for symbol in symbols:
+        ]:
             if hasattr(select, symbol):
                 interpleveldefs[symbol] = "space.wrap(%s)" % getattr(select, symbol)
 
     if hasattr(select, "kqueue"):
         interpleveldefs["kqueue"] = "interp_kqueue.W_Kqueue"
+        interpleveldefs["kevent"] = "interp_kqueue.W_Kevent"
+
+        for symbol in ["KQ_FILTER_READ", "KQ_FILTER_WRITE", "KQ_EV_ADD", "KQ_EV_ONESHOT", "KQ_EV_ENABLE"]:
+            interpleveldefs[symbol] = "space.wrap(interp_kqueue.%s)" % symbol
 
 
     def buildloaders(cls):

diff --git a/pypy/module/select/interp_kqueue.py b/pypy/module/select/interp_kqueue.py
--- a/pypy/module/select/interp_kqueue.py
+++ b/pypy/module/select/interp_kqueue.py
@@ -1,5 +1,190 @@
 from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.error import OperationError, exception_from_errno
+from pypy.interpreter.gateway import interp2app, unwrap_spec
+from pypy.interpreter.typedef import TypeDef, generic_new_descr, GetSetProperty
+from pypy.rlib._rsocket_rffi import socketclose
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.tool import rffi_platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+
+
+eci = ExternalCompilationInfo(
+    includes = ["sys/event.h"],
+)
+
+
+class CConfig:
+    _compilation_info_ = eci
+
+CConfig.kevent = rffi_platform.Struct("struct kevent", [
+    ("ident", rffi.UINT),
+    ("filter", rffi.INT),
+    ("flags", rffi.UINT),
+    ("fflags", rffi.UINT),
+    ("data", rffi.INT),
+    ("udata", rffi.VOIDP),
+])
+
+for symbol in ["EVFILT_READ", "EVFILT_WRITE", "EV_ADD", "EV_ONESHOT", "EV_ENABLE"]:
+    setattr(CConfig, symbol, rffi_platform.DefinedConstantInteger(symbol))
+
+cconfig = rffi_platform.configure(CConfig)
+
+kevent = cconfig["kevent"]
+KQ_FILTER_READ = cconfig["EVFILT_READ"]
+KQ_FILTER_WRITE = cconfig["EVFILT_WRITE"]
+KQ_EV_ADD = cconfig["EV_ADD"]
+KQ_EV_ONESHOT = cconfig["EV_ONESHOT"]
+KQ_EV_ENABLE = cconfig["EV_ENABLE"]
+
+kqueue = rffi.llexternal("kqueue",
+    [],
+    rffi.INT,
+    compilation_info=eci
+)
+    
 
 
 class W_Kqueue(Wrappable):
-    pass
\ No newline at end of file
+    def __init__(self, space, kqfd):
+        self.kqfd = kqfd
+
+    def descr__new__(space, w_subtype):
+        kqfd = kqueue()
+        if kqfd < 0:
+            raise exception_from_errno(space, space.w_IOError)
+        return space.wrap(W_Kqueue(space, kqfd))
+
+    @unwrap_spec(fd=int)
+    def descr_fromfd(space, w_cls, fd):
+        return space.wrap(W_Kqueue(space, fd))
+
+    def __del__(self):
+        self.close()
+
+    def get_closed(self):
+        return self.kqfd < 0
+
+    def close(self):
+        if not self.get_closed():
+            socketclose(self.kqfd)
+            self.kqfd = -1
+
+    def check_closed(self, space):
+        if self.get_closed():
+            raise OperationError(space.w_ValueError, space.wrap("I/O operation on closed kqueue fd"))
+
+    def descr_get_closed(self, space):
+        return space.wrap(self.get_closed())
+
+    def descr_fileno(self, space):
+        self.check_closed(space)
+        return space.wrap(self.kqfd)
+
+    def descr_close(self, space):
+        self.close()
+
+
+W_Kqueue.typedef = TypeDef("select.kqueue",
+    __new__ = interp2app(W_Kqueue.descr__new__.im_func),
+    fromfd = interp2app(W_Kqueue.descr_fromfd.im_func, as_classmethod=True),
+
+    closed = GetSetProperty(W_Kqueue.descr_get_closed),
+    fileno = interp2app(W_Kqueue.descr_fileno),
+
+    close = interp2app(W_Kqueue.descr_close),
+)
+W_Kqueue.typedef.acceptable_as_base_class = False
+
+
+class W_Kevent(Wrappable):
+    def __init__(self, space):
+        self.event = lltype.nullptr(kevent)
+
+    def __del__(self):
+        if self.event:
+            lltype.free(self.event, flavor="raw")
+
+    @unwrap_spec(filter=int, flags=int, fflags=int, data=int, udata=int)
+    def descr__init__(self, space, w_ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0):
+        ident = space.c_filedescriptor_w(w_ident)
+        
+        self.event = lltype.malloc(kevent, flavor="raw")
+        rffi.setintfield(self.event, "c_ident", ident)
+        rffi.setintfield(self.event, "c_filter", filter)
+        rffi.setintfield(self.event, "c_flags", flags)
+        rffi.setintfield(self.event, "c_fflags", fflags)
+        rffi.setintfield(self.event, "c_data", data)
+        self.event.c_udata = rffi.cast(rffi.VOIDP, udata)
+
+    def _compare_all_fields(self, other, op):
+        for field in ["ident", "filter", "flags", "fflags", "data", "udata"]:
+            lhs = getattr(self.event, "c_%s" % field)
+            rhs = getattr(other.event, "c_%s" % field)
+            if op == "eq":
+                if lhs != rhs:
+                    return False
+            elif op == "lt":
+                if lhs < rhs:
+                    return True
+            elif op == "ge":
+                if lhs >= rhs:
+                    return True
+            else:
+                assert False
+
+        if op == "eq":
+            return True
+        elif op == "lt":
+            return False
+        elif op == "ge":
+            return False
+
+    def compare_all_fields(self, space, other, op):
+        if not space.interp_w(W_Kevent, other):
+            return space.w_NotImplemented
+        return space.wrap(self._compare_all_fields(other, op))
+
+    def descr__eq__(self, space, w_other):
+        return self.compare_all_fields(space, w_other, "eq")
+
+    def descr__lt__(self, space, w_other):
+        return self.compare_all_fields(space, w_other, "lt")
+
+    def descr__ge__(self, space, w_other):
+        return self.compare_all_fields(space, w_other, "ge")
+
+    def descr_get_ident(self, space):
+        return space.wrap(self.event.c_ident)
+
+    def descr_get_filter(self, space):
+        return space.wrap(self.event.c_filter)
+
+    def descr_get_flags(self, space):
+        return space.wrap(self.event.c_flags)
+
+    def descr_get_fflags(self, space):
+        return space.wrap(self.event.c_fflags)
+
+    def descr_get_data(self, space):
+        return space.wrap(self.event.c_data)
+
+    def descr_get_udata(self, space):
+        return space.wrap(rffi.cast(rffi.INT, self.event.c_udata))
+
+
+W_Kevent.typedef = TypeDef("select.kevent",
+    __new__ = generic_new_descr(W_Kevent),
+    __init__ = interp2app(W_Kevent.descr__init__),
+    __eq__ = interp2app(W_Kevent.descr__eq__),
+    __lt__ = interp2app(W_Kevent.descr__lt__),
+    __ge__ = interp2app(W_Kevent.descr__ge__),
+
+    ident = GetSetProperty(W_Kevent.descr_get_ident),
+    filter = GetSetProperty(W_Kevent.descr_get_filter),
+    flags = GetSetProperty(W_Kevent.descr_get_flags),
+    fflags = GetSetProperty(W_Kevent.descr_get_fflags),
+    data = GetSetProperty(W_Kevent.descr_get_data),
+    udata = GetSetProperty(W_Kevent.descr_get_udata),
+)
+W_Kevent.typedef.acceptable_as_base_class = False


More information about the Pypy-commit mailing list