luaevent/luaevent.lua

changeset 2
01b3a96ae760
parent 1
31c782cfe7fe
child 3
5999243fab1d
equal deleted inserted replaced
1:31c782cfe7fe 2:01b3a96ae760
7 7
8 local EV_READ = luaevent.core.EV_READ 8 local EV_READ = luaevent.core.EV_READ
9 local EV_WRITE = luaevent.core.EV_WRITE 9 local EV_WRITE = luaevent.core.EV_WRITE
10 local fair = false 10 local fair = false
11 11
12 local hookedObjectMt = false
13
12 -- Weak keys.. the keys are the client sockets 14 -- Weak keys.. the keys are the client sockets
13 local clientTable = {} or setmetatable({}, {'__mode', 'k'}) 15 local clientTable = setmetatable({}, {'__mode', 'k'})
14
15 local function getWrapper()
16 local running = coroutine.running()
17 return function(...)
18 print(coroutine.running(), running)
19 print(debug.traceback())
20 if coroutine.running() == running then return end
21 return select(2, coroutine.resume(running, ...))
22 end
23 end
24 16
25 function send(sock, data, start, stop) 17 function send(sock, data, start, stop)
26 local s, err 18 local s, err
27 local from = start or 1 19 local from = start or 1
28 local sent = 0 20 local sent = 0
33 -- CURRENTLY DISABLED FOR TESTING...... 25 -- CURRENTLY DISABLED FOR TESTING......
34 if fair and math.random(100) > 90 then 26 if fair and math.random(100) > 90 then
35 coroutine.yield(EV_WRITE) 27 coroutine.yield(EV_WRITE)
36 end 28 end
37 if s or err ~= "timeout" then return s, err, sent end 29 if s or err ~= "timeout" then return s, err, sent end
38 if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_WRITE, getWrapper()) end
39 coroutine.yield(EV_WRITE) 30 coroutine.yield(EV_WRITE)
40 until false 31 until false
41 end 32 end
42 function receive(sock, pattern, part) 33 function receive(sock, pattern, part)
43 local s, err 34 local s, err
44 pattern = pattern or '*l' 35 pattern = pattern or '*l'
45 repeat 36 repeat
46 s, err, part = sock:receive(pattern, part) 37 s, err, part = sock:receive(pattern, part)
47 if s or err ~= "timeout" then return s, err, part end 38 if s or err ~= "timeout" then return s, err, part end
48 if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_READ, getWrapper()) end
49 coroutine.yield(EV_READ) 39 coroutine.yield(EV_READ)
50 until false 40 until false
51 end 41 end
52 -- same as above but with special treatment when reading chunks, 42 -- same as above but with special treatment when reading chunks,
53 -- unblocks on any data received. 43 -- unblocks on any data received.
56 pattern = pattern or "*l" 46 pattern = pattern or "*l"
57 repeat 47 repeat
58 s, err, part = client:receive(pattern) 48 s, err, part = client:receive(pattern)
59 if s or ( (type(pattern)=="number") and part~="" and part ~=nil ) or 49 if s or ( (type(pattern)=="number") and part~="" and part ~=nil ) or
60 err ~= "timeout" then return s, err, part end 50 err ~= "timeout" then return s, err, part end
61 if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_READ, getWrapper()) end
62 coroutine.yield(EV_READ) 51 coroutine.yield(EV_READ)
63 until false 52 until false
64 end 53 end
65 function connect(sock, ...) 54 function connect(sock, ...)
66 sock:settimeout(0) 55 sock:settimeout(0)
67 local ret, err = sock:connect(...) 56 local ret, err = sock:connect(...)
68 if ret or err ~= "timeout" then return ret, err end 57 if ret or err ~= "timeout" then return ret, err end
69 if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_WRITE, getWrapper()) end
70 coroutine.yield(EV_WRITE) 58 coroutine.yield(EV_WRITE)
71 ret, err = sock:connect(...) 59 ret, err = sock:connect(...)
72 if err == "already connected" then 60 if err == "already connected" then
73 return 1 61 return 1
74 end 62 end
79 end 67 end
80 local function clientCoroutine(sock, handler) 68 local function clientCoroutine(sock, handler)
81 -- Figure out what to do ...... 69 -- Figure out what to do ......
82 return handler(sock) 70 return handler(sock)
83 end 71 end
84 local function handleClient(co, client, handler) 72
85 local ok, res, event = coroutine.resume(co, client, handler)
86 end
87 local function serverCoroutine(sock, callback) 73 local function serverCoroutine(sock, callback)
88 local listenItem = luaevent.core.addevent(sock, EV_READ, getWrapper())
89 repeat 74 repeat
90 local event = coroutine.yield(EV_READ) 75 local event = coroutine.yield(EV_READ)
91 -- Get new socket 76 -- Get new socket
92 local client = sock:accept() 77 local client = sock:accept()
93 if client then 78 if client then
79 --cl[#cl + 1] = client
94 client:settimeout(0) 80 client:settimeout(0)
95 local co = coroutine.create(clientCoroutine) 81 local coFunc = coroutine.wrap(clientCoroutine)
96 handleClient(co, client, callback) 82 clientTable[client] = luaevent.core.addevent(client, coFunc, client, callback)
97 end 83 end
98 until false 84 until false
99 end 85 end
86
87 local oldAddEvent = luaevent.core.addevent
88 luaevent.core.addevent = function(...)
89 local item = oldAddEvent(...)
90 print("SETUP ITEM FOR: ", debug.getmetatable(item).getfd(item))
91 if not hookedObjectMt then
92 hookedObjectMt = true
93 local mt = debug.getmetatable(item)
94 local oldGC = mt.__gc
95 mt.__gc = function(...)
96 print("RELEASING ITEM FOR: ", mt.getfd(...))
97 return oldGC(...)
98 end
99 end
100 return item
101 end
102
100 function addserver(sock, callback) 103 function addserver(sock, callback)
101 local coro = coroutine.create(serverCoroutine) 104 local coFunc = coroutine.wrap(serverCoroutine)
102 assert(coroutine.resume(coro, sock, callback)) 105 clientTable[sock] = luaevent.core.addevent(sock, coFunc, sock, callback)
103 end 106 end
104 function addthread(func, ...) 107 function addthread(sock, func, ...)
105 return coroutine.resume(coroutine.create(func), ...) 108 local coFunc = coroutine.wrap(func)
109 clientTable[sock] = luaevent.core.addevent(sock, coFunc, ...)
106 end 110 end
107 local _skt_mt = {__index = { 111 local _skt_mt = {__index = {
108 connect = function(self, ...) 112 connect = function(self, ...)
109 return connect(self.socket, ...) 113 return connect(self.socket, ...)
110 end, 114 end,

mercurial