From f48221f6c09b89d532e44034d7a4e355966faeed Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 3 May 2014 20:06:53 +0300 Subject: [PATCH] select: Need to keep parallel mapping of fd -> callback obj on uPy side. Even despite epoll allows us to map fd onto any object, we need to keep parallel bookkeeping on Python side, to: 1) keep associated object from being garbage collection; 2) to be able to release associated object back to GC when we finished watching fd. --- select/select.py | 5 +++++ select/setup.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/select/select.py b/select/select.py index a7349b8f..5709db0b 100644 --- a/select/select.py +++ b/select/select.py @@ -31,6 +31,7 @@ class Epoll: def __init__(self, epfd): self.epfd = epfd self.evbuf = struct.pack(self.epoll_event, 0, 0) + self.registry = {} def register(self, fd, eventmask=EPOLLIN|EPOLLPRI|EPOLLOUT, retval=None): "retval is extension to stdlib, value to use in results from .poll()." @@ -41,11 +42,15 @@ class Epoll: if r == -1 and os.errno.get() == errno.EEXIST: r = epoll_ctl(self.epfd, EPOLL_CTL_MOD, fd, s) os.check_error(r) + # We must keep reference to retval, or it may be GCed. And we must + # keep mapping from fd to retval to be able to get rid of retval reference. + self.registry[fd] = retval def unregister(self, fd): # Pass dummy event structure, to workaround kernel bug r = epoll_ctl(self.epfd, EPOLL_CTL_DEL, fd, self.evbuf) os.check_error(r) + del self.registry[fd] def poll(self, timeout=-1): s = bytearray(self.evbuf) diff --git a/select/setup.py b/select/setup.py index 7138100e..194a2695 100644 --- a/select/setup.py +++ b/select/setup.py @@ -5,7 +5,7 @@ sys.path.pop(0) from setuptools import setup setup(name='micropython-select', - version='0.0.4', + version='0.0.5', description='select module to MicroPython', url='https://github.com/micropython/micropython/issues/405', author='Paul Sokolovsky',