Commit 7657af63 authored by Hasan Alayli's avatar Hasan Alayli

fixing linux poller

parent 65577cc3
...@@ -173,7 +173,7 @@ cdef class event_key: ...@@ -173,7 +173,7 @@ cdef class event_key:
cdef int fd cdef int fd
cdef int op cdef int op
def __cinit__ (self, int events, int fd, int op=EPOLL_CTL_MOD): def __cinit__ (self, int events, int fd, int op=EPOLL_CTL_ADD):
self.events = events self.events = events
self.fd = fd self.fd = fd
self.op = op self.op = op
...@@ -240,7 +240,7 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t ...@@ -240,7 +240,7 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t
self.event_map[ek] = target self.event_map[ek] = target
e = &(self.change_list[self.change_list_index]) e = &(self.change_list[self.change_list_index])
e.data.fd = ek.fd e.data.fd = ek.fd
e.op = EPOLL_CTL_MOD e.op = EPOLL_CTL_ADD
e.events = ek.events e.events = ek.events
e.flags = EPOLLONESHOT e.flags = EPOLLONESHOT
self.change_list_index = self.change_list_index + 1 self.change_list_index = self.change_list_index + 1
...@@ -326,7 +326,7 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t ...@@ -326,7 +326,7 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t
#if r < 0: #if r < 0:
# raise_oserror() # raise_oserror()
def set_handler (self, object event, object handler, int flags=EPOLLONESHOT, int op=EPOLL_CTL_MOD): def set_handler (self, object event, object handler, int flags=EPOLLONESHOT, int op=EPOLL_CTL_ADD):
"""Add a event handler. """Add a event handler.
This is a low-level interface to register a event handler. This is a low-level interface to register a event handler.
...@@ -424,8 +424,9 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t ...@@ -424,8 +424,9 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t
for i from 0 <= i < self.change_list_index: for i from 0 <= i < self.change_list_index:
e = &(self.change_list[i]) e = &(self.change_list[i])
org_e.events = e.events | e.flags org_e.events = e.events | EPOLLET
org_e.data.fd = e.data.fd org_e.data.fd = e.data.fd
# try to add fd to epoll
if e.events != 0: if e.events != 0:
r = epoll_ctl ( r = epoll_ctl (
self.ep_fd, self.ep_fd,
...@@ -433,10 +434,12 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t ...@@ -433,10 +434,12 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t
org_e.data.fd, org_e.data.fd,
&org_e &org_e
) )
if r == -1 and (libc.errno == libc.ENOENT): # if fd already exist, then modify to to register intrest in read/write
if r == -1 and (libc.errno == libc.EEXIST):
org_e.events = e.events | EPOLLOUT | EPOLLIN | EPOLLET
r = epoll_ctl ( r = epoll_ctl (
self.ep_fd, self.ep_fd,
EPOLL_CTL_ADD, EPOLL_CTL_MOD,
org_e.data.fd, org_e.data.fd,
&org_e &org_e
) )
...@@ -474,36 +477,48 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t ...@@ -474,36 +477,48 @@ cdef public class queue_poller [ object queue_poller_object, type queue_poller_t
new_e.events = events[i].events new_e.events = events[i].events
new_e.err = 0 new_e.err = 0
#print 'epoll_wait event >>>>>> %s for %s' % (new_e.events, new_e.data.fd) #print 'epoll_wait event >>>>>> %s for %s' % (new_e.events, new_e.data.fd)
if new_e.events & EPOLLERR or new_e.events & EPOLLHUP: tmp = (EPOLLIN, EPOLLOUT)
#print 'epoll_wait event >>>>>> %s for %s' % (new_e.events, new_e.data.fd) if events[i].events & tmp[0] and events[i].events & tmp[1]:
new_e.events = new_e.events & ~(EPOLLHUP) pass
new_e.events = new_e.events & ~(EPOLLERR)
new_e.err = 104
# epoll doesn't specify the last event we had registered so make a guess
if new_e.events == 0:
new_e.events = EPOLLIN
try:
et = self.event_map[event_key(EPOLLIN, new_e.data.fd)]
except KeyError:
new_e.events = EPOLLOUT
_py_event = py_event()
_py_event.__fast_init__(&new_e)
ek = event_key (new_e.events, new_e.data.fd)
try:
et = self.event_map[ek]
except KeyError:
W ('un-handled event: fd=%s events=%s\n' % (new_e.data.fd, new_e.events))
else: else:
assert et.status != EVENT_STATUS_ABORTED tmp = [0]
for j from 0 <= j < len(tmp):
if len(tmp) == 2:
if events[i].events & tmp[j]:
new_e.events = events[i].events & ~(tmp[j])
if new_e.events & EPOLLERR or new_e.events & EPOLLHUP:
#print 'epoll_wait event >>>>>> %s for %s' % (new_e.events, new_e.data.fd)
new_e.events = new_e.events & ~(EPOLLHUP)
new_e.events = new_e.events & ~(EPOLLERR)
new_e.err = 104
# epoll doesn't specify the last event we had registered so make a guess
if new_e.events == 0:
new_e.events = EPOLLIN
try:
et = self.event_map[event_key(EPOLLIN, new_e.data.fd)]
except KeyError:
new_e.events = EPOLLOUT
_py_event = py_event()
_py_event.__fast_init__(&new_e)
ek = event_key (new_e.events, new_e.data.fd)
if not PyDict_Contains (self.event_map, ek):
continue
try: try:
et.status = EVENT_STATUS_FIRED et = self.event_map[ek]
if isinstance (et.target, coro): except KeyError:
co = et.target W ('un-handled event: fd=%s events=%s\n' % (new_e.data.fd, new_e.events))
co._schedule (_py_event) else:
else: assert et.status != EVENT_STATUS_ABORTED
# assumes kt.target is a callable object try:
_spawn(et.target, (_py_event,), {}) et.status = EVENT_STATUS_FIRED
finally: if isinstance (et.target, coro):
if et.flags & TARGET_FLAG_ONESHOT: co = et.target
del self.event_map[ek] co._schedule (_py_event)
else:
# assumes kt.target is a callable object
_spawn(et.target, (_py_event,), {})
finally:
if et.flags & TARGET_FLAG_ONESHOT:
del self.event_map[ek]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment