base/lua: fixes incorrectly recorded version and prepares a new release
[luaevent.git] / lua / luaevent.lua
blob509d94fc97cc103bf91f1481ed7cb3305ab01491
1 --[[
2 LuaEvent - Copyright (C) 2007 Thomas Harning <harningt@gmail.com>
3 Licensed as LGPL - See doc/COPYING for details.
4 ]]
5 module("luaevent", package.seeall)
6 require("luaevent.core")
8 _NAME = "luaevent";
9 _VERSION = "0.3.2";
11 local EV_READ = luaevent.core.EV_READ
12 local EV_WRITE = luaevent.core.EV_WRITE
13 local base = luaevent.core.new()
15 local function addevent(...)
16 return base:addevent(...)
17 end
19 local function getWrapper()
20 local running = coroutine.running()
21 return function(...)
22 return select(2, coroutine.resume(running, ...))
23 end
24 end
25 -- Weak keys.. the keys are the client sockets
26 local clientTable = setmetatable({}, {'__mode', 'kv'})
27 local function socketWait(sock, event)
28 if not clientTable[sock] then clientTable[sock] = addevent(sock, event, getWrapper()) end
29 coroutine.yield(event)
30 end
33 function send(sock, data, start, stop)
34 local s, err
35 local from = start or 1
36 local sent = 0
37 repeat
38 from = from + sent
39 s, err, sent = sock:send(data, from, stop)
40 if s or err ~= "timeout" then return s, err, sent end
41 socketWait(sock, EV_WRITE)
42 until false
43 end
44 function receive(sock, pattern, part)
45 local s, err
46 pattern = pattern or '*l'
47 repeat
48 s, err, part = sock:receive(pattern, part)
49 if s or err ~= "timeout" then return s, err, part end
50 socketWait(sock, EV_READ)
51 until false
52 end
53 -- same as above but with special treatment when reading chunks,
54 -- unblocks on any data received.
55 function receivePartial(client, pattern)
56 local s, err, part
57 pattern = pattern or "*l"
58 repeat
59 s, err, part = client:receive(pattern)
60 if s or ( (type(pattern)=="number") and part~="" and part ~=nil ) or
61 err ~= "timeout" then return s, err, part end
62 socketWait(sock, EV_READ)
63 until false
64 end
65 function connect(sock, ...)
66 sock:settimeout(0)
67 local ret, err = sock:connect(...)
68 if ret or err ~= "timeout" then return ret, err end
69 socketWait(sock, EV_WRITE)
70 ret, err = sock:connect(...)
71 if err == "already connected" then
72 return 1
73 end
74 return ret, err
75 end
76 -- Deprecated..
77 function flush(sock)
78 end
79 local function clientCoroutine(sock, handler)
80 -- Figure out what to do ......
81 return handler(sock)
82 end
83 local function handleClient(co, client, handler)
84 local ok, res, event = coroutine.resume(co, client, handler)
85 end
86 local function serverCoroutine(sock, callback)
87 local listenItem = addevent(sock, EV_READ, getWrapper())
88 repeat
89 local event = coroutine.yield(EV_READ)
90 -- Get new socket
91 local client = sock:accept()
92 if client then
93 client:settimeout(0)
94 local co = coroutine.create(clientCoroutine)
95 handleClient(co, client, callback)
96 end
97 until false
98 end
99 function addserver(sock, callback)
100 local coro = coroutine.create(serverCoroutine)
101 assert(coroutine.resume(coro, sock, callback))
103 function addthread(func, ...)
104 return coroutine.resume(coroutine.create(func), ...)
106 local _skt_mt = {__index = {
107 connect = function(self, ...)
108 return connect(self.socket, ...)
109 end,
110 send = function (self, data)
111 return send(self.socket, data)
112 end,
114 receive = function (self, pattern)
115 if (self.timeout==0) then
116 return receivePartial(self.socket, pattern)
118 return receive(self.socket, pattern)
119 end,
121 flush = function (self)
122 return flush(self.socket)
123 end,
125 settimeout = function (self,time)
126 self.timeout=time
127 return
128 end,
130 close = function(self)
131 clientTable[self.socket]:close()
132 self.socket:close()
135 function wrap(sock)
136 return setmetatable({socket = sock}, _skt_mt)
138 loop = function(...) base:loop(...) end