Setup management of socket create/close.
[luaevent.git] / luaevent / luaevent.lua
blobc6bd0158db02aa0acccf60b0262b7184e21f734f
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 local EV_READ = luaevent.core.EV_READ
9 local EV_WRITE = luaevent.core.EV_WRITE
10 local fair = false
12 local hookedObjectMt = false
14 function send(sock, data, start, stop)
15 local s, err
16 local from = start or 1
17 local sent = 0
18 repeat
19 from = from + sent
20 s, err, sent = sock:send(data, from, stop)
21 -- Add extra coro swap for fairness
22 -- CURRENTLY DISABLED FOR TESTING......
23 if fair and math.random(100) > 90 then
24 coroutine.yield(EV_WRITE)
25 end
26 if s or err ~= "timeout" then return s, err, sent end
27 coroutine.yield(EV_WRITE)
28 until false
29 end
30 function receive(sock, pattern, part)
31 local s, err
32 pattern = pattern or '*l'
33 repeat
34 s, err, part = sock:receive(pattern, part)
35 if s or err ~= "timeout" then return s, err, part end
36 coroutine.yield(EV_READ)
37 until false
38 end
39 -- same as above but with special treatment when reading chunks,
40 -- unblocks on any data received.
41 function receivePartial(client, pattern)
42 local s, err, part
43 pattern = pattern or "*l"
44 repeat
45 s, err, part = client:receive(pattern)
46 if s or ( (type(pattern)=="number") and part~="" and part ~=nil ) or
47 err ~= "timeout" then return s, err, part end
48 coroutine.yield(EV_READ)
49 until false
50 end
51 function connect(sock, ...)
52 sock:settimeout(0)
53 local ret, err = sock:connect(...)
54 if ret or err ~= "timeout" then return ret, err end
55 coroutine.yield(EV_WRITE)
56 ret, err = sock:connect(...)
57 if err == "already connected" then
58 return 1
59 end
60 return ret, err
61 end
62 -- Deprecated..
63 function flush(sock)
64 end
65 local function clientCoroutine(sock, handler)
66 -- Figure out what to do ......
67 return handler(sock)
68 end
70 local function serverCoroutine(sock, callback)
71 repeat
72 local event = coroutine.yield(EV_READ)
73 -- Get new socket
74 local client = sock:accept()
75 if client then
76 --cl[#cl + 1] = client
77 client:settimeout(0)
78 local coFunc = coroutine.wrap(clientCoroutine)
79 luaevent.core.addevent(client, coFunc, client, callback)
80 end
81 until false
82 end
84 local oldAddEvent = luaevent.core.addevent
85 luaevent.core.addevent = function(...)
86 local item = oldAddEvent(...)
87 if not item then print("FAILED TO SETUP ITEM") return item end
88 print("SETUP ITEM FOR: ", debug.getmetatable(item).getfd(item))
89 if not hookedObjectMt then
90 hookedObjectMt = true
91 local mt = debug.getmetatable(item)
92 local oldGC = mt.__gc
93 mt.__gc = function(...)
94 print("RELEASING ITEM FOR: ", mt.getfd(...))
95 return oldGC(...)
96 end
97 end
98 return item
99 end
101 function addserver(sock, callback)
102 local coFunc = coroutine.wrap(serverCoroutine)
103 luaevent.core.addevent(sock, coFunc, sock, callback)
105 function addthread(sock, func, ...)
106 local coFunc = coroutine.wrap(func)
107 luaevent.core.addevent(sock, coFunc, ...)
109 local _skt_mt = {__index = {
110 connect = function(self, ...)
111 return connect(self.socket, ...)
112 end,
113 send = function (self, data)
114 return send (self.socket, data)
115 end,
117 receive = function (self, pattern)
118 if (self.timeout==0) then
119 return receivePartial(self.socket, pattern)
121 return receive (self.socket, pattern)
122 end,
124 flush = function (self)
125 return flush (self.socket)
126 end,
128 settimeout = function (self,time)
129 self.timeout=time
130 return
131 end,
132 close = function(self)
133 self.socket:close()
136 function wrap(sock)
137 return setmetatable({socket = sock}, _skt_mt)
139 loop = luaevent.core.loop