-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathex9_2.lua
75 lines (67 loc) · 1.72 KB
/
ex9_2.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
--[[
This multithreading downloader is just a combination of code clips from p91-95
--]]
local socket = require "socket"
local u = require "utils"
local function receive (connection)
connection:settimeout(0) -- do not block
local s, status, partial = connection:receive(2^10)
if status == "timeout" then
coroutine.yield(connection)
end
return s or partial, status
end
local function download (host, file)
local c = assert(socket.connect(host, 80))
local count = 0
print ("downloading " .. host .. file)
c:send("GET " .. file .. " HTTP/1.0\r\n\r\n")
while true do
local s, status = receive(c)
count = count + #s
if status == "closed" then break end
end
c:close()
print(file, count)
end
local threads = {}
local function get (host, file)
-- create coroutine
local co = coroutine.create(
function ()
download(host, file)
end)
-- insert it in the list
table.insert(threads, co)
end
local function dispatch ()
local i = 1
local timedout = {}
print ("a")
while true do
if threads[i] == nil then -- no more threads
if threads[1] == nil then break end -- list is empty?
i = 1 -- restart the loop
timedout = {}
end
local status, res = coroutine.resume(threads[i])
if not res then -- thread finished its task?
print ("d")
table.remove(threads, i)
else
i = i + 1
table.insert(timedout, res)
if #timedout == #threads then -- all threads blocked?
-- select would block forever, to be investigated
-- socket.select(thimedout)
end
end
end
end
local function test ()
local host = "www.w3.org"
get(host, "/TR/html401/html40.txt")
get(host, "/TR/html401/html40.txt")
dispatch()
end
test()