1 |
commit: b986bcdd49c5523ffe6972377071d556a819c776 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Aug 22 05:38:57 2012 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Aug 22 05:38:57 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=b986bcdd |
7 |
|
8 |
EventLoop: use epoll when available |
9 |
|
10 |
This will fix bug #432024. |
11 |
|
12 |
--- |
13 |
pym/portage/util/_eventloop/EventLoop.py | 59 ++++++++++++++++++++++++++---- |
14 |
1 files changed, 52 insertions(+), 7 deletions(-) |
15 |
|
16 |
diff --git a/pym/portage/util/_eventloop/EventLoop.py b/pym/portage/util/_eventloop/EventLoop.py |
17 |
index bbbce52..eed68fe 100644 |
18 |
--- a/pym/portage/util/_eventloop/EventLoop.py |
19 |
+++ b/pym/portage/util/_eventloop/EventLoop.py |
20 |
@@ -52,14 +52,25 @@ class EventLoop(object): |
21 |
self._idle_callbacks = {} |
22 |
self._timeout_handlers = {} |
23 |
self._timeout_interval = None |
24 |
- self._poll_obj = create_poll_instance() |
25 |
|
26 |
- self.IO_ERR = PollConstants.POLLERR |
27 |
- self.IO_HUP = PollConstants.POLLHUP |
28 |
- self.IO_IN = PollConstants.POLLIN |
29 |
- self.IO_NVAL = PollConstants.POLLNVAL |
30 |
- self.IO_OUT = PollConstants.POLLOUT |
31 |
- self.IO_PRI = PollConstants.POLLPRI |
32 |
+ try: |
33 |
+ select.epoll |
34 |
+ except AttributeError: |
35 |
+ self._poll_obj = create_poll_instance() |
36 |
+ self.IO_ERR = PollConstants.POLLERR |
37 |
+ self.IO_HUP = PollConstants.POLLHUP |
38 |
+ self.IO_IN = PollConstants.POLLIN |
39 |
+ self.IO_NVAL = PollConstants.POLLNVAL |
40 |
+ self.IO_OUT = PollConstants.POLLOUT |
41 |
+ self.IO_PRI = PollConstants.POLLPRI |
42 |
+ else: |
43 |
+ self._poll_obj = _epoll_adapter(select.epoll()) |
44 |
+ self.IO_ERR = select.EPOLLERR |
45 |
+ self.IO_HUP = select.EPOLLHUP |
46 |
+ self.IO_IN = select.EPOLLIN |
47 |
+ self.IO_NVAL = 0 |
48 |
+ self.IO_OUT = select.EPOLLOUT |
49 |
+ self.IO_PRI = select.EPOLLPRI |
50 |
|
51 |
self._child_handlers = {} |
52 |
self._sigchld_read = None |
53 |
@@ -488,3 +499,37 @@ def create_poll_instance(): |
54 |
if can_poll_device(): |
55 |
return select.poll() |
56 |
return PollSelectAdapter() |
57 |
+ |
58 |
+class _epoll_adapter(object): |
59 |
+ """ |
60 |
+ Wraps a select.epoll instance in order to make it compatible |
61 |
+ with select.poll instances. This is necessary since epoll instances |
62 |
+ interpret timeout arguments differently. Note that the file descriptor |
63 |
+ that is associated with an epoll instance will close automatically when |
64 |
+ it is garbage collected, so it's not necessary to close it explicitly. |
65 |
+ """ |
66 |
+ __slots__ = ('_epoll_obj',) |
67 |
+ |
68 |
+ def __init__(self, epoll_obj): |
69 |
+ self._epoll_obj = epoll_obj |
70 |
+ |
71 |
+ def register(self, fd, *args): |
72 |
+ self._epoll_obj.register(fd, *args) |
73 |
+ |
74 |
+ def unregister(self, fd): |
75 |
+ self._epoll_obj.unregister(fd) |
76 |
+ |
77 |
+ def poll(self, *args): |
78 |
+ if len(args) > 1: |
79 |
+ raise TypeError( |
80 |
+ "poll expected at most 2 arguments, got " + \ |
81 |
+ repr(1 + len(args))) |
82 |
+ timeout = -1 |
83 |
+ if args: |
84 |
+ timeout = args[0] |
85 |
+ if timeout is None or timeout < 0: |
86 |
+ timeout = -1 |
87 |
+ elif timeout != 0: |
88 |
+ timeout = timeout / 1000 |
89 |
+ |
90 |
+ return self._epoll_obj.poll(timeout) |