Skip to content

Commit 8274c56

Browse files
committed
select: Work around epoll_event field alignment variation.
1 parent 104471e commit 8274c56

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

select/select.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,27 @@
2222
EPOLL_CTL_DEL = 2
2323
EPOLL_CTL_MOD = 3
2424

25+
# TODO: struct epoll_event's 2nd member is union of uint64_t, etc.
26+
# On x86, uint64_t is 4-byte aligned, on many other platforms - 8-byte.
27+
# Until uctypes module can assign native struct offset, use dirty hack
28+
# below.
29+
if struct.calcsize("IQ") == 12:
30+
epoll_event = "IO"
31+
else:
32+
epoll_event = "QO"
2533

2634
class Epoll:
2735

28-
# Second value is actually of uint64_t size, so struct
29-
# will be smaller on 32bit, but seem to not segfault.
30-
epoll_event = "IO"
31-
3236
def __init__(self, epfd):
3337
self.epfd = epfd
34-
self.evbuf = struct.pack(self.epoll_event, 0, 0)
38+
self.evbuf = struct.pack(epoll_event, 0, None)
3539
self.registry = {}
3640

3741
def register(self, fd, eventmask=EPOLLIN|EPOLLPRI|EPOLLOUT, retval=None):
3842
"retval is extension to stdlib, value to use in results from .poll()."
3943
if retval is None:
4044
retval = fd
41-
s = struct.pack(self.epoll_event, eventmask, retval)
45+
s = struct.pack(epoll_event, eventmask, retval)
4246
r = epoll_ctl(self.epfd, EPOLL_CTL_ADD, fd, s)
4347
if r == -1 and os.errno_.get() == errno.EEXIST:
4448
r = epoll_ctl(self.epfd, EPOLL_CTL_MOD, fd, s)
@@ -59,7 +63,7 @@ def poll(self, timeout=-1):
5963
os.check_error(n)
6064
res = []
6165
if n > 0:
62-
vals = struct.unpack(self.epoll_event, s)
66+
vals = struct.unpack(epoll_event, s)
6367
res.append((vals[1], vals[0]))
6468
return res
6569

0 commit comments

Comments
 (0)