-
Notifications
You must be signed in to change notification settings - Fork 0
/
Event.py
94 lines (80 loc) · 3.58 KB
/
Event.py
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# -*- coding: utf-8 -*-
import time
import select
import sys
from Logging import Logger
from Logging import Level
TYPE_TIMEOUT = 1
TYPE_CLOSED = 2
EVENT_TYPE_FD = 1
EVENT_TYPE_TIME = 2
events = []
logger = Logger("EVENT", Level.INFO)
def getCurrentMills():
return int(round(time.time() * 1000))
def eventTimeout(timeMs, callback, argument, strId):
event = EventData(EVENT_TYPE_TIME, callback, argument)
event.time = getCurrentMills() + timeMs
event.id = strId
logger.log(Level.DEBUG, "Registering timeout " + str(event))
events.append(event)
def eventTimeoutDelete(callback, argument):
for event in events:
if event.type == EVENT_TYPE_TIME and event.callback == callback and event.argument == argument:
logger.log(Level.DEBUG, "Deleting " + str(event))
events.remove(event)
return True
return False
def eventFd(fd, callback, callbackArgument, strId):
logger.log(Level.DEBUG, "EVENT_FD Registered fd:" + str(fd))
event = EventData(EVENT_TYPE_FD, callback, callbackArgument)
event.fd = fd
# file descriptor,
# A file descriptor is either a socket or file object,
# or a small integer gotten from a fileno() method call on one of those.
# in lftp.py createSocket() has one usage :
# Event.eventFd(sock.fileno(), handleDataAvailable, lftpSocket, "DataReceived")
# fileno() 方法返回一个整型的文件描述符(file descriptor FD 整型),可用于底层操作系统的 I/O 操作
event.id = strId
events.append(event)
pass
def eventFdDelete(callback, argument):
for event in events:
if event.type == EVENT_TYPE_FD and event.callback == callback and event.argument == argument:
events.remove(event)
return True
return False
def eventLoop():
LOOP_DELAY = 0.001
while True:
if len(events) < 1:
break
for event in events:
if event.type == EVENT_TYPE_FD:
#print "Found:" + str(event)
# Check if we have some data available
oRead, [], [] = select.select([event.fd], [], [], 0) # 0 - means polling, othewrise timeout time in seconds
# select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)
# rlist,wlist,xlist分别代表等待可读,可写,可读可写的文件的打开。不需要的项传[]
# 第四个参数是timeout的时间,不指定则永远不会timeout
# 返回值与参数一一对应
if len(oRead) > 0:
event.callback(event.fd, event.argument)
else:
#sys.stdout.write('.')
time.sleep(LOOP_DELAY)
elif event.type == EVENT_TYPE_TIME:
logger.log(Level.DEBUG, "Checking for timeout, current time:" + str(getCurrentMills()) + " event timeout:" + str(event.time) + " id:" + str(event.id))
if event.time < getCurrentMills():
logger.log(Level.ERROR, "\n\nTIMEOUT for event: " + str(event))
event.callback(event.argument)
class EventData:
def __init__(self, eventType, eventCallback, eventArgument):
self.type = eventType
self.callback = eventCallback
self.argument = eventArgument
self.fd = None # to be set outside constructor
self.time = None # to be set outside constructor
self.id = None
def __str__(self): # Override string representation
return "Type:" + str(self.type) + " argument:" + str(self.argument) + " callback:" + str(self.callback)