forked from douban/greenify
-
Notifications
You must be signed in to change notification settings - Fork 1
/
greenify.pyx
56 lines (49 loc) · 1.54 KB
/
greenify.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
cdef extern from "libgreenify.h":
struct greenify_watcher:
int fd
int events
ctypedef int (*greenify_wait_callback_func_t) (greenify_watcher* watchers, int nwatchers, int timeout)
cdef void greenify_set_wait_callback(greenify_wait_callback_func_t callback)
from gevent.hub import get_hub, getcurrent, Waiter
from gevent.timeout import Timeout
cdef int wait_gevent(greenify_watcher* watchers, int nwatchers, int timeout_in_ms) with gil:
cdef int fd, event
cdef float timeout_in_s
cdef int i
hub = get_hub()
watchers_list = []
for i in range(nwatchers):
fd = watchers[i].fd;
event = watchers[i].events;
watcher = hub.loop.io(fd, event)
watchers_list.append(watcher)
if timeout_in_ms != 0:
timeout_in_s = timeout_in_ms / 1000.0
t = Timeout.start_new(timeout_in_s)
try:
wait(watchers_list)
return 0
except Timeout:
return -1
finally:
t.cancel()
else:
wait(watchers_list)
return 0
def greenify():
greenify_set_wait_callback(wait_gevent)
def wait(watchers):
waiter = Waiter()
switch = waiter.switch
unique = object()
try:
count = len(watchers)
for watcher in watchers:
watcher.start(switch, unique)
result = waiter.get()
assert result is unique, 'Invalid switch into %s: %r' % (getcurrent(), result)
waiter.clear()
return result
finally:
for watcher in watchers:
watcher.stop()