2 LuaEvent - Copyright (C) 2007 Thomas Harning <harningt@gmail.com>
3 Licensed as LGPL - See doc/COPYING for details.
5 module("luaevent", package
.seeall
)
6 require("luaevent.core")
8 local EV_READ
= luaevent
.core
.EV_READ
9 local EV_WRITE
= luaevent
.core
.EV_WRITE
12 -- Weak keys.. the keys are the client sockets
13 local clientTable
= {} or setmetatable({}, {'__mode', 'k'})
15 local function getWrapper()
16 local running
= coroutine
.running()
18 print(coroutine
.running(), running
)
19 print(debug
.traceback())
20 if coroutine
.running() == running
then return end
21 return select(2, coroutine
.resume(running
, ...))
25 function send(sock
, data
, start
, stop
)
27 local from
= start
or 1
31 s
, err
, sent
= sock
:send(data
, from
, stop
)
32 -- Add extra coro swap for fairness
33 -- CURRENTLY DISABLED FOR TESTING......
34 if fair
and math
.random(100) > 90 then
35 coroutine
.yield(EV_WRITE
)
37 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
)
42 function receive(sock
, pattern
, part
)
44 pattern
= pattern
or '*l'
46 s
, err
, part
= sock
:receive(pattern
, part
)
47 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
)
52 -- same as above but with special treatment when reading chunks,
53 -- unblocks on any data received.
54 function receivePartial(client
, pattern
)
56 pattern
= pattern
or "*l"
58 s
, err
, part
= client
:receive(pattern
)
59 if s
or ( (type(pattern
)=="number") and part
~="" and part
~=nil ) or
60 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
)
65 function connect(sock
, ...)
67 local ret
, err
= sock
:connect(...)
68 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
)
71 ret
, err
= sock
:connect(...)
72 if err
== "already connected" then
80 local function clientCoroutine(sock
, handler
)
81 -- Figure out what to do ......
84 local function handleClient(co
, client
, handler
)
85 local ok
, res
, event
= coroutine
.resume(co
, client
, handler
)
87 local function serverCoroutine(sock
, callback
)
88 local listenItem
= luaevent
.core
.addevent(sock
, EV_READ
, getWrapper())
90 local event
= coroutine
.yield(EV_READ
)
92 local client
= sock
:accept()
95 local co
= coroutine
.create(clientCoroutine
)
96 handleClient(co
, client
, callback
)
100 function addserver(sock
, callback
)
101 local coro
= coroutine
.create(serverCoroutine
)
102 assert(coroutine
.resume(coro
, sock
, callback
))
104 function addthread(func
, ...)
105 return coroutine
.resume(coroutine
.create(func
), ...)
107 local _skt_mt
= {__index
= {
108 connect
= function(self
, ...)
109 return connect(self
.socket
, ...)
111 send
= function (self
, data
)
112 return send (self
.socket
, data
)
115 receive
= function (self
, pattern
)
116 if (self
.timeout
==0) then
117 return receivePartial(self
.socket
, pattern
)
119 return receive (self
.socket
, pattern
)
122 flush = function (self
)
123 return flush (self
.socket
)
126 settimeout
= function (self
,time
)
132 return setmetatable({socket
= sock
}, _skt_mt
)
134 loop
= luaevent
.core
.loop