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 local hookedObjectMt
= false
14 -- Weak keys.. the keys are the client sockets
15 local clientTable
= setmetatable({}, {'__mode', 'k'})
17 function send(sock
, data
, start
, stop
)
19 local from
= start
or 1
23 s
, err
, sent
= sock
:send(data
, from
, stop
)
24 -- Add extra coro swap for fairness
25 -- CURRENTLY DISABLED FOR TESTING......
26 if fair
and math
.random(100) > 90 then
27 coroutine
.yield(EV_WRITE
)
29 if s
or err
~= "timeout" then return s
, err
, sent
end
30 coroutine
.yield(EV_WRITE
)
33 function receive(sock
, pattern
, part
)
35 pattern
= pattern
or '*l'
37 s
, err
, part
= sock
:receive(pattern
, part
)
38 if s
or err
~= "timeout" then return s
, err
, part
end
39 coroutine
.yield(EV_READ
)
42 -- same as above but with special treatment when reading chunks,
43 -- unblocks on any data received.
44 function receivePartial(client
, pattern
)
46 pattern
= pattern
or "*l"
48 s
, err
, part
= client
:receive(pattern
)
49 if s
or ( (type(pattern
)=="number") and part
~="" and part
~=nil ) or
50 err
~= "timeout" then return s
, err
, part
end
51 coroutine
.yield(EV_READ
)
54 function connect(sock
, ...)
56 local ret
, err
= sock
:connect(...)
57 if ret
or err
~= "timeout" then return ret
, err
end
58 coroutine
.yield(EV_WRITE
)
59 ret
, err
= sock
:connect(...)
60 if err
== "already connected" then
68 local function clientCoroutine(sock
, handler
)
69 -- Figure out what to do ......
73 local function serverCoroutine(sock
, callback
)
75 local event
= coroutine
.yield(EV_READ
)
77 local client
= sock
:accept()
79 --cl[#cl + 1] = client
81 local coFunc
= coroutine
.wrap(clientCoroutine
)
82 clientTable
[client
] = luaevent
.core
.addevent(client
, coFunc
, client
, callback
)
87 local oldAddEvent
= luaevent
.core
.addevent
88 luaevent
.core
.addevent
= function(...)
89 local item
= oldAddEvent(...)
90 if not item
then print("FAILED TO SETUP ITEM") return item
end
91 print("SETUP ITEM FOR: ", debug
.getmetatable(item
).getfd(item
))
92 if not hookedObjectMt
then
94 local mt
= debug
.getmetatable(item
)
96 mt
.__gc
= function(...)
97 print("RELEASING ITEM FOR: ", mt
.getfd(...))
104 function addserver(sock
, callback
)
105 local coFunc
= coroutine
.wrap(serverCoroutine
)
106 clientTable
[sock
] = luaevent
.core
.addevent(sock
, coFunc
, sock
, callback
)
108 function addthread(sock
, func
, ...)
109 local coFunc
= coroutine
.wrap(func
)
110 clientTable
[sock
] = luaevent
.core
.addevent(sock
, coFunc
, ...)
112 local _skt_mt
= {__index
= {
113 connect
= function(self
, ...)
114 return connect(self
.socket
, ...)
116 send
= function (self
, data
)
117 return send (self
.socket
, data
)
120 receive
= function (self
, pattern
)
121 if (self
.timeout
==0) then
122 return receivePartial(self
.socket
, pattern
)
124 return receive (self
.socket
, pattern
)
127 flush = function (self
)
128 return flush (self
.socket
)
131 settimeout
= function (self
,time
)
137 return setmetatable({socket
= sock
}, _skt_mt
)
139 loop
= luaevent
.core
.loop