luaevent/luaevent.lua

Mon, 11 Jun 2007 01:08:59 +0000

author
Thomas Harning Jr <harningt@gmail.com>
date
Mon, 11 Jun 2007 01:08:59 +0000
changeset 2
01b3a96ae760
parent 1
31c782cfe7fe
child 3
5999243fab1d
permissions
-rw-r--r--

* Completed mostly working version
* Moved to a mode where addevent calls a callback rather than
it being instantiated within.
* If the callback returns -1, then no event is ever setup
* Otherwise the integer value is used to setup the event
* This allows for using coroutine.wrap rather than a cooked-up wrapper
* Tests work, although there are a few remaining issues:
* Need to figure a good way of preserving the event object,
not sure if current method is good enough, since the socket
is the only anchor, and it is only held inside the coro..
circular reference, something that Lua 'handles' well.
* Doing more than the maximum sockets the process is allows
causes strangeness to occur in libevent.. somehow
it is getting around to epoll_add which is causing valgrind
to barf.

1
31c782cfe7fe * Adjusted licensing and added README.
Thomas Harning Jr <harningt@gmail.com>
parents: 0
diff changeset
1 --[[
31c782cfe7fe * Adjusted licensing and added README.
Thomas Harning Jr <harningt@gmail.com>
parents: 0
diff changeset
2 LuaEvent - Copyright (C) 2007 Thomas Harning <harningt@gmail.com>
31c782cfe7fe * Adjusted licensing and added README.
Thomas Harning Jr <harningt@gmail.com>
parents: 0
diff changeset
3 Licensed as LGPL - See doc/COPYING for details.
31c782cfe7fe * Adjusted licensing and added README.
Thomas Harning Jr <harningt@gmail.com>
parents: 0
diff changeset
4 ]]
0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
5 module("luaevent", package.seeall)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
6 require("luaevent.core")
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
7
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
8 local EV_READ = luaevent.core.EV_READ
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
9 local EV_WRITE = luaevent.core.EV_WRITE
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
10 local fair = false
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
11
2
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
12 local hookedObjectMt = false
0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
13
2
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
14 -- Weak keys.. the keys are the client sockets
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
15 local clientTable = setmetatable({}, {'__mode', 'k'})
0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
16
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
17 function send(sock, data, start, stop)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
18 local s, err
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
19 local from = start or 1
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
20 local sent = 0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
21 repeat
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
22 from = from + sent
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
23 s, err, sent = sock:send(data, from, stop)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
24 -- Add extra coro swap for fairness
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
25 -- CURRENTLY DISABLED FOR TESTING......
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
26 if fair and math.random(100) > 90 then
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
27 coroutine.yield(EV_WRITE)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
28 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
29 if s or err ~= "timeout" then return s, err, sent end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
30 coroutine.yield(EV_WRITE)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
31 until false
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
32 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
33 function receive(sock, pattern, part)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
34 local s, err
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
35 pattern = pattern or '*l'
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
36 repeat
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
37 s, err, part = sock:receive(pattern, part)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
38 if s or err ~= "timeout" then return s, err, part end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
39 coroutine.yield(EV_READ)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
40 until false
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
41 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
42 -- same as above but with special treatment when reading chunks,
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
43 -- unblocks on any data received.
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
44 function receivePartial(client, pattern)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
45 local s, err, part
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
46 pattern = pattern or "*l"
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
47 repeat
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
48 s, err, part = client:receive(pattern)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
49 if s or ( (type(pattern)=="number") and part~="" and part ~=nil ) or
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
50 err ~= "timeout" then return s, err, part end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
51 coroutine.yield(EV_READ)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
52 until false
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
53 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
54 function connect(sock, ...)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
55 sock:settimeout(0)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
56 local ret, err = sock:connect(...)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
57 if ret or err ~= "timeout" then return ret, err end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
58 coroutine.yield(EV_WRITE)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
59 ret, err = sock:connect(...)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
60 if err == "already connected" then
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
61 return 1
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
62 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
63 return ret, err
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
64 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
65 -- Deprecated..
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
66 function flush(sock)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
67 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
68 local function clientCoroutine(sock, handler)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
69 -- Figure out what to do ......
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
70 return handler(sock)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
71 end
2
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
72
0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
73 local function serverCoroutine(sock, callback)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
74 repeat
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
75 local event = coroutine.yield(EV_READ)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
76 -- Get new socket
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
77 local client = sock:accept()
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
78 if client then
2
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
79 --cl[#cl + 1] = client
0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
80 client:settimeout(0)
2
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
81 local coFunc = coroutine.wrap(clientCoroutine)
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
82 clientTable[client] = luaevent.core.addevent(client, coFunc, client, callback)
0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
83 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
84 until false
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
85 end
2
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
86
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
87 local oldAddEvent = luaevent.core.addevent
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
88 luaevent.core.addevent = function(...)
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
89 local item = oldAddEvent(...)
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
90 print("SETUP ITEM FOR: ", debug.getmetatable(item).getfd(item))
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
91 if not hookedObjectMt then
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
92 hookedObjectMt = true
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
93 local mt = debug.getmetatable(item)
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
94 local oldGC = mt.__gc
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
95 mt.__gc = function(...)
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
96 print("RELEASING ITEM FOR: ", mt.getfd(...))
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
97 return oldGC(...)
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
98 end
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
99 end
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
100 return item
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
101 end
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
102
0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
103 function addserver(sock, callback)
2
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
104 local coFunc = coroutine.wrap(serverCoroutine)
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
105 clientTable[sock] = luaevent.core.addevent(sock, coFunc, sock, callback)
0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
106 end
2
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
107 function addthread(sock, func, ...)
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
108 local coFunc = coroutine.wrap(func)
01b3a96ae760 * Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents: 1
diff changeset
109 clientTable[sock] = luaevent.core.addevent(sock, coFunc, ...)
0
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
110 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
111 local _skt_mt = {__index = {
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
112 connect = function(self, ...)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
113 return connect(self.socket, ...)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
114 end,
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
115 send = function (self, data)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
116 return send (self.socket, data)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
117 end,
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
118
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
119 receive = function (self, pattern)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
120 if (self.timeout==0) then
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
121 return receivePartial(self.socket, pattern)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
122 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
123 return receive (self.socket, pattern)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
124 end,
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
125
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
126 flush = function (self)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
127 return flush (self.socket)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
128 end,
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
129
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
130 settimeout = function (self,time)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
131 self.timeout=time
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
132 return
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
133 end,
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
134 }}
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
135 function wrap(sock)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
136 return setmetatable({socket = sock}, _skt_mt)
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
137 end
f2e807614be9 Initial commit:
Thomas Harning Jr <harningt@gmail.com>
parents:
diff changeset
138 loop = luaevent.core.loop

mercurial