Wed, 13 Jun 2007 04:32:12 +0000
Setup management of socket create/close.
Recognized new bug: cannot create threads within threads... C contains reference to closed thread, not
global.
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 | 5 | module("luaevent", package.seeall) |
6 | require("luaevent.core") | |
7 | ||
8 | local EV_READ = luaevent.core.EV_READ | |
9 | local EV_WRITE = luaevent.core.EV_WRITE | |
10 | local fair = false | |
11 | ||
2
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
12 | local hookedObjectMt = false |
0 | 13 | |
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 | |
2
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
69 | |
0 | 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 | |
2
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
76 | --cl[#cl + 1] = client |
0 | 77 | client:settimeout(0) |
2
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
78 | local coFunc = coroutine.wrap(clientCoroutine) |
10
88ce07d62597
Setup management of socket create/close.
Thomas Harning Jr <harningt@gmail.com>
parents:
3
diff
changeset
|
79 | luaevent.core.addevent(client, coFunc, client, callback) |
0 | 80 | end |
81 | until false | |
82 | end | |
2
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
83 | |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
84 | local oldAddEvent = luaevent.core.addevent |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
85 | luaevent.core.addevent = function(...) |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
86 | local item = oldAddEvent(...) |
3
5999243fab1d
* Added some cheap protection code for failures in callback
Thomas Harning Jr <harningt@gmail.com>
parents:
2
diff
changeset
|
87 | if not item then print("FAILED TO SETUP ITEM") return item end |
2
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
88 | print("SETUP ITEM FOR: ", debug.getmetatable(item).getfd(item)) |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
89 | if not hookedObjectMt then |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
90 | hookedObjectMt = true |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
91 | local mt = debug.getmetatable(item) |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
92 | local oldGC = mt.__gc |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
93 | mt.__gc = function(...) |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
94 | print("RELEASING ITEM FOR: ", mt.getfd(...)) |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
95 | return oldGC(...) |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
96 | end |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
97 | end |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
98 | return item |
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 | |
0 | 101 | function addserver(sock, callback) |
2
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
102 | local coFunc = coroutine.wrap(serverCoroutine) |
10
88ce07d62597
Setup management of socket create/close.
Thomas Harning Jr <harningt@gmail.com>
parents:
3
diff
changeset
|
103 | luaevent.core.addevent(sock, coFunc, sock, callback) |
0 | 104 | end |
2
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
105 | function addthread(sock, func, ...) |
01b3a96ae760
* Completed mostly working version
Thomas Harning Jr <harningt@gmail.com>
parents:
1
diff
changeset
|
106 | local coFunc = coroutine.wrap(func) |
10
88ce07d62597
Setup management of socket create/close.
Thomas Harning Jr <harningt@gmail.com>
parents:
3
diff
changeset
|
107 | luaevent.core.addevent(sock, coFunc, ...) |
0 | 108 | end |
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, | |
116 | ||
117 | receive = function (self, pattern) | |
118 | if (self.timeout==0) then | |
119 | return receivePartial(self.socket, pattern) | |
120 | end | |
121 | return receive (self.socket, pattern) | |
122 | end, | |
123 | ||
124 | flush = function (self) | |
125 | return flush (self.socket) | |
126 | end, | |
127 | ||
128 | settimeout = function (self,time) | |
129 | self.timeout=time | |
130 | return | |
131 | end, | |
10
88ce07d62597
Setup management of socket create/close.
Thomas Harning Jr <harningt@gmail.com>
parents:
3
diff
changeset
|
132 | close = function(self) |
88ce07d62597
Setup management of socket create/close.
Thomas Harning Jr <harningt@gmail.com>
parents:
3
diff
changeset
|
133 | self.socket:close() |
88ce07d62597
Setup management of socket create/close.
Thomas Harning Jr <harningt@gmail.com>
parents:
3
diff
changeset
|
134 | end |
0 | 135 | }} |
136 | function wrap(sock) | |
137 | return setmetatable({socket = sock}, _skt_mt) | |
138 | end | |
139 | loop = luaevent.core.loop |