c532956ca92057fc378d1599f2cad7f3d6ad62d8
2 LuaEvent - Copyright (C) 2007,2012 Thomas Harning <harningt@gmail.com>
3 Licensed as LGPL - See doc/COPYING for details.
6 local core
= require("luaevent.core")
12 local EV_READ
= core
.EV_READ
13 local EV_WRITE
= core
.EV_WRITE
14 local base
= core
.new()
16 local function addevent(...)
17 return base
:addevent(...)
20 local function getWrapper()
21 local running
= coroutine
.running()
23 return select(2, coroutine
.resume(running
, ...))
26 -- Weak keys.. the keys are the client sockets
27 local clientTable
= setmetatable({}, {'__mode', 'kv'})
28 local function socketWait(sock
, event
)
29 if not clientTable
[sock
] then clientTable
[sock
] = addevent(sock
, event
, getWrapper()) end
30 coroutine
.yield(event
)
34 function _M
.send(sock
, data
, start
, stop
)
36 local from
= start
or 1
40 s
, err
, sent
= sock
:send(data
, from
, stop
)
41 if s
or err
~= "timeout" then return s
, err
, sent
end
42 socketWait(sock
, EV_WRITE
)
45 function _M
.receive(sock
, pattern
, part
)
47 pattern
= pattern
or '*l'
49 s
, err
, part
= sock
:receive(pattern
, part
)
50 if s
or err
~= "timeout" then return s
, err
, part
end
51 socketWait(sock
, EV_READ
)
54 -- same as above but with special treatment when reading chunks,
55 -- unblocks on any data received.
56 function _M
.receivePartial(client
, pattern
)
58 pattern
= pattern
or "*l"
60 s
, err
, part
= client
:receive(pattern
)
61 if s
or ( (type(pattern
)=="number") and part
~="" and part
~=nil ) or err
~= "timeout" then
64 socketWait(client
, EV_READ
)
67 function _M
.connect(sock
, ...)
69 local ret
, err
= sock
:connect(...)
70 if ret
or err
~= "timeout" then return ret
, err
end
71 socketWait(sock
, EV_WRITE
)
72 ret
, err
= sock
:connect(...)
73 if err
== "already connected" then
79 function _M
.flush(sock
)
81 local function clientCoroutine(sock
, handler
)
82 -- Figure out what to do ......
85 local function handleClient(co
, client
, handler
)
86 local ok
, res
, event
= coroutine
.resume(co
, client
, handler
)
88 local function serverCoroutine(sock
, callback
)
89 local listenItem
= addevent(sock
, EV_READ
, getWrapper())
91 local event
= coroutine
.yield(EV_READ
)
93 local client
= sock
:accept()
96 local co
= coroutine
.create(clientCoroutine
)
97 handleClient(co
, client
, callback
)
101 function _M
.addserver(sock
, callback
)
102 local coro
= coroutine
.create(serverCoroutine
)
103 assert(coroutine
.resume(coro
, sock
, callback
))
105 function _M
.addthread(func
, ...)
106 return coroutine
.resume(coroutine
.create(func
), ...)
108 local _skt_mt
= {__index
= {
109 connect
= function(self
, ...)
110 return _M
.connect(self
.socket
, ...)
112 send
= function (self
, data
)
113 return _M
.send(self
.socket
, data
)
116 receive
= function (self
, pattern
)
117 if (self
.timeout
==0) then
118 return _M
.receivePartial(self
.socket
, pattern
)
120 return _M
.receive(self
.socket
, pattern
)
123 flush = function (self
)
124 return _M
.flush(self
.socket
)
127 settimeout
= function (self
,time
)
132 close
= function(self
)
133 clientTable
[self
.socket
]:close()
137 function _M
.wrap(sock
)
138 return setmetatable({socket
= sock
}, _skt_mt
)
140 _M
.loop
= function(...) base
:loop(...) end