mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 03:53:09 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77d53cf5f1 | ||
|
|
5621c52a44 | ||
|
|
f6fa6c7ded | ||
|
|
e739df0a32 | ||
|
|
b18962929b | ||
|
|
dec2e6fe4c | ||
|
|
7beed39b1d | ||
|
|
4673344e1e | ||
|
|
b49fc291a7 | ||
|
|
11c528987c |
13
HISTORY.md
13
HISTORY.md
@@ -1,3 +1,16 @@
|
|||||||
|
v0.5.2 (2014-8-11)
|
||||||
|
-----------
|
||||||
|
* Bugfix : httpd request
|
||||||
|
* Bugifx : http chunked mode
|
||||||
|
* Add : httpc
|
||||||
|
* timer support more than 497 days
|
||||||
|
|
||||||
|
v0.5.1 (2014-8-4)
|
||||||
|
-----------
|
||||||
|
* Bugfix : http module
|
||||||
|
* Bugfix : multicast local channel delete
|
||||||
|
* Bugfix : socket.read(fd)
|
||||||
|
|
||||||
v0.5.0 (2014-7-28)
|
v0.5.0 (2014-7-28)
|
||||||
-----------
|
-----------
|
||||||
* skynet.exit will quit service immediately.
|
* skynet.exit will quit service immediately.
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ Each lua file only load once and cache it in memory during skynet start . so if
|
|||||||
|
|
||||||
You can also use the offical lua version , edit the makefile by yourself .
|
You can also use the offical lua version , edit the makefile by yourself .
|
||||||
|
|
||||||
## Blog (in Chinese)
|
## How To (in Chinese)
|
||||||
|
|
||||||
* http://blog.codingnow.com/2012/09/the_design_of_skynet.html
|
* Read Wiki https://github.com/cloudwu/skynet/wiki
|
||||||
* http://blog.codingnow.com/2012/08/skynet.html
|
|
||||||
* http://blog.codingnow.com/eo/skynet/
|
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ skynet.start(function()
|
|||||||
table.insert(tmp, string.format("query: %s= %s", k,v))
|
table.insert(tmp, string.format("query: %s= %s", k,v))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
table.insert(tmp, "-----header----")
|
||||||
|
for k,v in pairs(header) do
|
||||||
|
table.insert(tmp, string.format("%s = %s",k,v))
|
||||||
|
end
|
||||||
|
table.insert(tmp, "-----body----\n" .. body)
|
||||||
response(id, code, table.concat(tmp,"\n"))
|
response(id, code, table.concat(tmp,"\n"))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -246,6 +246,7 @@ lclearbuffer(lua_State *L) {
|
|||||||
while(sb->head) {
|
while(sb->head) {
|
||||||
return_free_node(L,2,sb);
|
return_free_node(L,2,sb);
|
||||||
}
|
}
|
||||||
|
sb->size = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,6 +265,7 @@ lreadall(lua_State *L) {
|
|||||||
return_free_node(L,2,sb);
|
return_free_node(L,2,sb);
|
||||||
}
|
}
|
||||||
luaL_pushresult(&b);
|
luaL_pushresult(&b);
|
||||||
|
sb->size = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
114
lualib/http/httpc.lua
Normal file
114
lualib/http/httpc.lua
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
local socket = require "http.sockethelper"
|
||||||
|
local url = require "http.url"
|
||||||
|
local internal = require "http.internal"
|
||||||
|
local string = string
|
||||||
|
local table = table
|
||||||
|
|
||||||
|
local httpc = {}
|
||||||
|
|
||||||
|
local function request(fd, method, host, url, recvheader, header, content)
|
||||||
|
local read = socket.readfunc(fd)
|
||||||
|
local write = socket.writefunc(fd)
|
||||||
|
local header_content = ""
|
||||||
|
if header then
|
||||||
|
for k,v in pairs(header) do
|
||||||
|
header_content = string.format("%s%s:%s\r\n", header_content, k, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if content then
|
||||||
|
local data = string.format("%s %s HTTP/1.1\r\nhost:%s\r\ncontent-length:%d\r\n%s\r\n%s", method, url, host, #content, header_content, content)
|
||||||
|
write(data)
|
||||||
|
else
|
||||||
|
local request_header = string.format("%s %s HTTP/1.1\r\nhost:%s\r\ncontent-length:0\r\n%s\r\n", method, url, host, header_content)
|
||||||
|
write(request_header)
|
||||||
|
end
|
||||||
|
|
||||||
|
local tmpline = {}
|
||||||
|
local body = internal.recvheader(read, tmpline, "")
|
||||||
|
if not body then
|
||||||
|
error(socket.socket_error)
|
||||||
|
end
|
||||||
|
|
||||||
|
local statusline = tmpline[1]
|
||||||
|
local code, info = statusline:match "HTTP/[%d%.]+%s+([%d]+)%s+(.*)$"
|
||||||
|
code = assert(tonumber(code))
|
||||||
|
|
||||||
|
local header = internal.parseheader(tmpline,2,recvheader or {})
|
||||||
|
if not header then
|
||||||
|
error("Invalid HTTP response header")
|
||||||
|
end
|
||||||
|
|
||||||
|
local length = header["content-length"]
|
||||||
|
if length then
|
||||||
|
length = tonumber(length)
|
||||||
|
end
|
||||||
|
local mode = header["transfer-encoding"]
|
||||||
|
if mode then
|
||||||
|
if mode ~= "identity" and mode ~= "chunked" then
|
||||||
|
error ("Unsupport transfer-encoding")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if mode == "chunked" then
|
||||||
|
body, header = internal.recvchunkedbody(read, nil, header, body)
|
||||||
|
if not body then
|
||||||
|
error("Invalid response body")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- identity mode
|
||||||
|
if length then
|
||||||
|
if #body >= length then
|
||||||
|
body = body:sub(1,length)
|
||||||
|
else
|
||||||
|
local padding = read(length - #body)
|
||||||
|
body = body .. padding
|
||||||
|
end
|
||||||
|
else
|
||||||
|
body = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return code, body
|
||||||
|
end
|
||||||
|
|
||||||
|
function httpc.request(method, host, url, recvheader, header, content)
|
||||||
|
local hostname, port = host:match"([^:]+):?(%d*)$"
|
||||||
|
if port == "" then
|
||||||
|
port = 80
|
||||||
|
else
|
||||||
|
port = tonumber(port)
|
||||||
|
end
|
||||||
|
local fd = socket.connect(hostname, port)
|
||||||
|
local ok , statuscode, body = pcall(request, fd,method, host, url, recvheader, header, content)
|
||||||
|
if ok then
|
||||||
|
return statuscode, body
|
||||||
|
else
|
||||||
|
socket.close(fd)
|
||||||
|
error(statuscode)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function httpc.get(...)
|
||||||
|
return httpc.request("GET", ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function escape(s)
|
||||||
|
return (string.gsub(s, "([^A-Za-z0-9_])", function(c)
|
||||||
|
return string.format("%%%02X", string.byte(c))
|
||||||
|
end))
|
||||||
|
end
|
||||||
|
|
||||||
|
function httpc.post(host, url, form, recvheader)
|
||||||
|
local header = {
|
||||||
|
["content-type"] = "application/x-www-form-urlencoded"
|
||||||
|
}
|
||||||
|
local body = {}
|
||||||
|
for k,v in pairs(form) do
|
||||||
|
table.insert(body, string.format("%s=%s",escape(k),escape(v)))
|
||||||
|
end
|
||||||
|
|
||||||
|
return httpc.request("POST", host, url, recvheader, header, table.concat(body , "&"))
|
||||||
|
end
|
||||||
|
|
||||||
|
return httpc
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
local internal = require "http.internal"
|
||||||
|
|
||||||
local table = table
|
local table = table
|
||||||
|
|
||||||
local httpd = {}
|
local httpd = {}
|
||||||
@@ -45,140 +47,9 @@ local http_status_msg = {
|
|||||||
[505] = "HTTP Version not supported",
|
[505] = "HTTP Version not supported",
|
||||||
}
|
}
|
||||||
|
|
||||||
local function recvheader(readbytes, limit, lines, header)
|
|
||||||
local result
|
|
||||||
local e = header:find("\r\n\r\n", 1, true)
|
|
||||||
if e then
|
|
||||||
result = header:sub(e+4)
|
|
||||||
else
|
|
||||||
while true do
|
|
||||||
local bytes = readbytes()
|
|
||||||
header = header .. bytes
|
|
||||||
if #header > limit then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
e = header:find("\r\n\r\n", -#bytes-3, true)
|
|
||||||
if e then
|
|
||||||
result = header:sub(e+4)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local idx = 1
|
|
||||||
for v in header:gmatch("(.-)\r\n") do
|
|
||||||
if v == "" then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
lines[idx] = v
|
|
||||||
idx = idx + 1
|
|
||||||
end
|
|
||||||
for i = idx, #lines do
|
|
||||||
lines[i] = nil
|
|
||||||
end
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
local function parseheader(lines, from, header)
|
|
||||||
local name, value
|
|
||||||
for i=from,#lines do
|
|
||||||
local line = lines[i]
|
|
||||||
if line:byte(1) == 9 then -- tab, append last line
|
|
||||||
if name == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
header[name] = header[name] .. line:sub(2)
|
|
||||||
else
|
|
||||||
name, value = line:match "^(.-):%s*(.*)"
|
|
||||||
if name == nil or value == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
name = name:lower()
|
|
||||||
if header[name] then
|
|
||||||
header[name] = header[name] .. ", " .. value
|
|
||||||
else
|
|
||||||
header[name] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return header
|
|
||||||
end
|
|
||||||
|
|
||||||
local function chunksize(readbytes, body)
|
|
||||||
while true do
|
|
||||||
if #body > 128 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
body = body .. readbytes()
|
|
||||||
local f,e = body:find("\r\n",1,true)
|
|
||||||
if f then
|
|
||||||
return tonumber(body:sub(1,f-1),16), body:sub(e+1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function readcrln(readbytes, body)
|
|
||||||
if #body > 2 then
|
|
||||||
if body:sub(1,2) ~= "\r\n" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
return body:sub(3)
|
|
||||||
else
|
|
||||||
body = body .. readbytes(2-#body)
|
|
||||||
if body ~= "\r\n" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local tmpline = {}
|
|
||||||
|
|
||||||
local function recvchunkedbody(readbytes, bodylimit, header, body)
|
|
||||||
local result = ""
|
|
||||||
local size = 0
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local sz
|
|
||||||
sz , body = chunksize(readbytes, body)
|
|
||||||
if not sz then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if sz == 0 then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
size = size + sz
|
|
||||||
if bodylimit and size > bodylimit then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if #body >= sz then
|
|
||||||
result = result .. body:sub(1,sz)
|
|
||||||
body = body:sub(sz+1)
|
|
||||||
else
|
|
||||||
result = result .. body .. readbytes(sz - #body)
|
|
||||||
body = ""
|
|
||||||
end
|
|
||||||
body = readcrln(readbytes, body)
|
|
||||||
if not body then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
body = readcrln(readbytes, body)
|
|
||||||
if not body then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
body = recvheader(readbytes, 8192, tmpline, body)
|
|
||||||
if not body then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
header = parseheader(tmpline,1,header)
|
|
||||||
|
|
||||||
return result, header
|
|
||||||
end
|
|
||||||
|
|
||||||
local function readall(readbytes, bodylimit)
|
local function readall(readbytes, bodylimit)
|
||||||
local body = recvheader(readbytes, 8192, tmpline, "")
|
local tmpline = {}
|
||||||
|
local body = internal.recvheader(readbytes, tmpline, "")
|
||||||
if not body then
|
if not body then
|
||||||
return 413 -- Request Entity Too Large
|
return 413 -- Request Entity Too Large
|
||||||
end
|
end
|
||||||
@@ -189,7 +60,7 @@ local function readall(readbytes, bodylimit)
|
|||||||
if httpver < 1.0 or httpver > 1.1 then
|
if httpver < 1.0 or httpver > 1.1 then
|
||||||
return 505 -- HTTP Version not supported
|
return 505 -- HTTP Version not supported
|
||||||
end
|
end
|
||||||
local header = parseheader(tmpline,2,{})
|
local header = internal.parseheader(tmpline,2,{})
|
||||||
if not header then
|
if not header then
|
||||||
return 400 -- Bad request
|
return 400 -- Bad request
|
||||||
end
|
end
|
||||||
@@ -199,13 +70,13 @@ local function readall(readbytes, bodylimit)
|
|||||||
end
|
end
|
||||||
local mode = header["transfer-encoding"]
|
local mode = header["transfer-encoding"]
|
||||||
if mode then
|
if mode then
|
||||||
if mode ~= "identity" or mode ~= "chunked" then
|
if mode ~= "identity" and mode ~= "chunked" then
|
||||||
return 501 -- Not Implemented
|
return 501 -- Not Implemented
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if mode == "chunked" then
|
if mode == "chunked" then
|
||||||
body, header = recvchunkedbody(readbytes, bodylimit, header, body)
|
body, header = internal.recvchunkedbody(readbytes, bodylimit, header, body)
|
||||||
if not body then
|
if not body then
|
||||||
return 413
|
return 413
|
||||||
end
|
end
|
||||||
|
|||||||
135
lualib/http/internal.lua
Normal file
135
lualib/http/internal.lua
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
local M = {}
|
||||||
|
|
||||||
|
local LIMIT = 8192
|
||||||
|
|
||||||
|
local function chunksize(readbytes, body)
|
||||||
|
while true do
|
||||||
|
if #body > 128 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
body = body .. readbytes()
|
||||||
|
local f,e = body:find("\r\n",1,true)
|
||||||
|
if f then
|
||||||
|
return tonumber(body:sub(1,f-1),16), body:sub(e+1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function readcrln(readbytes, body)
|
||||||
|
if #body >= 2 then
|
||||||
|
if body:sub(1,2) ~= "\r\n" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return body:sub(3)
|
||||||
|
else
|
||||||
|
body = body .. readbytes(2-#body)
|
||||||
|
if body ~= "\r\n" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.recvheader(readbytes, lines, header)
|
||||||
|
if #header >= 2 then
|
||||||
|
if header:find "^\r\n" then
|
||||||
|
return header:sub(3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local result
|
||||||
|
local e = header:find("\r\n\r\n", 1, true)
|
||||||
|
if e then
|
||||||
|
result = header:sub(e+4)
|
||||||
|
else
|
||||||
|
while true do
|
||||||
|
local bytes = readbytes()
|
||||||
|
header = header .. bytes
|
||||||
|
if #header > LIMIT then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
e = header:find("\r\n\r\n", -#bytes-3, true)
|
||||||
|
if e then
|
||||||
|
result = header:sub(e+4)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if header:find "^\r\n" then
|
||||||
|
return header:sub(3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for v in header:gmatch("(.-)\r\n") do
|
||||||
|
if v == "" then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
table.insert(lines, v)
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.parseheader(lines, from, header)
|
||||||
|
local name, value
|
||||||
|
for i=from,#lines do
|
||||||
|
local line = lines[i]
|
||||||
|
if line:byte(1) == 9 then -- tab, append last line
|
||||||
|
if name == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
header[name] = header[name] .. line:sub(2)
|
||||||
|
else
|
||||||
|
name, value = line:match "^(.-):%s*(.*)"
|
||||||
|
if name == nil or value == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
name = name:lower()
|
||||||
|
if header[name] then
|
||||||
|
header[name] = header[name] .. ", " .. value
|
||||||
|
else
|
||||||
|
header[name] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return header
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.recvchunkedbody(readbytes, bodylimit, header, body)
|
||||||
|
local result = ""
|
||||||
|
local size = 0
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local sz
|
||||||
|
sz , body = chunksize(readbytes, body)
|
||||||
|
if not sz then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if sz == 0 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
size = size + sz
|
||||||
|
if bodylimit and size > bodylimit then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if #body >= sz then
|
||||||
|
result = result .. body:sub(1,sz)
|
||||||
|
body = body:sub(sz+1)
|
||||||
|
else
|
||||||
|
result = result .. body .. readbytes(sz - #body)
|
||||||
|
body = ""
|
||||||
|
end
|
||||||
|
body = readcrln(readbytes, body)
|
||||||
|
if not body then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local tmpline = {}
|
||||||
|
body = M.recvheader(readbytes, tmpline, body)
|
||||||
|
if not body then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
header = M.parseheader(tmpline,1,header)
|
||||||
|
|
||||||
|
return result, header
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
@@ -28,4 +28,16 @@ function sockethelper.writefunc(fd)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function sockethelper.connect(host, port)
|
||||||
|
local fd = socket.open(host, port)
|
||||||
|
if fd then
|
||||||
|
return fd
|
||||||
|
end
|
||||||
|
error(socket_error)
|
||||||
|
end
|
||||||
|
|
||||||
|
function sockethelper.close(fd)
|
||||||
|
socket.close(fd)
|
||||||
|
end
|
||||||
|
|
||||||
return sockethelper
|
return sockethelper
|
||||||
|
|||||||
@@ -50,8 +50,10 @@ function command.DEL(source, c)
|
|||||||
channel[c] = nil
|
channel[c] = nil
|
||||||
channel_n[c] = nil
|
channel_n[c] = nil
|
||||||
channel_remote[c] = nil
|
channel_remote[c] = nil
|
||||||
for node in pairs(remote) do
|
if remote then
|
||||||
skynet.send(node_address[node], "lua", "DELR", c)
|
for node in pairs(remote) do
|
||||||
|
skynet.send(node_address[node], "lua", "DELR", c)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return NORET
|
return NORET
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ static const char * load_config = "\
|
|||||||
local code = assert(f:read \'*a\')\
|
local code = assert(f:read \'*a\')\
|
||||||
local function getenv(name) return assert(os.getenv(name), name) end\
|
local function getenv(name) return assert(os.getenv(name), name) end\
|
||||||
code = string.gsub(code, \'%$([%w_%d]+)\', getenv)\
|
code = string.gsub(code, \'%$([%w_%d]+)\', getenv)\
|
||||||
print(code)\
|
|
||||||
f:close()\
|
f:close()\
|
||||||
local result = {}\
|
local result = {}\
|
||||||
assert(load(code,\'=(load)\',\'t\',result))()\
|
assert(load(code,\'=(load)\',\'t\',result))()\
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@@ -33,7 +34,7 @@ struct timer_event {
|
|||||||
|
|
||||||
struct timer_node {
|
struct timer_node {
|
||||||
struct timer_node *next;
|
struct timer_node *next;
|
||||||
int expire;
|
uint32_t expire;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct link_list {
|
struct link_list {
|
||||||
@@ -43,9 +44,9 @@ struct link_list {
|
|||||||
|
|
||||||
struct timer {
|
struct timer {
|
||||||
struct link_list near[TIME_NEAR];
|
struct link_list near[TIME_NEAR];
|
||||||
struct link_list t[4][TIME_LEVEL-1];
|
struct link_list t[4][TIME_LEVEL];
|
||||||
int lock;
|
int lock;
|
||||||
int time;
|
uint32_t time;
|
||||||
uint32_t current;
|
uint32_t current;
|
||||||
uint32_t starttime;
|
uint32_t starttime;
|
||||||
uint64_t current_point;
|
uint64_t current_point;
|
||||||
@@ -72,21 +73,22 @@ link(struct link_list *list,struct timer_node *node) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
add_node(struct timer *T,struct timer_node *node) {
|
add_node(struct timer *T,struct timer_node *node) {
|
||||||
int time=node->expire;
|
uint32_t time=node->expire;
|
||||||
int current_time=T->time;
|
uint32_t current_time=T->time;
|
||||||
|
|
||||||
if ((time|TIME_NEAR_MASK)==(current_time|TIME_NEAR_MASK)) {
|
if ((time|TIME_NEAR_MASK)==(current_time|TIME_NEAR_MASK)) {
|
||||||
link(&T->near[time&TIME_NEAR_MASK],node);
|
link(&T->near[time&TIME_NEAR_MASK],node);
|
||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
int mask=TIME_NEAR << TIME_LEVEL_SHIFT;
|
uint32_t mask=TIME_NEAR << TIME_LEVEL_SHIFT;
|
||||||
for (i=0;i<3;i++) {
|
for (i=0;i<3;i++) {
|
||||||
if ((time|(mask-1))==(current_time|(mask-1))) {
|
if ((time|(mask-1))==(current_time|(mask-1))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mask <<= TIME_LEVEL_SHIFT;
|
mask <<= TIME_LEVEL_SHIFT;
|
||||||
}
|
}
|
||||||
link(&T->t[i][((time>>(TIME_NEAR_SHIFT + i*TIME_LEVEL_SHIFT)) & TIME_LEVEL_MASK)-1],node);
|
|
||||||
|
link(&T->t[i][((time>>(TIME_NEAR_SHIFT + i*TIME_LEVEL_SHIFT)) & TIME_LEVEL_MASK)],node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,29 +105,38 @@ timer_add(struct timer *T,void *arg,size_t sz,int time) {
|
|||||||
UNLOCK(T);
|
UNLOCK(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
move_list(struct timer *T, int level, int idx) {
|
||||||
|
struct timer_node *current = link_clear(&T->t[level][idx]);
|
||||||
|
while (current) {
|
||||||
|
struct timer_node *temp=current->next;
|
||||||
|
add_node(T,current);
|
||||||
|
current=temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
timer_shift(struct timer *T) {
|
timer_shift(struct timer *T) {
|
||||||
LOCK(T);
|
LOCK(T);
|
||||||
int mask = TIME_NEAR;
|
int mask = TIME_NEAR;
|
||||||
int time = (++T->time) >> TIME_NEAR_SHIFT;
|
uint32_t ct = ++T->time;
|
||||||
int i=0;
|
if (ct == 0) {
|
||||||
|
move_list(T, 3, 0);
|
||||||
while ((T->time & (mask-1))==0) {
|
} else {
|
||||||
int idx=time & TIME_LEVEL_MASK;
|
uint32_t time = ct >> TIME_NEAR_SHIFT;
|
||||||
if (idx!=0) {
|
int i=0;
|
||||||
--idx;
|
|
||||||
struct timer_node *current = link_clear(&T->t[i][idx]);
|
while ((ct & (mask-1))==0) {
|
||||||
while (current) {
|
int idx=time & TIME_LEVEL_MASK;
|
||||||
struct timer_node *temp=current->next;
|
if (idx!=0) {
|
||||||
add_node(T,current);
|
move_list(T, i, idx);
|
||||||
current=temp;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
mask <<= TIME_LEVEL_SHIFT;
|
||||||
|
time >>= TIME_LEVEL_SHIFT;
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
mask <<= TIME_LEVEL_SHIFT;
|
}
|
||||||
time >>= TIME_LEVEL_SHIFT;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
UNLOCK(T);
|
UNLOCK(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +198,7 @@ timer_create_timer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;i<4;i++) {
|
for (i=0;i<4;i++) {
|
||||||
for (j=0;j<TIME_LEVEL-1;j++) {
|
for (j=0;j<TIME_LEVEL;j++) {
|
||||||
link_clear(&r->t[i][j]);
|
link_clear(&r->t[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,6 +276,7 @@ skynet_updatetime(void) {
|
|||||||
uint64_t cp = gettime();
|
uint64_t cp = gettime();
|
||||||
if(cp < TI->current_point) {
|
if(cp < TI->current_point) {
|
||||||
skynet_error(NULL, "time diff error: change from %lld to %lld", cp, TI->current_point);
|
skynet_error(NULL, "time diff error: change from %lld to %lld", cp, TI->current_point);
|
||||||
|
TI->current_point = cp;
|
||||||
} else if (cp != TI->current_point) {
|
} else if (cp != TI->current_point) {
|
||||||
uint32_t diff = (uint32_t)(cp - TI->current_point);
|
uint32_t diff = (uint32_t)(cp - TI->current_point);
|
||||||
TI->current_point = cp;
|
TI->current_point = cp;
|
||||||
|
|||||||
16
test/testhttp.lua
Normal file
16
test/testhttp.lua
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
local httpc = require "http.httpc"
|
||||||
|
|
||||||
|
skynet.start(function()
|
||||||
|
print("GET baidu.com")
|
||||||
|
local header = {}
|
||||||
|
local status, body = httpc.get("baidu.com", "/", header)
|
||||||
|
print("[header] =====>")
|
||||||
|
for k,v in pairs(header) do
|
||||||
|
print(k,v)
|
||||||
|
end
|
||||||
|
print("[body] =====>", status)
|
||||||
|
print(body)
|
||||||
|
|
||||||
|
skynet.exit()
|
||||||
|
end)
|
||||||
@@ -4,9 +4,13 @@ local mc = require "multicast"
|
|||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
print("remote start")
|
print("remote start")
|
||||||
skynet.monitor("simplemonitor", true)
|
|
||||||
local console = skynet.newservice("console")
|
local console = skynet.newservice("console")
|
||||||
local channel = dc.get "MCCHANNEL"
|
local channel = dc.get "MCCHANNEL"
|
||||||
|
if channel then
|
||||||
|
print("remote channel", channel)
|
||||||
|
else
|
||||||
|
print("create local channel")
|
||||||
|
end
|
||||||
for i=1,10 do
|
for i=1,10 do
|
||||||
local sub = skynet.newservice("testmulticast", "sub")
|
local sub = skynet.newservice("testmulticast", "sub")
|
||||||
skynet.call(sub, "lua", "init", channel)
|
skynet.call(sub, "lua", "init", channel)
|
||||||
|
|||||||
Reference in New Issue
Block a user