Sun, 10 Jun 2007 16:01:26 +0000
Initial commit:
* Created tree structure
* Committed current version
0 | 1 | module("luaevent", package.seeall) |
2 | require("luaevent.core") | |
3 | ||
4 | local EV_READ = luaevent.core.EV_READ | |
5 | local EV_WRITE = luaevent.core.EV_WRITE | |
6 | local fair = false | |
7 | ||
8 | -- Weak keys.. the keys are the client sockets | |
9 | local clientTable = {} or setmetatable({}, {'__mode', 'k'}) | |
10 | ||
11 | local function getWrapper() | |
12 | local running = coroutine.running() | |
13 | return function(...) | |
14 | print(coroutine.running(), running) | |
15 | print(debug.traceback()) | |
16 | if coroutine.running() == running then return end | |
17 | return select(2, coroutine.resume(running, ...)) | |
18 | end | |
19 | end | |
20 | ||
21 | function send(sock, data, start, stop) | |
22 | local s, err | |
23 | local from = start or 1 | |
24 | local sent = 0 | |
25 | repeat | |
26 | from = from + sent | |
27 | s, err, sent = sock:send(data, from, stop) | |
28 | -- Add extra coro swap for fairness | |
29 | -- CURRENTLY DISABLED FOR TESTING...... | |
30 | if fair and math.random(100) > 90 then | |
31 | coroutine.yield(EV_WRITE) | |
32 | end | |
33 | if s or err ~= "timeout" then return s, err, sent end | |
34 | if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_WRITE, getWrapper()) end | |
35 | coroutine.yield(EV_WRITE) | |
36 | until false | |
37 | end | |
38 | function receive(sock, pattern, part) | |
39 | local s, err | |
40 | pattern = pattern or '*l' | |
41 | repeat | |
42 | s, err, part = sock:receive(pattern, part) | |
43 | if s or err ~= "timeout" then return s, err, part end | |
44 | if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_READ, getWrapper()) end | |
45 | coroutine.yield(EV_READ) | |
46 | until false | |
47 | end | |
48 | -- same as above but with special treatment when reading chunks, | |
49 | -- unblocks on any data received. | |
50 | function receivePartial(client, pattern) | |
51 | local s, err, part | |
52 | pattern = pattern or "*l" | |
53 | repeat | |
54 | s, err, part = client:receive(pattern) | |
55 | if s or ( (type(pattern)=="number") and part~="" and part ~=nil ) or | |
56 | err ~= "timeout" then return s, err, part end | |
57 | if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_READ, getWrapper()) end | |
58 | coroutine.yield(EV_READ) | |
59 | until false | |
60 | end | |
61 | function connect(sock, ...) | |
62 | sock:settimeout(0) | |
63 | local ret, err = sock:connect(...) | |
64 | if ret or err ~= "timeout" then return ret, err end | |
65 | if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_WRITE, getWrapper()) end | |
66 | coroutine.yield(EV_WRITE) | |
67 | ret, err = sock:connect(...) | |
68 | if err == "already connected" then | |
69 | return 1 | |
70 | end | |
71 | return ret, err | |
72 | end | |
73 | -- Deprecated.. | |
74 | function flush(sock) | |
75 | end | |
76 | local function clientCoroutine(sock, handler) | |
77 | -- Figure out what to do ...... | |
78 | return handler(sock) | |
79 | end | |
80 | local function handleClient(co, client, handler) | |
81 | local ok, res, event = coroutine.resume(co, client, handler) | |
82 | end | |
83 | local function serverCoroutine(sock, callback) | |
84 | local listenItem = luaevent.core.addevent(sock, EV_READ, getWrapper()) | |
85 | repeat | |
86 | local event = coroutine.yield(EV_READ) | |
87 | -- Get new socket | |
88 | local client = sock:accept() | |
89 | if client then | |
90 | client:settimeout(0) | |
91 | local co = coroutine.create(clientCoroutine) | |
92 | handleClient(co, client, callback) | |
93 | end | |
94 | until false | |
95 | end | |
96 | function addserver(sock, callback) | |
97 | local coro = coroutine.create(serverCoroutine) | |
98 | assert(coroutine.resume(coro, sock, callback)) | |
99 | end | |
100 | function addthread(func, ...) | |
101 | return coroutine.resume(coroutine.create(func), ...) | |
102 | end | |
103 | local _skt_mt = {__index = { | |
104 | connect = function(self, ...) | |
105 | return connect(self.socket, ...) | |
106 | end, | |
107 | send = function (self, data) | |
108 | return send (self.socket, data) | |
109 | end, | |
110 | ||
111 | receive = function (self, pattern) | |
112 | if (self.timeout==0) then | |
113 | return receivePartial(self.socket, pattern) | |
114 | end | |
115 | return receive (self.socket, pattern) | |
116 | end, | |
117 | ||
118 | flush = function (self) | |
119 | return flush (self.socket) | |
120 | end, | |
121 | ||
122 | settimeout = function (self,time) | |
123 | self.timeout=time | |
124 | return | |
125 | end, | |
126 | }} | |
127 | function wrap(sock) | |
128 | return setmetatable({socket = sock}, _skt_mt) | |
129 | end | |
130 | loop = luaevent.core.loop |