├── README.md ├── config └── gs_config.lua ├── daobiao └── gamedata │ └── data.lua ├── lualib └── base │ ├── baseobj.lua │ ├── interactive.lua │ ├── loadshare.lua │ ├── preload.lua │ ├── protobuf.lua │ ├── reload.lua │ ├── share.lua │ └── tableop.lua ├── service ├── dictator │ ├── dictatorcmd.lua │ ├── dictatorobj.lua │ ├── global.lua │ ├── logiccmd │ │ ├── common.lua │ │ └── init.lua │ └── main.lua ├── gamedb │ ├── gamedbobj.lua │ ├── global.lua │ ├── logiccmd │ │ ├── init.lua │ │ └── testdb.lua │ └── main.lua ├── gs_launcher.lua └── share │ ├── logiccmd │ ├── common.lua │ └── init.lua │ └── main.lua ├── shell ├── gs_kill.sh ├── gs_run.sh └── make_proto.sh └── skynet ├── .gitignore ├── .gitmodules ├── 3rd ├── lpeg │ ├── HISTORY │ ├── lpcap.c │ ├── lpcap.h │ ├── lpcode.c │ ├── lpcode.h │ ├── lpeg-128.gif │ ├── lpeg.html │ ├── lpprint.c │ ├── lpprint.h │ ├── lptree.c │ ├── lptree.h │ ├── lptypes.h │ ├── lpvm.c │ ├── lpvm.h │ ├── makefile │ ├── re.html │ ├── re.lua │ └── test.lua ├── lua-md5 │ ├── README │ ├── compat-5.2.c │ ├── compat-5.2.h │ ├── md5.c │ ├── md5.h │ └── md5lib.c └── lua │ ├── Makefile │ ├── README │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lbitlib.c │ ├── lcode.c │ ├── lcode.h │ ├── lcorolib.c │ ├── lctype.c │ ├── lctype.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── liolib.c │ ├── llex.c │ ├── llex.h │ ├── llimits.h │ ├── lmathlib.c │ ├── lmem.c │ ├── lmem.h │ ├── loadlib.c │ ├── lobject.c │ ├── lobject.h │ ├── lopcodes.c │ ├── lopcodes.h │ ├── loslib.c │ ├── lparser.c │ ├── lparser.h │ ├── lprefix.h │ ├── lstate.c │ ├── lstate.h │ ├── lstring.c │ ├── lstring.h │ ├── lstrlib.c │ ├── ltable.c │ ├── ltable.h │ ├── ltablib.c │ ├── ltm.c │ ├── ltm.h │ ├── lua.c │ ├── lua.h │ ├── lua.hpp │ ├── luac.c │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lutf8lib.c │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ └── lzio.h ├── HISTORY.md ├── LICENSE ├── Makefile ├── README.md ├── examples ├── abort.lua ├── agent.lua ├── checkdeadloop.lua ├── client.lua ├── cluster1.lua ├── cluster2.lua ├── clustername.lua ├── config ├── config.c1 ├── config.c2 ├── config.login ├── config.mc ├── config.mysql ├── config.userlog ├── config_log ├── globallog.lua ├── injectlaunch.lua ├── login │ ├── client.lua │ ├── gated.lua │ ├── logind.lua │ ├── main.lua │ └── msgagent.lua ├── main.lua ├── main_log.lua ├── main_mysql.lua ├── preload.lua ├── proto.lua ├── protoloader.lua ├── share.lua ├── simpledb.lua ├── simplemonitor.lua ├── simpleweb.lua ├── userlog.lua └── watchdog.lua ├── lualib-src ├── lsha1.c ├── lua-bson.c ├── lua-clientsocket.c ├── lua-cluster.c ├── lua-crypt.c ├── lua-debugchannel.c ├── lua-memory.c ├── lua-mongo.c ├── lua-multicast.c ├── lua-mysqlaux.c ├── lua-netpack.c ├── lua-profile.c ├── lua-seri.c ├── lua-seri.h ├── lua-sharedata.c ├── lua-skynet.c ├── lua-socket.c ├── lua-stm.c └── sproto │ ├── README │ ├── README.md │ ├── lsproto.c │ ├── msvcint.h │ ├── sproto.c │ └── sproto.h ├── lualib ├── cluster.lua ├── datacenter.lua ├── dns.lua ├── http │ ├── httpc.lua │ ├── httpd.lua │ ├── internal.lua │ ├── sockethelper.lua │ └── url.lua ├── loader.lua ├── md5.lua ├── mongo.lua ├── mqueue.lua ├── multicast.lua ├── mysql.lua ├── redis.lua ├── sharedata.lua ├── sharedata │ └── corelib.lua ├── sharemap.lua ├── skynet.lua ├── skynet │ ├── coroutine.lua │ ├── debug.lua │ ├── harbor.lua │ ├── inject.lua │ ├── injectcode.lua │ ├── manager.lua │ ├── queue.lua │ └── remotedebug.lua ├── snax.lua ├── snax │ ├── gateserver.lua │ ├── hotfix.lua │ ├── interface.lua │ ├── loginserver.lua │ └── msgserver.lua ├── socket.lua ├── socketchannel.lua ├── sproto.lua ├── sprotoloader.lua └── sprotoparser.lua ├── pbc ├── Makefile ├── README.md ├── binding │ ├── lua │ │ ├── Makefile │ │ ├── README.md │ │ ├── build_ios.sh │ │ ├── parser.lua │ │ ├── pbc-lua.c │ │ ├── protobuf.lua │ │ ├── test.lua │ │ ├── test2.lua │ │ └── testparser.lua │ └── lua53 │ │ ├── Makefile │ │ ├── build_ios.sh │ │ ├── pbc-lua53.c │ │ ├── protobuf.lua │ │ └── test.lua ├── build │ └── o │ │ ├── alloc.d │ │ ├── array.d │ │ ├── bootstrap.d │ │ ├── context.d │ │ ├── decode.d │ │ ├── map.d │ │ ├── pattern.d │ │ ├── proto.d │ │ ├── register.d │ │ ├── rmessage.d │ │ ├── stringpool.d │ │ ├── varint.d │ │ └── wmessage.d ├── pbc-lua53.c ├── pbc.h └── src │ ├── alloc.c │ ├── alloc.h │ ├── array.c │ ├── array.h │ ├── bootstrap.c │ ├── bootstrap.h │ ├── context.c │ ├── context.h │ ├── decode.c │ ├── descriptor.pbc.h │ ├── map.c │ ├── map.h │ ├── pattern.c │ ├── pattern.h │ ├── proto.c │ ├── proto.h │ ├── register.c │ ├── rmessage.c │ ├── stringpool.c │ ├── stringpool.h │ ├── varint.c │ ├── varint.h │ └── wmessage.c ├── platform.mk ├── service-src ├── databuffer.h ├── hashid.h ├── service_gate.c ├── service_harbor.c ├── service_logger.c └── service_snlua.c ├── service ├── bootstrap.lua ├── cdummy.lua ├── clusterd.lua ├── clusterproxy.lua ├── cmaster.lua ├── cmemory.lua ├── console.lua ├── cslave.lua ├── datacenterd.lua ├── dbg.lua ├── debug_agent.lua ├── debug_console.lua ├── gate.lua ├── launcher.lua ├── multicastd.lua ├── service_mgr.lua ├── sharedatad.lua └── snaxd.lua ├── skynet-src ├── atomic.h ├── luashrtbl.h ├── malloc_hook.c ├── malloc_hook.h ├── rwlock.h ├── skynet.h ├── skynet_daemon.c ├── skynet_daemon.h ├── skynet_env.c ├── skynet_env.h ├── skynet_error.c ├── skynet_handle.c ├── skynet_handle.h ├── skynet_harbor.c ├── skynet_harbor.h ├── skynet_imp.h ├── skynet_log.c ├── skynet_log.h ├── skynet_main.c ├── skynet_malloc.h ├── skynet_module.c ├── skynet_module.h ├── skynet_monitor.c ├── skynet_monitor.h ├── skynet_mq.c ├── skynet_mq.h ├── skynet_server.c ├── skynet_server.h ├── skynet_socket.c ├── skynet_socket.h ├── skynet_start.c ├── skynet_timer.c ├── skynet_timer.h ├── socket_epoll.h ├── socket_kqueue.h ├── socket_poll.h ├── socket_server.c ├── socket_server.h └── spinlock.h └── test ├── pingserver.lua ├── sharemap.sp ├── testbson.lua ├── testcoroutine.lua ├── testdatacenter.lua ├── testdeadcall.lua ├── testdeadloop.lua ├── testdns.lua ├── testecho.lua ├── testharborlink.lua ├── testhttp.lua ├── testmemlimit.lua ├── testmongodb.lua ├── testmulticast.lua ├── testmulticast2.lua ├── testmysql.lua ├── testoverload.lua ├── testping.lua ├── testpipeline.lua ├── testqueue.lua ├── testredis.lua ├── testredis2.lua ├── testresponse.lua ├── testsha.lua ├── testsm.lua ├── testsocket.lua ├── teststm.lua ├── testterm.lua ├── testtimer.lua ├── testudp.lua └── time.lua /config/gs_config.lua: -------------------------------------------------------------------------------- 1 | root = "./" 2 | thread = 8 3 | logger = "log/gs.log" 4 | harbor = 0 5 | start = "gs_launcher" 6 | bootstrap = "snlua bootstrap" -- The service for bootstrap 7 | 8 | dictator_port = 7002 9 | sharedata_file = root.."lualib/base/loadshare.lua" 10 | 11 | ------------------路径配置------------------------------ 12 | luaservice = root.."service/?.lua;"..root.."service/?/main.lua;"..root.."skynet/service/?.lua;"..root.."skynet/service/?/main.lua" 13 | lua_path = root.."lualib/?.lua;"..root.."skynet/lualib/?.lua" 14 | lua_cpath = root.."skynet/luaclib/?.so" 15 | cpath = root.."skynet/cservice/?.so" 16 | lualoader = root.."skynet/lualib/loader.lua" 17 | preload = root.."lualib/base/preload.lua" 18 | ------------------路径配置------------------------------- 19 | -------------------------------------------------------------------------------- /daobiao/gamedata/data.lua: -------------------------------------------------------------------------------- 1 | return { 2 | test_data = {1, 2, 3, }, 3 | test_string = "string", 4 | test_number = 123124, 5 | } 6 | -------------------------------------------------------------------------------- /lualib/base/baseobj.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | CBaseObj = {} 4 | CBaseObj.__index = CBaseObj 5 | 6 | function CBaseObj:New() 7 | local o = setmetatable({}, self) 8 | o.m_mData = {} 9 | o.m_mInfo = {} 10 | o.m_bDirty = false 11 | return o 12 | end 13 | 14 | function CBaseObj:GetData(k, default) 15 | return self.m_mData[k] or defalut 16 | end 17 | 18 | function CBaseObj:SetData(k, v) 19 | self.m_mData[k] = v 20 | end 21 | 22 | function CBaseObj:GetInfo(k, default) 23 | return self.m_mInfo[k] or default 24 | end 25 | 26 | function CBaseObj:SetInfo(k, v) 27 | self.m_mInfo[k] = v 28 | end 29 | 30 | function CBaseObj:IsDirty() 31 | return self.m_bDirty 32 | end 33 | 34 | function CBaseObj:Dirty() 35 | self.m_bDirty = true 36 | end 37 | 38 | function CBaseObj:UnDirty() 39 | self.m_bDirty = false 40 | end 41 | -------------------------------------------------------------------------------- /lualib/base/loadshare.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function Require(sPath) 4 | local f = loadfile_ex(sPath) 5 | return f() 6 | end 7 | 8 | M.daobiao = Require("daobiao/gamedata/data.lua") 9 | 10 | return M 11 | -------------------------------------------------------------------------------- /lualib/base/preload.lua: -------------------------------------------------------------------------------- 1 | 2 | MY_ADDR = ... 3 | 4 | local skynet = require "skynet" 5 | require "base.tableop" 6 | 7 | print = function(...) 8 | local info_list = table.pack(...) 9 | local ret_list = {} 10 | for i = 1, #info_list do 11 | if info_list[i] == "nil" then 12 | table.insert(ret_list, "nil") 13 | elseif type(info_list[i]) == "table" then 14 | table.insert(ret_list, table_serialize(info_list[i])) 15 | else 16 | table.insert(ret_list, info_list[i]) 17 | end 18 | end 19 | skynet.error(table.unpack(ret_list)) 20 | end 21 | 22 | inherit = function(children, parent) 23 | setmetatable(children, parent) 24 | end 25 | 26 | super = function(class) 27 | return getmetatable(class) 28 | end 29 | 30 | trace_msg = function(msg) 31 | print(debug.traceback("=====" .. msg .. "=====")) 32 | end 33 | 34 | safe_call = function(func, ...) 35 | xpcall(func, trace_msg, ...) 36 | end 37 | 38 | loadfile_ex = function(file_name, mode, env) 39 | mode = mode or "rb" 40 | local fp = io.open(file_name, mode) 41 | local data = fp:read("a") 42 | fp:close() 43 | local f, s = load(data, file_name, "bt", env) 44 | assert(f, s) 45 | return f 46 | end 47 | 48 | service_path = function(dotfile) 49 | return "service."..MY_ADDR.."."..dotfile 50 | end 51 | 52 | lualib_path = function(dotfile) 53 | return "lualib".."."..dotfile 54 | end 55 | 56 | require "base.reload" 57 | -------------------------------------------------------------------------------- /lualib/base/reload.lua: -------------------------------------------------------------------------------- 1 | local module = {} 2 | 3 | function import(dotfile) 4 | if module[dotfile] then 5 | return module[dotfile] 6 | end 7 | 8 | local file_name = string.gsub(dotfile, "%.", "/") .. ".lua" 9 | local m = setmetatable({}, {__index = _G}) 10 | local f = loadfile_ex(file_name, "rb", m) 11 | f() 12 | module[dotfile] = m 13 | return m 14 | end 15 | 16 | function reload(dotfile) 17 | if not module[dotfile] then 18 | return 19 | end 20 | 21 | local new_m = module[dotfile] 22 | local bak_m = table_copy(new_m) 23 | local file_name = string.gsub(dotfile, "%.", "/") .. ".lua" 24 | local f = loadfile_ex(file_name, "rb", new_m) 25 | if not f then return end 26 | f() 27 | 28 | local visited, recu = {}, nil 29 | recu = function(old, new) 30 | for k, v in pairs(new) do 31 | if not visited[k] then 32 | visited[k] = true 33 | if type(old[k]) == "table" and type(new[k]) == "table" then 34 | recu(old[k], new[k]) 35 | else 36 | old[k] = v 37 | end 38 | end 39 | end 40 | for k, v in pairs(old) do 41 | if not visited[k] and not new[k] then 42 | visited[k] = true 43 | old[k] = nil 44 | end 45 | end 46 | end 47 | 48 | local ret, msg = pcall(function() 49 | for k, v in pairs(new_m) do 50 | if type(v) == "table" and type(bak_m[k]) == "table" then 51 | recu(bak_m[k], v) 52 | new_m[k] = bak_m[k] 53 | end 54 | end 55 | end) 56 | 57 | if not ret then 58 | print("reload fail:", msg) 59 | --TODO need return back 60 | print("return back success") 61 | else 62 | print("reload success:", file_name) 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /lualib/base/share.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local sharedata = require "sharedata" 3 | 4 | local M = {} 5 | 6 | skynet.init(function() 7 | --避免每次query创建一个table,一个服务只创建一个table 8 | --此种写法有一个要求就是需要每个server启动的时候,require "base.share" 进行一次初始化 9 | local box = sharedata.query("share") 10 | setmetatable(M, {__index = box}) 11 | end, "share") 12 | 13 | return M 14 | -------------------------------------------------------------------------------- /lualib/base/tableop.lua: -------------------------------------------------------------------------------- 1 | function table_copy(tbl) 2 | local res = {} 3 | for k, v in pairs(tbl) do 4 | res[k] = v 5 | end 6 | return res 7 | end 8 | 9 | function table_deep_copy(tbl) 10 | --TODO 11 | return tbl 12 | end 13 | 14 | function table_serialize(tbl, visited) 15 | visited = visited or {} 16 | local con = "{" 17 | for k, v in pairs(tbl) do 18 | if not visited[k] or visited[k] ~= v then 19 | visited[k] = v 20 | if type(k) == "table" then 21 | con = con.."["..table_serialize(k, visited).."] = " 22 | elseif type(k) == "number" then 23 | con = con.."["..tostring(k).."] = " 24 | else 25 | con = con..tostring(k).." = " 26 | end 27 | if type(v) == "table" then 28 | con = con..table_serialize(v, visited) 29 | else 30 | con = con .. tostring(v) 31 | end 32 | con = con .. ", " 33 | end 34 | end 35 | con = con .. "}" 36 | return con 37 | end 38 | -------------------------------------------------------------------------------- /service/dictator/dictatorcmd.lua: -------------------------------------------------------------------------------- 1 | ------------------------------ 2 | --此模块主要用于实现后台指令 3 | ------------------------------ 4 | 5 | local global = require "global" 6 | local interactive = require "base.interactive" 7 | 8 | function update_code(stdin, print_back, file) 9 | --热更代码 10 | local dotfile = string.gsub(file, "%/", ".") 11 | global.oDictatorObj:UpdateCode(dotfile) 12 | end 13 | 14 | function uc(stdin, print_back, file) 15 | update_code(stdin, print_back, file) 16 | end 17 | 18 | function update_share(stdin, print_back) 19 | --更新sharedata 共享数据块 20 | interactive.send(".share", "common", "UpdateShareData") 21 | end 22 | 23 | function inter(stdin, print_back) 24 | local skynet = require "skynet" 25 | local interactive = require "base.interactive" 26 | --interactive.send(".world", "module", "function", "args") 27 | interactive.send(".gamedb", "testdb", "SaveInfo2TestDb") 28 | end 29 | -------------------------------------------------------------------------------- /service/dictator/dictatorobj.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local interactive = require "base.interactive" 3 | local baseobj = import(lualib_path("base.baseobj")) 4 | 5 | function NewDictatorObj(...) 6 | return CDictator:New(...) 7 | end 8 | 9 | 10 | CDictator = {} 11 | CDictator.__index = CDictator 12 | inherit(CDictator, baseobj.CBaseObj) 13 | 14 | function CDictator:New(...) 15 | local o = super(CDictator).New(self) 16 | o.m_mService = {} 17 | return o 18 | end 19 | 20 | function CDictator:RegisterService(sAddr, iInst) 21 | if not self.m_mService[sAddr] then 22 | self.m_mService[sAddr] = {} 23 | end 24 | self.m_mService[sAddr][iInst] = true 25 | end 26 | 27 | function CDictator:UpdateCode(dotfile) 28 | local sExecute = string.format([[ 29 | reload("%s") 30 | ]], dotfile) 31 | for sAddr, mInst in pairs(self.m_mService) do 32 | for iInst, _ in pairs(mInst) do 33 | interactive.send(iInst, "default", "ExecuteString", sExecute) 34 | end 35 | end 36 | end 37 | 38 | -------------------------------------------------------------------------------- /service/dictator/global.lua: -------------------------------------------------------------------------------- 1 | M = {} 2 | 3 | M.oDictatorObj = nil 4 | 5 | return M 6 | -------------------------------------------------------------------------------- /service/dictator/logiccmd/common.lua: -------------------------------------------------------------------------------- 1 | local global = require "global" 2 | 3 | function RegisterService(mRecord, mArgs) 4 | local iInst = mArgs.inst 5 | local sAddr = mArgs.addr 6 | global.oDictatorObj:RegisterService(sAddr, iInst) 7 | end 8 | -------------------------------------------------------------------------------- /service/dictator/logiccmd/init.lua: -------------------------------------------------------------------------------- 1 | 2 | local mCmd = {} 3 | 4 | mCmd.common = import(service_path("logiccmd.common")) 5 | 6 | 7 | function Invoke(sModule, sFunc, ...) 8 | if not mCmd[sModule] then 9 | print("err: there is not invoke module:"..sModule..", check please") 10 | return 11 | end 12 | if not mCmd[sModule][sFunc] then 13 | print("err: there is not invoke func:"..sFunc..", check please") 14 | return 15 | end 16 | 17 | mCmd[sModule][sFunc](...) 18 | end 19 | -------------------------------------------------------------------------------- /service/gamedb/gamedbobj.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local mongo = require "mongo" 3 | local baseobj = import(lualib_path("base.baseobj")) 4 | 5 | function NewGameDbObj(...) 6 | return CGameDb:New(...) 7 | end 8 | 9 | 10 | CGameDb = {} 11 | CGameDb.__index = CGameDb 12 | inherit(CGameDb, baseobj.CBaseObj) 13 | 14 | function CGameDb:New(mConfig, sDbName) 15 | local o = super(CGameDb).New(self) 16 | o.m_oClient = nil 17 | o.m_sDbName = sDbName 18 | o:Init(mConfig) 19 | return o 20 | end 21 | 22 | function CGameDb:Init(mConfig) 23 | local oClient = mongo.client(mConfig) 24 | self.m_oClient = oClient 25 | end 26 | 27 | function CGameDb:GetDb() 28 | return self.m_oClient:getDB(self.m_sDbName) 29 | end 30 | 31 | function CGameDb:Insert(sTable, mInsert) 32 | --Insert("player", {account="xterm"}) 33 | local obj = self:GetDb() 34 | obj[sTable]:safe_insert(mInsert) 35 | end 36 | 37 | function CGameDb:Update(sTable, mCond, mUpdate, bUpsert, bMulti) 38 | --Update("player, {account="xterm"}, {account="xteam", age=17}, true, false) 39 | local obj = self:GetDb() 40 | obj[sTable]:update(mCond, mUpdate, bUpsert, bMulti) 41 | end 42 | 43 | function CGameDb:Delete(sTable, mCond, bSingle) 44 | local obj = self:GetDb() 45 | obj[sTable]:delete(mCond, bSingle) 46 | end 47 | 48 | function CGameDb:FindOne(sTable, mQuery, mSelect) 49 | local obj = self:GetDb() 50 | local m = obj[sTable]:findOne(mQuery, mSelect) 51 | return m 52 | end 53 | 54 | function CGameDb:Find(sTable, mQuery, mSelect) 55 | local obj = self:GetDb() 56 | local m = obj[sTable]:find(mQuery, mSelect) 57 | -- while m:hasNext() do 58 | -- print(m:next()) 59 | -- end 60 | return m 61 | end 62 | 63 | function CGameDb:EnsureIndex(sTable, ...) 64 | --EnsureIndex({index_key=1}, {unique=true,name="name_index"}) 65 | local obj = self:GetDb() 66 | obj[sTable]:ensureIndex(...) 67 | end 68 | 69 | function CGameDb:FindAndModify(mConf) 70 | local obj = self:GetDb() 71 | obj:findAndModify(mConf) 72 | end 73 | -------------------------------------------------------------------------------- /service/gamedb/global.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.oGameDb = nil 4 | 5 | return M 6 | -------------------------------------------------------------------------------- /service/gamedb/logiccmd/init.lua: -------------------------------------------------------------------------------- 1 | 2 | local mCmd = {} 3 | 4 | mCmd.testdb = import(service_path("logiccmd.testdb")) 5 | 6 | 7 | function Invoke(sModule, sFunc, ...) 8 | if not mCmd[sModule] then 9 | print("err: there is not invoke module:"..sModule..", check please") 10 | return 11 | end 12 | if not mCmd[sModule][sFunc] then 13 | print("err: there is not invoke func:"..sFunc..", check please") 14 | return 15 | end 16 | 17 | mCmd[sModule][sFunc](...) 18 | end 19 | -------------------------------------------------------------------------------- /service/gamedb/logiccmd/testdb.lua: -------------------------------------------------------------------------------- 1 | local global = require "global" 2 | 3 | local sTableName = "test" 4 | 5 | function SaveInfo2TestDb(...) 6 | --global.oGameDb:EnsureIndex(sTableName, {pid=1}, {unique=true}) 7 | --global.oGameDb:Insert(sTableName, {pid=10001, base={name="testdata", count=90909}}) 8 | --global.oGameDb:Insert(sTableName, {pid=10002, base={name="testdata", count=90909}}) 9 | --global.oGameDb:Insert(sTableName, {pid=10003, base={name="testdata", count=90909}}) 10 | --global.oGameDb:Update(sTableName, {pid=10003}, {["$set"] = {base={name="testdata", count=90919}}}) 11 | --global.oGameDb:Find(sTableName, {pid=10004}) --need use next func to get useful data 12 | --global.oGameDb:FindOne(sTableName, {pid=10004}) 13 | end 14 | -------------------------------------------------------------------------------- /service/gamedb/main.lua: -------------------------------------------------------------------------------- 1 | 2 | local skynet = require "skynet.manager" 3 | local global = require "global" 4 | local interactive = require "base.interactive" 5 | local share = require "base.share" 6 | local gamedb = import(service_path("gamedbobj")) 7 | local logiccmd = import(service_path("logiccmd.init")) 8 | 9 | 10 | skynet.start(function() 11 | interactive.dispatch_logic(logiccmd) 12 | 13 | local mConfig = {host="127.0.0.1", port="27017"} 14 | global.oGameDb = gamedb.NewGameDbObj(mConfig, "game") 15 | 16 | --TODO ensure index 17 | 18 | skynet.register(".gamedb") 19 | interactive.send(".dictator", "common", "RegisterService", { 20 | addr = "."..MY_ADDR, 21 | inst = skynet.self(), 22 | }) 23 | skynet.error("gamedb service booted") 24 | end) 25 | -------------------------------------------------------------------------------- /service/gs_launcher.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | skynet.start(function() 4 | skynet.newservice("share") 5 | skynet.newservice("debug_console", 7001) 6 | skynet.newservice("dictator") 7 | skynet.newservice("gamedb") 8 | --skynet.newservice("world") 9 | end) 10 | -------------------------------------------------------------------------------- /service/share/logiccmd/common.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local sharedata = require "sharedata" 3 | 4 | function UpdateShareData(mRecord, mArgs) 5 | local fp = io.open(skynet.getenv("sharedata_file")) 6 | local data = fp:read("a") 7 | fp:close() 8 | 9 | sharedata.update("share", data) 10 | end 11 | -------------------------------------------------------------------------------- /service/share/logiccmd/init.lua: -------------------------------------------------------------------------------- 1 | 2 | local mCmd = {} 3 | 4 | mCmd.common = import(service_path("logiccmd.common")) 5 | 6 | 7 | function Invoke(sModule, sFunc, ...) 8 | if not mCmd[sModule] then 9 | print("err: there is not invoke module:"..sModule..", check please") 10 | return 11 | end 12 | if not mCmd[sModule][sFunc] then 13 | print("err: there is not invoke func:"..sFunc..", check please") 14 | return 15 | end 16 | 17 | mCmd[sModule][sFunc](...) 18 | end 19 | -------------------------------------------------------------------------------- /service/share/main.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local manager = require "skynet.manager" 3 | local sharedata = require "sharedata" 4 | local interactive = require "base.interactive" 5 | local logiccmd = import(service_path("logiccmd.init")) 6 | 7 | skynet.start(function() 8 | interactive.dispatch_logic(logiccmd) 9 | 10 | local fp = io.open(skynet.getenv("sharedata_file")) 11 | local data = fp:read("a") 12 | fp:close() 13 | sharedata.new("share", data) 14 | 15 | manager.register ".share" 16 | skynet.error("share service booted") 17 | end) 18 | -------------------------------------------------------------------------------- /shell/gs_kill.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ps ux |grep skynet |grep config |awk '{print $2}' |xargs kill -9 3 | -------------------------------------------------------------------------------- /shell/gs_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./shell/gs_kill.sh 3 | ./skynet/skynet ./config/gs_config.lua & 4 | -------------------------------------------------------------------------------- /shell/make_proto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protoc -I=./proto/ -o./proto/proto.pb `find ./ -name '*.proto'` 4 | -------------------------------------------------------------------------------- /skynet/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | /skynet 4 | /skynet.pid 5 | 3rd/lua/lua 6 | 3rd/lua/luac 7 | /cservice 8 | /luaclib 9 | *.so 10 | *.dSYM 11 | .DS_Store 12 | -------------------------------------------------------------------------------- /skynet/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "3rd/jemalloc"] 2 | path = 3rd/jemalloc 3 | url = https://github.com/jemalloc/jemalloc.git 4 | -------------------------------------------------------------------------------- /skynet/3rd/lpeg/lpcap.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lpcap.h,v 1.2 2015/02/27 17:13:17 roberto Exp $ 3 | */ 4 | 5 | #if !defined(lpcap_h) 6 | #define lpcap_h 7 | 8 | 9 | #include "lptypes.h" 10 | 11 | 12 | /* kinds of captures */ 13 | typedef enum CapKind { 14 | Cclose, Cposition, Cconst, Cbackref, Carg, Csimple, Ctable, Cfunction, 15 | Cquery, Cstring, Cnum, Csubst, Cfold, Cruntime, Cgroup 16 | } CapKind; 17 | 18 | 19 | typedef struct Capture { 20 | const char *s; /* subject position */ 21 | unsigned short idx; /* extra info (group name, arg index, etc.) */ 22 | byte kind; /* kind of capture */ 23 | byte siz; /* size of full capture + 1 (0 = not a full capture) */ 24 | } Capture; 25 | 26 | 27 | typedef struct CapState { 28 | Capture *cap; /* current capture */ 29 | Capture *ocap; /* (original) capture list */ 30 | lua_State *L; 31 | int ptop; /* index of last argument to 'match' */ 32 | const char *s; /* original string */ 33 | int valuecached; /* value stored in cache slot */ 34 | } CapState; 35 | 36 | 37 | int runtimecap (CapState *cs, Capture *close, const char *s, int *rem); 38 | int getcaptures (lua_State *L, const char *s, const char *r, int ptop); 39 | int finddyncap (Capture *cap, Capture *last); 40 | 41 | #endif 42 | 43 | 44 | -------------------------------------------------------------------------------- /skynet/3rd/lpeg/lpcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lpcode.h,v 1.7 2015/06/12 18:24:45 roberto Exp $ 3 | */ 4 | 5 | #if !defined(lpcode_h) 6 | #define lpcode_h 7 | 8 | #include "lua.h" 9 | 10 | #include "lptypes.h" 11 | #include "lptree.h" 12 | #include "lpvm.h" 13 | 14 | int tocharset (TTree *tree, Charset *cs); 15 | int checkaux (TTree *tree, int pred); 16 | int fixedlenx (TTree *tree, int count, int len); 17 | int hascaptures (TTree *tree); 18 | int lp_gc (lua_State *L); 19 | Instruction *compile (lua_State *L, Pattern *p); 20 | void realloccode (lua_State *L, Pattern *p, int nsize); 21 | int sizei (const Instruction *i); 22 | 23 | 24 | #define PEnullable 0 25 | #define PEnofail 1 26 | 27 | /* 28 | ** nofail(t) implies that 't' cannot fail with any input 29 | */ 30 | #define nofail(t) checkaux(t, PEnofail) 31 | 32 | /* 33 | ** (not nullable(t)) implies 't' cannot match without consuming 34 | ** something 35 | */ 36 | #define nullable(t) checkaux(t, PEnullable) 37 | 38 | #define fixedlen(t) fixedlenx(t, 0, 0) 39 | 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /skynet/3rd/lpeg/lpeg-128.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifzz/game_dev/1646bc2fe2cd4d1de64e4b81684d8a286af3263c/skynet/3rd/lpeg/lpeg-128.gif -------------------------------------------------------------------------------- /skynet/3rd/lpeg/lpprint.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lpprint.h,v 1.2 2015/06/12 18:18:08 roberto Exp $ 3 | */ 4 | 5 | 6 | #if !defined(lpprint_h) 7 | #define lpprint_h 8 | 9 | 10 | #include "lptree.h" 11 | #include "lpvm.h" 12 | 13 | 14 | #if defined(LPEG_DEBUG) 15 | 16 | void printpatt (Instruction *p, int n); 17 | void printtree (TTree *tree, int ident); 18 | void printktable (lua_State *L, int idx); 19 | void printcharset (const byte *st); 20 | void printcaplist (Capture *cap, Capture *limit); 21 | void printinst (const Instruction *op, const Instruction *p); 22 | 23 | #else 24 | 25 | #define printktable(L,idx) \ 26 | luaL_error(L, "function only implemented in debug mode") 27 | #define printtree(tree,i) \ 28 | luaL_error(L, "function only implemented in debug mode") 29 | #define printpatt(p,n) \ 30 | luaL_error(L, "function only implemented in debug mode") 31 | 32 | #endif 33 | 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /skynet/3rd/lpeg/lptree.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lptree.h,v 1.2 2013/03/24 13:51:12 roberto Exp $ 3 | */ 4 | 5 | #if !defined(lptree_h) 6 | #define lptree_h 7 | 8 | 9 | #include "lptypes.h" 10 | 11 | 12 | /* 13 | ** types of trees 14 | */ 15 | typedef enum TTag { 16 | TChar = 0, TSet, TAny, /* standard PEG elements */ 17 | TTrue, TFalse, 18 | TRep, 19 | TSeq, TChoice, 20 | TNot, TAnd, 21 | TCall, 22 | TOpenCall, 23 | TRule, /* sib1 is rule's pattern, sib2 is 'next' rule */ 24 | TGrammar, /* sib1 is initial (and first) rule */ 25 | TBehind, /* match behind */ 26 | TCapture, /* regular capture */ 27 | TRunTime /* run-time capture */ 28 | } TTag; 29 | 30 | /* number of siblings for each tree */ 31 | extern const byte numsiblings[]; 32 | 33 | 34 | /* 35 | ** Tree trees 36 | ** The first sibling of a tree (if there is one) is immediately after 37 | ** the tree. A reference to a second sibling (ps) is its position 38 | ** relative to the position of the tree itself. A key in ktable 39 | ** uses the (unique) address of the original tree that created that 40 | ** entry. NULL means no data. 41 | */ 42 | typedef struct TTree { 43 | byte tag; 44 | byte cap; /* kind of capture (if it is a capture) */ 45 | unsigned short key; /* key in ktable for Lua data (0 if no key) */ 46 | union { 47 | int ps; /* occasional second sibling */ 48 | int n; /* occasional counter */ 49 | } u; 50 | } TTree; 51 | 52 | 53 | /* 54 | ** A complete pattern has its tree plus, if already compiled, 55 | ** its corresponding code 56 | */ 57 | typedef struct Pattern { 58 | union Instruction *code; 59 | int codesize; 60 | TTree tree[1]; 61 | } Pattern; 62 | 63 | 64 | /* number of siblings for each tree */ 65 | extern const byte numsiblings[]; 66 | 67 | /* access to siblings */ 68 | #define sib1(t) ((t) + 1) 69 | #define sib2(t) ((t) + (t)->u.ps) 70 | 71 | 72 | 73 | 74 | 75 | 76 | #endif 77 | 78 | -------------------------------------------------------------------------------- /skynet/3rd/lpeg/lpvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lpvm.h,v 1.3 2014/02/21 13:06:41 roberto Exp $ 3 | */ 4 | 5 | #if !defined(lpvm_h) 6 | #define lpvm_h 7 | 8 | #include "lpcap.h" 9 | 10 | 11 | /* Virtual Machine's instructions */ 12 | typedef enum Opcode { 13 | IAny, /* if no char, fail */ 14 | IChar, /* if char != aux, fail */ 15 | ISet, /* if char not in buff, fail */ 16 | ITestAny, /* in no char, jump to 'offset' */ 17 | ITestChar, /* if char != aux, jump to 'offset' */ 18 | ITestSet, /* if char not in buff, jump to 'offset' */ 19 | ISpan, /* read a span of chars in buff */ 20 | IBehind, /* walk back 'aux' characters (fail if not possible) */ 21 | IRet, /* return from a rule */ 22 | IEnd, /* end of pattern */ 23 | IChoice, /* stack a choice; next fail will jump to 'offset' */ 24 | IJmp, /* jump to 'offset' */ 25 | ICall, /* call rule at 'offset' */ 26 | IOpenCall, /* call rule number 'key' (must be closed to a ICall) */ 27 | ICommit, /* pop choice and jump to 'offset' */ 28 | IPartialCommit, /* update top choice to current position and jump */ 29 | IBackCommit, /* "fails" but jump to its own 'offset' */ 30 | IFailTwice, /* pop one choice and then fail */ 31 | IFail, /* go back to saved state on choice and jump to saved offset */ 32 | IGiveup, /* internal use */ 33 | IFullCapture, /* complete capture of last 'off' chars */ 34 | IOpenCapture, /* start a capture */ 35 | ICloseCapture, 36 | ICloseRunTime 37 | } Opcode; 38 | 39 | 40 | 41 | typedef union Instruction { 42 | struct Inst { 43 | byte code; 44 | byte aux; 45 | short key; 46 | } i; 47 | int offset; 48 | byte buff[1]; 49 | } Instruction; 50 | 51 | 52 | void printpatt (Instruction *p, int n); 53 | const char *match (lua_State *L, const char *o, const char *s, const char *e, 54 | Instruction *op, Capture *capture, int ptop); 55 | 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /skynet/3rd/lpeg/makefile: -------------------------------------------------------------------------------- 1 | LIBNAME = lpeg 2 | LUADIR = ../lua/ 3 | 4 | COPT = -O2 5 | # COPT = -DLPEG_DEBUG -g 6 | 7 | CWARNS = -Wall -Wextra -pedantic \ 8 | -Waggregate-return \ 9 | -Wcast-align \ 10 | -Wcast-qual \ 11 | -Wdisabled-optimization \ 12 | -Wpointer-arith \ 13 | -Wshadow \ 14 | -Wsign-compare \ 15 | -Wundef \ 16 | -Wwrite-strings \ 17 | -Wbad-function-cast \ 18 | -Wdeclaration-after-statement \ 19 | -Wmissing-prototypes \ 20 | -Wnested-externs \ 21 | -Wstrict-prototypes \ 22 | # -Wunreachable-code \ 23 | 24 | 25 | CFLAGS = $(CWARNS) $(COPT) -std=c99 -I$(LUADIR) -fPIC 26 | CC = gcc 27 | 28 | FILES = lpvm.o lpcap.o lptree.o lpcode.o lpprint.o 29 | 30 | # For Linux 31 | linux: 32 | make lpeg.so "DLLFLAGS = -shared -fPIC" 33 | 34 | # For Mac OS 35 | macosx: 36 | make lpeg.so "DLLFLAGS = -bundle -undefined dynamic_lookup" 37 | 38 | lpeg.so: $(FILES) 39 | env $(CC) $(DLLFLAGS) $(FILES) -o lpeg.so 40 | 41 | $(FILES): makefile 42 | 43 | test: test.lua re.lua lpeg.so 44 | ./test.lua 45 | 46 | clean: 47 | rm -f $(FILES) lpeg.so 48 | 49 | 50 | lpcap.o: lpcap.c lpcap.h lptypes.h 51 | lpcode.o: lpcode.c lptypes.h lpcode.h lptree.h lpvm.h lpcap.h 52 | lpprint.o: lpprint.c lptypes.h lpprint.h lptree.h lpvm.h lpcap.h 53 | lptree.o: lptree.c lptypes.h lpcap.h lpcode.h lptree.h lpvm.h lpprint.h 54 | lpvm.o: lpvm.c lpcap.h lptypes.h lpvm.h lpprint.h lptree.h 55 | 56 | -------------------------------------------------------------------------------- /skynet/3rd/lua-md5/README: -------------------------------------------------------------------------------- 1 | MD5 - Cryptographic Library for Lua 2 | Copyright 2003 PUC-Rio 3 | http://www.keplerproject.org/md5 4 | 5 | MD5 offers basic cryptographic facilities for Lua 5.1: a hash (digest) 6 | function, a pair crypt/decrypt based on MD5 and CFB, and a pair crypt/decrypt based 7 | on DES with 56-bit keys. 8 | 9 | MD5 current version is 1.1.2. 10 | 11 | This version is copy from https://github.com/keplerproject/md5 12 | 13 | -------------------------------------------------------------------------------- /skynet/3rd/lua-md5/compat-5.2.c: -------------------------------------------------------------------------------- 1 | #include "lua.h" 2 | #include "lauxlib.h" 3 | #include "compat-5.2.h" 4 | 5 | #if !defined LUA_VERSION_NUM || LUA_VERSION_NUM==501 6 | /* 7 | ** Adapted from Lua 5.2.0 8 | */ 9 | void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { 10 | luaL_checkstack(L, nup+1, "too many upvalues"); 11 | for (; l->name != NULL; l++) { /* fill the table with given functions */ 12 | int i; 13 | lua_pushstring(L, l->name); 14 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ 15 | lua_pushvalue(L, -(nup + 1)); 16 | lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ 17 | lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */ 18 | } 19 | lua_pop(L, nup); /* remove upvalues */ 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /skynet/3rd/lua-md5/compat-5.2.h: -------------------------------------------------------------------------------- 1 | #if !defined LUA_VERSION_NUM 2 | /* Lua 5.0 */ 3 | #define luaL_Reg luaL_reg 4 | 5 | #define luaL_addchar(B,c) \ 6 | ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ 7 | (*(B)->p++ = (char)(c))) 8 | #endif 9 | 10 | #if LUA_VERSION_NUM==501 11 | /* Lua 5.1 */ 12 | #define lua_rawlen lua_objlen 13 | #endif 14 | 15 | void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup); 16 | -------------------------------------------------------------------------------- /skynet/3rd/lua-md5/md5.h: -------------------------------------------------------------------------------- 1 | /** 2 | * $Id: md5.h,v 1.2 2006/03/03 15:04:49 tomas Exp $ 3 | * Cryptographic module for Lua. 4 | * @author Roberto Ierusalimschy 5 | */ 6 | 7 | 8 | #ifndef md5_h 9 | #define md5_h 10 | 11 | #include 12 | 13 | 14 | #define HASHSIZE 16 15 | 16 | void md5 (const char *message, long len, char *output); 17 | int luaopen_md5_core (lua_State *L); 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /skynet/3rd/lua/README: -------------------------------------------------------------------------------- 1 | This is a modify version of lua 5.3.2 (http://www.lua.org/ftp/lua-5.3.2.tar.gz) . 2 | 3 | For detail , 4 | Shared Proto : http://lua-users.org/lists/lua-l/2014-03/msg00489.html 5 | Shared short string table : http://blog.codingnow.com/2015/08/lua_vm_share_string.html 6 | Signal for debug use : http://blog.codingnow.com/2015/03/skynet_signal.html 7 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 15 | "stack overflow");} 16 | 17 | #define adjustresults(L,nres) \ 18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 19 | 20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 21 | "not enough elements in the stack") 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lctype.h" 14 | 15 | #if !LUA_USE_CTYPE /* { */ 16 | 17 | #include 18 | 19 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 20 | 0x00, /* EOZ */ 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 22 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 26 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 27 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 28 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 29 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 30 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 31 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 32 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 33 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 34 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 35 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 36 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | }; 54 | 55 | #endif /* } */ 56 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | /* 65 | ** this 'ltolower' only works for alphabetic characters 66 | */ 67 | #define ltolower(c) ((c) | ('A' ^ 'a')) 68 | 69 | 70 | /* two more entries for 0 and -1 (EOZ) */ 71 | LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; 72 | 73 | 74 | #else /* }{ */ 75 | 76 | /* 77 | ** use standard C ctypes 78 | */ 79 | 80 | #include 81 | 82 | 83 | #define lislalpha(c) (isalpha(c) || (c) == '_') 84 | #define lislalnum(c) (isalnum(c) || (c) == '_') 85 | #define lisdigit(c) (isdigit(c)) 86 | #define lisspace(c) (isspace(c)) 87 | #define lisprint(c) (isprint(c)) 88 | #define lisxdigit(c) (isxdigit(c)) 89 | 90 | #define ltolower(c) (tolower(c)) 91 | 92 | #endif /* } */ 93 | 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /skynet/3rd/lua/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->sp->code) - 1) 15 | 16 | #define getfuncline(f,pc) (((f)->sp->lineinfo) ? (f)->sp->lineinfo[pc] : -1) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | 21 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 22 | const char *opname); 23 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 24 | const TValue *p2); 25 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 26 | const TValue *p2, 27 | const char *msg); 28 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 29 | const TValue *p2); 30 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 31 | const TValue *p2); 32 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 33 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 34 | TString *src, int line); 35 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 36 | LUAI_FUNC void luaG_traceexec (lua_State *L); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /skynet/3rd/lua/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Macro to check stack size and grow stack if needed. Parameters 18 | ** 'pre'/'pos' allow the macro to preserve a pointer into the 19 | ** stack across reallocations, doing the work only when needed. 20 | ** 'condmovestack' is used in heavy tests to force a stack reallocation 21 | ** at every check. 22 | */ 23 | #define luaD_checkstackaux(L,n,pre,pos) \ 24 | if (L->stack_last - L->top <= (n)) \ 25 | { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); } 26 | 27 | /* In general, 'pre'/'pos' are empty (nothing to save) */ 28 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) 29 | 30 | 31 | 32 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 33 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 34 | 35 | 36 | /* type of protected functions, to be ran by 'runprotected' */ 37 | typedef void (*Pfunc) (lua_State *L, void *ud); 38 | 39 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 40 | const char *mode); 41 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); 42 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 43 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 44 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 45 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 46 | ptrdiff_t oldtop, ptrdiff_t ef); 47 | LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, 48 | int nres); 49 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 50 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 51 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 52 | LUAI_FUNC void luaD_inctop (lua_State *L); 53 | 54 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 55 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ 15 | cast(int, sizeof(TValue)*((n)-1))) 16 | 17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ 18 | cast(int, sizeof(TValue *)*((n)-1))) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | /* 33 | ** Upvalues for Lua closures 34 | */ 35 | struct UpVal { 36 | TValue *v; /* points to stack or to its own value */ 37 | lu_mem refcount; /* reference counter */ 38 | union { 39 | struct { /* (when open) */ 40 | UpVal *next; /* linked list */ 41 | int touched; /* mark to avoid cycles with dead threads */ 42 | } open; 43 | TValue value; /* the value (when closed) */ 44 | } u; 45 | }; 46 | 47 | #define upisopen(up) ((up)->v != &(up)->u.value) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L, SharedProto *sp); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 57 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 58 | int pc); 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /skynet/3rd/lua/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove _PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {"_G", luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | #if defined(LUA_COMPAT_BITLIB) 54 | {LUA_BITLIBNAME, luaopen_bit32}, 55 | #endif 56 | {NULL, NULL} 57 | }; 58 | 59 | 60 | LUALIB_API void luaL_openlibs (lua_State *L) { 61 | const luaL_Reg *lib; 62 | /* "require" functions from 'loadedlibs' and set results to global table */ 63 | for (lib = loadedlibs; lib->func; lib++) { 64 | luaL_requiref(L, lib->name, lib->func, 1); 65 | lua_pop(L, 1); /* remove lib */ 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.61 2015/11/03 15:36:01 roberto Exp $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) 16 | 17 | #define sizeludata(l) (sizeof(union UUdata) + (l)) 18 | #define sizeudata(u) sizeludata((u)->len) 19 | 20 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 21 | (sizeof(s)/sizeof(char))-1)) 22 | 23 | 24 | /* 25 | ** test whether a string is a reserved word 26 | */ 27 | #define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0) 28 | 29 | 30 | /* 31 | ** equality for short strings, which are always internalized 32 | */ 33 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b)) 34 | 35 | 36 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 37 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 39 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 40 | LUAI_FUNC void luaS_clearcache (global_State *g); 41 | LUAI_FUNC void luaS_init (lua_State *L); 42 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 43 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); 44 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 45 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 46 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 47 | 48 | #define ENABLE_SHORT_STRING_TABLE 49 | 50 | LUA_API void luaS_initshr(); 51 | LUA_API void luaS_exitshr(); 52 | LUA_API void luaS_expandshr(int n); 53 | LUAI_FUNC TString *luaS_clonestring(lua_State *L, TString *); 54 | LUA_API int luaS_shrinfo(lua_State *L); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /skynet/3rd/lua/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.21 2015/11/03 15:47:30 roberto Exp $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->i_key.nk.next) 16 | 17 | 18 | /* 'const' to avoid wrong writings that can mess up field 'next' */ 19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) 20 | 21 | /* 22 | ** writable version of 'gkey'; allows updates to individual fields, 23 | ** but not to the whole (which has incompatible type) 24 | */ 25 | #define wgkey(n) (&(n)->i_key.nk) 26 | 27 | #define invalidateTMcache(t) ((t)->flags = 0) 28 | 29 | 30 | /* returns the key, given the value of a table entry */ 31 | #define keyfromval(v) \ 32 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) 33 | 34 | 35 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 36 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 37 | TValue *value); 38 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 39 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 40 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 41 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 42 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 43 | LUAI_FUNC Table *luaH_new (lua_State *L); 44 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 45 | unsigned int nhsize); 46 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 47 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 48 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 49 | LUAI_FUNC int luaH_getn (Table *t); 50 | 51 | 52 | #if defined(LUA_DEBUG) 53 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 54 | LUAI_FUNC int luaH_isdummy (Node *n); 55 | #endif 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /skynet/3rd/lua/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" and "ORDER OP" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_LEN, 24 | TM_EQ, /* last tag method with fast access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_MOD, 29 | TM_POW, 30 | TM_DIV, 31 | TM_IDIV, 32 | TM_BAND, 33 | TM_BOR, 34 | TM_BXOR, 35 | TM_SHL, 36 | TM_SHR, 37 | TM_UNM, 38 | TM_BNOT, 39 | TM_LT, 40 | TM_LE, 41 | TM_CONCAT, 42 | TM_CALL, 43 | TM_N /* number of elements in the enum */ 44 | } TMS; 45 | 46 | 47 | 48 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 49 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 50 | 51 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 52 | 53 | #define ttypename(x) luaT_typenames_[(x) + 1] 54 | 55 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; 56 | 57 | 58 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); 59 | 60 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 61 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 62 | TMS event); 63 | LUAI_FUNC void luaT_init (lua_State *L); 64 | 65 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 66 | const TValue *p2, TValue *p3, int hasres); 67 | LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 68 | StkId res, TMS event); 69 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 70 | StkId res, TMS event); 71 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 72 | const TValue *p2, TMS event); 73 | 74 | 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | 15 | LUAMOD_API int (luaopen_base) (lua_State *L); 16 | 17 | #define LUA_COLIBNAME "coroutine" 18 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 19 | 20 | #define LUA_TABLIBNAME "table" 21 | LUAMOD_API int (luaopen_table) (lua_State *L); 22 | 23 | #define LUA_IOLIBNAME "io" 24 | LUAMOD_API int (luaopen_io) (lua_State *L); 25 | 26 | #define LUA_OSLIBNAME "os" 27 | LUAMOD_API int (luaopen_os) (lua_State *L); 28 | 29 | #define LUA_STRLIBNAME "string" 30 | LUAMOD_API int (luaopen_string) (lua_State *L); 31 | 32 | #define LUA_UTF8LIBNAME "utf8" 33 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 34 | 35 | #define LUA_BITLIBNAME "bit32" 36 | LUAMOD_API int (luaopen_bit32) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | #define LUA_CACHELIB 48 | LUAMOD_API int (luaopen_cache) (lua_State *L); 49 | 50 | /* open all previous libraries */ 51 | LUALIB_API void (luaL_openlibs) (lua_State *L); 52 | 53 | 54 | 55 | #if !defined(lua_assert) 56 | #define lua_assert(x) ((void)0) 57 | #endif 58 | 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.45 2015/09/08 15:41:05 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | #define MYINT(s) (s[0]-'0') 22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 23 | #define LUAC_FORMAT 0 /* this is the official format */ 24 | 25 | /* load one chunk; from lundump.c */ 26 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 27 | 28 | /* dump one chunk; from ldump.c */ 29 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 30 | void* data, int strip); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.37 2015/09/08 15:41:05 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /skynet/3rd/lua/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.31 2015/09/08 15:41:05 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /skynet/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2012-2015 codingnow.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /skynet/README.md: -------------------------------------------------------------------------------- 1 | ## Skynet 2 | 3 | Skynet is a lightweight online game framework, and it can be used in many other fields. 4 | 5 | ## Build 6 | 7 | For Linux, install autoconf first for jemalloc: 8 | 9 | ``` 10 | git clone https://github.com/cloudwu/skynet.git 11 | cd skynet 12 | make 'PLATFORM' # PLATFORM can be linux, macosx, freebsd now 13 | ``` 14 | 15 | Or you can: 16 | 17 | ``` 18 | export PLAT=linux 19 | make 20 | ``` 21 | 22 | For FreeBSD , use gmake instead of make. 23 | 24 | ## Test 25 | 26 | Run these in different consoles: 27 | 28 | ``` 29 | ./skynet examples/config # Launch first skynet node (Gate server) and a skynet-master (see config for standalone option) 30 | ./3rd/lua/lua examples/client.lua # Launch a client, and try to input hello. 31 | ``` 32 | 33 | ## About Lua version 34 | 35 | Skynet now uses a modified version of lua 5.3.3 ( https://github.com/ejoy/lua/tree/skynet ) for multiple lua states. 36 | 37 | You can also use official Lua versions, just edit the Makefile by yourself. 38 | 39 | ## How To Use (Sorry, Only in Chinese now) 40 | 41 | * Read Wiki for documents https://github.com/cloudwu/skynet/wiki 42 | * The FAQ in wiki https://github.com/cloudwu/skynet/wiki/FAQ 43 | -------------------------------------------------------------------------------- /skynet/examples/abort.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | require "skynet.manager" -- import skynet.abort 3 | 4 | skynet.abort() 5 | -------------------------------------------------------------------------------- /skynet/examples/agent.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local netpack = require "netpack" 3 | local socket = require "socket" 4 | local sproto = require "sproto" 5 | local sprotoloader = require "sprotoloader" 6 | 7 | local WATCHDOG 8 | local host 9 | local send_request 10 | 11 | local CMD = {} 12 | local REQUEST = {} 13 | local client_fd 14 | 15 | function REQUEST:get() 16 | print("get", self.what) 17 | local r = skynet.call("SIMPLEDB", "lua", "get", self.what) 18 | return { result = r } 19 | end 20 | 21 | function REQUEST:set() 22 | print("set", self.what, self.value) 23 | local r = skynet.call("SIMPLEDB", "lua", "set", self.what, self.value) 24 | end 25 | 26 | function REQUEST:handshake() 27 | return { msg = "Welcome to skynet, I will send heartbeat every 5 sec." } 28 | end 29 | 30 | function REQUEST:quit() 31 | skynet.call(WATCHDOG, "lua", "close", client_fd) 32 | end 33 | 34 | local function request(name, args, response) 35 | local f = assert(REQUEST[name]) 36 | local r = f(args) 37 | if response then 38 | return response(r) 39 | end 40 | end 41 | 42 | local function send_package(pack) 43 | local package = string.pack(">s2", pack) 44 | socket.write(client_fd, package) 45 | end 46 | 47 | skynet.register_protocol { 48 | name = "client", 49 | id = skynet.PTYPE_CLIENT, 50 | unpack = function (msg, sz) 51 | return host:dispatch(msg, sz) 52 | end, 53 | dispatch = function (_, _, type, ...) 54 | if type == "REQUEST" then 55 | local ok, result = pcall(request, ...) 56 | if ok then 57 | if result then 58 | send_package(result) 59 | end 60 | else 61 | skynet.error(result) 62 | end 63 | else 64 | assert(type == "RESPONSE") 65 | error "This example doesn't support request client" 66 | end 67 | end 68 | } 69 | 70 | function CMD.start(conf) 71 | local fd = conf.client 72 | local gate = conf.gate 73 | WATCHDOG = conf.watchdog 74 | -- slot 1,2 set at main.lua 75 | host = sprotoloader.load(1):host "package" 76 | send_request = host:attach(sprotoloader.load(2)) 77 | skynet.fork(function() 78 | while true do 79 | send_package(send_request "heartbeat") 80 | skynet.sleep(500) 81 | end 82 | end) 83 | 84 | client_fd = fd 85 | skynet.call(gate, "lua", "forward", fd) 86 | end 87 | 88 | function CMD.disconnect() 89 | -- todo: do something before exit 90 | skynet.exit() 91 | end 92 | 93 | skynet.start(function() 94 | skynet.dispatch("lua", function(_,_, command, ...) 95 | local f = CMD[command] 96 | skynet.ret(skynet.pack(f(...))) 97 | end) 98 | end) 99 | -------------------------------------------------------------------------------- /skynet/examples/checkdeadloop.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local list = {} 4 | 5 | local function timeout_check(ti) 6 | if not next(list) then 7 | return 8 | end 9 | skynet.sleep(ti) -- sleep 10 sec 10 | for k,v in pairs(list) do 11 | skynet.error("timout",ti,k,v) 12 | end 13 | end 14 | 15 | skynet.start(function() 16 | skynet.error("ping all") 17 | local list_ret = skynet.call(".launcher", "lua", "LIST") 18 | for addr, desc in pairs(list_ret) do 19 | list[addr] = desc 20 | skynet.fork(function() 21 | skynet.call(addr,"debug","INFO") 22 | list[addr] = nil 23 | end) 24 | end 25 | skynet.sleep(0) 26 | timeout_check(100) 27 | timeout_check(400) 28 | timeout_check(500) 29 | skynet.exit() 30 | end) 31 | -------------------------------------------------------------------------------- /skynet/examples/cluster1.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local cluster = require "cluster" 3 | local snax = require "snax" 4 | 5 | skynet.start(function() 6 | local sdb = skynet.newservice("simpledb") 7 | -- register name "sdb" for simpledb, you can use cluster.query() later. 8 | -- See cluster2.lua 9 | cluster.register("sdb", sdb) 10 | 11 | print(skynet.call(sdb, "lua", "SET", "a", "foobar")) 12 | print(skynet.call(sdb, "lua", "SET", "b", "foobar2")) 13 | print(skynet.call(sdb, "lua", "GET", "a")) 14 | print(skynet.call(sdb, "lua", "GET", "b")) 15 | cluster.open "db" 16 | cluster.open "db2" 17 | -- unique snax service 18 | snax.uniqueservice "pingserver" 19 | end) 20 | -------------------------------------------------------------------------------- /skynet/examples/cluster2.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local cluster = require "cluster" 3 | 4 | skynet.start(function() 5 | -- query name "sdb" of cluster db. 6 | local sdb = cluster.query("db", "sdb") 7 | print("db.sbd=",sdb) 8 | local proxy = cluster.proxy("db", sdb) 9 | local largekey = string.rep("X", 128*1024) 10 | local largevalue = string.rep("R", 100 * 1024) 11 | print(skynet.call(proxy, "lua", "SET", largekey, largevalue)) 12 | local v = skynet.call(proxy, "lua", "GET", largekey) 13 | assert(largevalue == v) 14 | 15 | print(cluster.call("db", sdb, "GET", "a")) 16 | print(cluster.call("db2", sdb, "GET", "b")) 17 | 18 | -- test snax service 19 | local pingserver = cluster.snax("db", "pingserver") 20 | print(pingserver.req.ping "hello") 21 | end) 22 | -------------------------------------------------------------------------------- /skynet/examples/clustername.lua: -------------------------------------------------------------------------------- 1 | db = "127.0.0.1:2528" 2 | db2 = "127.0.0.1:2529" 3 | -------------------------------------------------------------------------------- /skynet/examples/config: -------------------------------------------------------------------------------- 1 | root = "./" 2 | thread = 8 3 | logger = nil 4 | logpath = "." 5 | harbor = 1 6 | address = "127.0.0.1:2526" 7 | master = "127.0.0.1:2013" 8 | start = "main" -- main script 9 | bootstrap = "snlua bootstrap" -- The service for bootstrap 10 | standalone = "0.0.0.0:2013" 11 | luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua" 12 | lualoader = root .. "lualib/loader.lua" 13 | lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua" 14 | lua_cpath = root .. "luaclib/?.so" 15 | -- preload = "./examples/preload.lua" -- run preload.lua before every lua service run 16 | snax = root.."examples/?.lua;"..root.."test/?.lua" 17 | -- snax_interface_g = "snax_g" 18 | cpath = root.."cservice/?.so" 19 | -- daemon = "./skynet.pid" 20 | -------------------------------------------------------------------------------- /skynet/examples/config.c1: -------------------------------------------------------------------------------- 1 | thread = 8 2 | logger = nil 3 | harbor = 0 4 | start = "cluster1" 5 | bootstrap = "snlua bootstrap" -- The service for bootstrap 6 | luaservice = "./service/?.lua;./test/?.lua;./examples/?.lua" 7 | lualoader = "lualib/loader.lua" 8 | cpath = "./cservice/?.so" 9 | cluster = "./examples/clustername.lua" 10 | snax = "./test/?.lua" 11 | -------------------------------------------------------------------------------- /skynet/examples/config.c2: -------------------------------------------------------------------------------- 1 | thread = 8 2 | logger = nil 3 | harbor = 0 4 | start = "cluster2" 5 | bootstrap = "snlua bootstrap" -- The service for bootstrap 6 | luaservice = "./service/?.lua;./test/?.lua;./examples/?.lua" 7 | lualoader = "lualib/loader.lua" 8 | cpath = "./cservice/?.so" 9 | cluster = "./examples/clustername.lua" 10 | snax = "./test/?.lua" 11 | -------------------------------------------------------------------------------- /skynet/examples/config.login: -------------------------------------------------------------------------------- 1 | thread = 8 2 | logger = nil 3 | harbor = 0 4 | start = "main" 5 | bootstrap = "snlua bootstrap" -- The service for bootstrap 6 | luaservice = "./service/?.lua;./examples/login/?.lua" 7 | lualoader = "lualib/loader.lua" 8 | cpath = "./cservice/?.so" 9 | -------------------------------------------------------------------------------- /skynet/examples/config.mc: -------------------------------------------------------------------------------- 1 | root = "./" 2 | thread = 8 3 | logger = nil 4 | harbor = 2 5 | address = "127.0.0.1:2527" 6 | master = "127.0.0.1:2013" 7 | start = "testmulticast2" -- main script 8 | bootstrap = "snlua bootstrap" -- The service for bootstrap 9 | --standalone = "0.0.0.0:2013" 10 | luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua" 11 | lualoader = "lualib/loader.lua" 12 | -- preload = "./examples/preload.lua" -- run preload.lua before every lua service run 13 | snax = root.."examples/?.lua;"..root.."test/?.lua" 14 | cpath = root.."cservice/?.so" 15 | -------------------------------------------------------------------------------- /skynet/examples/config.mysql: -------------------------------------------------------------------------------- 1 | root = "./" 2 | thread = 8 3 | logger = nil 4 | harbor = 0 5 | start = "main_mysql" -- main script 6 | bootstrap = "snlua bootstrap" -- The service for bootstrap 7 | luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua" 8 | lualoader = "lualib/loader.lua" 9 | snax = root.."examples/?.lua;"..root.."test/?.lua" 10 | cpath = root.."cservice/?.so" 11 | -- daemon = "./skynet.pid" 12 | -------------------------------------------------------------------------------- /skynet/examples/config.userlog: -------------------------------------------------------------------------------- 1 | root = "./" 2 | thread = 8 3 | logger = "userlog" 4 | logservice = "snlua" 5 | logpath = "." 6 | harbor = 0 7 | start = "main" -- main script 8 | bootstrap = "snlua bootstrap" -- The service for bootstrap 9 | luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua" 10 | lualoader = "lualib/loader.lua" 11 | -- preload = "./examples/preload.lua" -- run preload.lua before every lua service run 12 | snax = root.."examples/?.lua;"..root.."test/?.lua" 13 | -- snax_interface_g = "snax_g" 14 | cpath = root.."cservice/?.so" 15 | -- daemon = "./skynet.pid" 16 | -------------------------------------------------------------------------------- /skynet/examples/config_log: -------------------------------------------------------------------------------- 1 | thread = 8 2 | mqueue = 256 3 | cpath = "./cservice/?.so" 4 | logger = nil 5 | harbor = 2 6 | address = "127.0.0.1:2527" 7 | master = "127.0.0.1:2013" 8 | start = "main_log" 9 | luaservice ="./service/?.lua;./test/?.lua;./examples/?.lua" 10 | snax = "./examples/?.lua;./test/?.lua" 11 | -------------------------------------------------------------------------------- /skynet/examples/globallog.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | require "skynet.manager" -- import skynet.register 3 | 4 | skynet.start(function() 5 | skynet.dispatch("lua", function(session, address, ...) 6 | print("[GLOBALLOG]", skynet.address(address), ...) 7 | end) 8 | skynet.register ".log" 9 | skynet.register "LOG" 10 | end) 11 | -------------------------------------------------------------------------------- /skynet/examples/injectlaunch.lua: -------------------------------------------------------------------------------- 1 | if not _P then 2 | print[[ 3 | This file is examples to show how to inject code into lua service. 4 | It is used to inject into launcher service to change the command.LAUNCH to command.LOGLAUNCH. 5 | telnet the debug_console service (nc 127.0.0.1 8000), and run: 6 | inject 3 examples/injectlaunch.lua -- 3 means launcher service 7 | ]] 8 | return 9 | end 10 | local command = _P.lua.command 11 | 12 | if command.RAWLAUNCH then 13 | command.LAUNCH, command.RAWLAUNCH = command.RAWLAUNCH 14 | print "restore command.LAUNCH" 15 | else 16 | command.RAWLAUNCH = command.LAUNCH 17 | command.LAUNCH = command.LOGLAUNCH 18 | print "replace command.LAUNCH" 19 | end 20 | -------------------------------------------------------------------------------- /skynet/examples/login/gated.lua: -------------------------------------------------------------------------------- 1 | local msgserver = require "snax.msgserver" 2 | local crypt = require "crypt" 3 | local skynet = require "skynet" 4 | 5 | local loginservice = tonumber(...) 6 | 7 | local server = {} 8 | local users = {} 9 | local username_map = {} 10 | local internal_id = 0 11 | 12 | -- login server disallow multi login, so login_handler never be reentry 13 | -- call by login server 14 | function server.login_handler(uid, secret) 15 | if users[uid] then 16 | error(string.format("%s is already login", uid)) 17 | end 18 | 19 | internal_id = internal_id + 1 20 | local id = internal_id -- don't use internal_id directly 21 | local username = msgserver.username(uid, id, servername) 22 | 23 | -- you can use a pool to alloc new agent 24 | local agent = skynet.newservice "msgagent" 25 | local u = { 26 | username = username, 27 | agent = agent, 28 | uid = uid, 29 | subid = id, 30 | } 31 | 32 | -- trash subid (no used) 33 | skynet.call(agent, "lua", "login", uid, id, secret) 34 | 35 | users[uid] = u 36 | username_map[username] = u 37 | 38 | msgserver.login(username, secret) 39 | 40 | -- you should return unique subid 41 | return id 42 | end 43 | 44 | -- call by agent 45 | function server.logout_handler(uid, subid) 46 | local u = users[uid] 47 | if u then 48 | local username = msgserver.username(uid, subid, servername) 49 | assert(u.username == username) 50 | msgserver.logout(u.username) 51 | users[uid] = nil 52 | username_map[u.username] = nil 53 | skynet.call(loginservice, "lua", "logout",uid, subid) 54 | end 55 | end 56 | 57 | -- call by login server 58 | function server.kick_handler(uid, subid) 59 | local u = users[uid] 60 | if u then 61 | local username = msgserver.username(uid, subid, servername) 62 | assert(u.username == username) 63 | -- NOTICE: logout may call skynet.exit, so you should use pcall. 64 | pcall(skynet.call, u.agent, "lua", "logout") 65 | end 66 | end 67 | 68 | -- call by self (when socket disconnect) 69 | function server.disconnect_handler(username) 70 | local u = username_map[username] 71 | if u then 72 | skynet.call(u.agent, "lua", "afk") 73 | end 74 | end 75 | 76 | -- call by self (when recv a request from client) 77 | function server.request_handler(username, msg) 78 | local u = username_map[username] 79 | return skynet.tostring(skynet.rawcall(u.agent, "client", msg)) 80 | end 81 | 82 | -- call by self (when gate open) 83 | function server.register_handler(name) 84 | servername = name 85 | skynet.call(loginservice, "lua", "register_gate", servername, skynet.self()) 86 | end 87 | 88 | msgserver.start(server) 89 | 90 | -------------------------------------------------------------------------------- /skynet/examples/login/logind.lua: -------------------------------------------------------------------------------- 1 | local login = require "snax.loginserver" 2 | local crypt = require "crypt" 3 | local skynet = require "skynet" 4 | 5 | local server = { 6 | host = "127.0.0.1", 7 | port = 8001, 8 | multilogin = false, -- disallow multilogin 9 | name = "login_master", 10 | } 11 | 12 | local server_list = {} 13 | local user_online = {} 14 | local user_login = {} 15 | 16 | function server.auth_handler(token) 17 | -- the token is base64(user)@base64(server):base64(password) 18 | local user, server, password = token:match("([^@]+)@([^:]+):(.+)") 19 | user = crypt.base64decode(user) 20 | server = crypt.base64decode(server) 21 | password = crypt.base64decode(password) 22 | assert(password == "password", "Invalid password") 23 | return server, user 24 | end 25 | 26 | function server.login_handler(server, uid, secret) 27 | print(string.format("%s@%s is login, secret is %s", uid, server, crypt.hexencode(secret))) 28 | local gameserver = assert(server_list[server], "Unknown server") 29 | -- only one can login, because disallow multilogin 30 | local last = user_online[uid] 31 | if last then 32 | skynet.call(last.address, "lua", "kick", uid, last.subid) 33 | end 34 | if user_online[uid] then 35 | error(string.format("user %s is already online", uid)) 36 | end 37 | 38 | local subid = tostring(skynet.call(gameserver, "lua", "login", uid, secret)) 39 | user_online[uid] = { address = gameserver, subid = subid , server = server} 40 | return subid 41 | end 42 | 43 | local CMD = {} 44 | 45 | function CMD.register_gate(server, address) 46 | server_list[server] = address 47 | end 48 | 49 | function CMD.logout(uid, subid) 50 | local u = user_online[uid] 51 | if u then 52 | print(string.format("%s@%s is logout", uid, u.server)) 53 | user_online[uid] = nil 54 | end 55 | end 56 | 57 | function server.command_handler(command, ...) 58 | local f = assert(CMD[command]) 59 | return f(...) 60 | end 61 | 62 | login(server) 63 | -------------------------------------------------------------------------------- /skynet/examples/login/main.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | skynet.start(function() 4 | local loginserver = skynet.newservice("logind") 5 | local gate = skynet.newservice("gated", loginserver) 6 | 7 | skynet.call(gate, "lua", "open" , { 8 | port = 8888, 9 | maxclient = 64, 10 | servername = "sample", 11 | }) 12 | end) 13 | -------------------------------------------------------------------------------- /skynet/examples/login/msgagent.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | skynet.register_protocol { 4 | name = "client", 5 | id = skynet.PTYPE_CLIENT, 6 | unpack = skynet.tostring, 7 | } 8 | 9 | local gate 10 | local userid, subid 11 | 12 | local CMD = {} 13 | 14 | function CMD.login(source, uid, sid, secret) 15 | -- you may use secret to make a encrypted data stream 16 | skynet.error(string.format("%s is login", uid)) 17 | gate = source 18 | userid = uid 19 | subid = sid 20 | -- you may load user data from database 21 | end 22 | 23 | local function logout() 24 | if gate then 25 | skynet.call(gate, "lua", "logout", userid, subid) 26 | end 27 | skynet.exit() 28 | end 29 | 30 | function CMD.logout(source) 31 | -- NOTICE: The logout MAY be reentry 32 | skynet.error(string.format("%s is logout", userid)) 33 | logout() 34 | end 35 | 36 | function CMD.afk(source) 37 | -- the connection is broken, but the user may back 38 | skynet.error(string.format("AFK")) 39 | end 40 | 41 | skynet.start(function() 42 | -- If you want to fork a work thread , you MUST do it in CMD.login 43 | skynet.dispatch("lua", function(session, source, command, ...) 44 | local f = assert(CMD[command]) 45 | skynet.ret(skynet.pack(f(source, ...))) 46 | end) 47 | 48 | skynet.dispatch("client", function(_,_, msg) 49 | -- the simple echo service 50 | skynet.sleep(10) -- sleep a while 51 | skynet.ret(msg) 52 | end) 53 | end) 54 | -------------------------------------------------------------------------------- /skynet/examples/main.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local sprotoloader = require "sprotoloader" 3 | 4 | local max_client = 64 5 | 6 | skynet.start(function() 7 | skynet.error("Server start") 8 | skynet.uniqueservice("protoloader") 9 | if not skynet.getenv "daemon" then 10 | local console = skynet.newservice("console") 11 | end 12 | skynet.newservice("debug_console",8000) 13 | skynet.newservice("simpledb") 14 | local watchdog = skynet.newservice("watchdog") 15 | skynet.call(watchdog, "lua", "start", { 16 | port = 8888, 17 | maxclient = max_client, 18 | nodelay = true, 19 | }) 20 | skynet.error("Watchdog listen on", 8888) 21 | skynet.exit() 22 | end) 23 | -------------------------------------------------------------------------------- /skynet/examples/main_log.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local harbor = require "skynet.harbor" 3 | require "skynet.manager" -- import skynet.monitor 4 | 5 | local function monitor_master() 6 | harbor.linkmaster() 7 | print("master is down") 8 | skynet.exit() 9 | end 10 | 11 | skynet.start(function() 12 | print("Log server start") 13 | skynet.monitor "simplemonitor" 14 | local log = skynet.newservice("globallog") 15 | skynet.fork(monitor_master) 16 | end) 17 | 18 | -------------------------------------------------------------------------------- /skynet/examples/main_mysql.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | 4 | skynet.start(function() 5 | print("Main Server start") 6 | local console = skynet.newservice("testmysql") 7 | 8 | print("Main Server exit") 9 | skynet.exit() 10 | end) 11 | -------------------------------------------------------------------------------- /skynet/examples/preload.lua: -------------------------------------------------------------------------------- 1 | -- This file will execute before every lua service start 2 | -- See config 3 | 4 | print("PRELOAD", ...) 5 | 6 | -------------------------------------------------------------------------------- /skynet/examples/proto.lua: -------------------------------------------------------------------------------- 1 | local sprotoparser = require "sprotoparser" 2 | 3 | local proto = {} 4 | 5 | proto.c2s = sprotoparser.parse [[ 6 | .package { 7 | type 0 : integer 8 | session 1 : integer 9 | } 10 | 11 | handshake 1 { 12 | response { 13 | msg 0 : string 14 | } 15 | } 16 | 17 | get 2 { 18 | request { 19 | what 0 : string 20 | } 21 | response { 22 | result 0 : string 23 | } 24 | } 25 | 26 | set 3 { 27 | request { 28 | what 0 : string 29 | value 1 : string 30 | } 31 | } 32 | 33 | quit 4 {} 34 | 35 | ]] 36 | 37 | proto.s2c = sprotoparser.parse [[ 38 | .package { 39 | type 0 : integer 40 | session 1 : integer 41 | } 42 | 43 | heartbeat 1 {} 44 | ]] 45 | 46 | return proto 47 | -------------------------------------------------------------------------------- /skynet/examples/protoloader.lua: -------------------------------------------------------------------------------- 1 | -- module proto as examples/proto.lua 2 | package.path = "./examples/?.lua;" .. package.path 3 | 4 | local skynet = require "skynet" 5 | local sprotoparser = require "sprotoparser" 6 | local sprotoloader = require "sprotoloader" 7 | local proto = require "proto" 8 | 9 | skynet.start(function() 10 | sprotoloader.save(proto.c2s, 1) 11 | sprotoloader.save(proto.s2c, 2) 12 | -- don't call skynet.exit() , because sproto.core may unload and the global slot become invalid 13 | end) 14 | -------------------------------------------------------------------------------- /skynet/examples/share.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local sharedata = require "sharedata" 3 | 4 | local mode = ... 5 | 6 | if mode == "host" then 7 | 8 | skynet.start(function() 9 | skynet.error("new foobar") 10 | sharedata.new("foobar", { a=1, b= { "hello", "world" } }) 11 | 12 | skynet.fork(function() 13 | skynet.sleep(200) -- sleep 2s 14 | skynet.error("update foobar a = 2") 15 | sharedata.update("foobar", { a =2 }) 16 | skynet.sleep(200) -- sleep 2s 17 | skynet.error("update foobar a = 3") 18 | sharedata.update("foobar", { a = 3, b = { "change" } }) 19 | skynet.sleep(100) 20 | skynet.error("delete foobar") 21 | sharedata.delete "foobar" 22 | end) 23 | end) 24 | 25 | else 26 | 27 | 28 | skynet.start(function() 29 | skynet.newservice(SERVICE_NAME, "host") 30 | 31 | local obj = sharedata.query "foobar" 32 | 33 | local b = obj.b 34 | skynet.error(string.format("a=%d", obj.a)) 35 | 36 | for k,v in ipairs(b) do 37 | skynet.error(string.format("b[%d]=%s", k,v)) 38 | end 39 | 40 | -- test lua serialization 41 | local s = skynet.packstring(obj) 42 | local nobj = skynet.unpack(s) 43 | for k,v in pairs(nobj) do 44 | skynet.error(string.format("nobj[%s]=%s", k,v)) 45 | end 46 | for k,v in ipairs(nobj.b) do 47 | skynet.error(string.format("nobj.b[%d]=%s", k,v)) 48 | end 49 | 50 | for i = 1, 5 do 51 | skynet.sleep(100) 52 | skynet.error("second " ..i) 53 | for k,v in pairs(obj) do 54 | skynet.error(string.format("%s = %s", k , tostring(v))) 55 | end 56 | end 57 | 58 | local ok, err = pcall(function() 59 | local tmp = { b[1], b[2] } -- b is invalid , so pcall should failed 60 | end) 61 | 62 | if not ok then 63 | skynet.error(err) 64 | end 65 | 66 | -- obj. b is not the same with local b 67 | for k,v in ipairs(obj.b) do 68 | skynet.error(string.format("b[%d] = %s", k , tostring(v))) 69 | end 70 | 71 | collectgarbage() 72 | skynet.error("sleep") 73 | skynet.sleep(100) 74 | b = nil 75 | collectgarbage() 76 | skynet.error("sleep") 77 | skynet.sleep(100) 78 | 79 | skynet.exit() 80 | end) 81 | 82 | end 83 | -------------------------------------------------------------------------------- /skynet/examples/simpledb.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | require "skynet.manager" -- import skynet.register 3 | local db = {} 4 | 5 | local command = {} 6 | 7 | function command.GET(key) 8 | return db[key] 9 | end 10 | 11 | function command.SET(key, value) 12 | local last = db[key] 13 | db[key] = value 14 | return last 15 | end 16 | 17 | skynet.start(function() 18 | skynet.dispatch("lua", function(session, address, cmd, ...) 19 | local f = command[string.upper(cmd)] 20 | if f then 21 | skynet.ret(skynet.pack(f(...))) 22 | else 23 | error(string.format("Unknown command %s", tostring(cmd))) 24 | end 25 | end) 26 | skynet.register "SIMPLEDB" 27 | end) 28 | -------------------------------------------------------------------------------- /skynet/examples/simplemonitor.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | -- It's a simple service exit monitor, you can do something more when a service exit. 4 | 5 | local service_map = {} 6 | 7 | skynet.register_protocol { 8 | name = "client", 9 | id = skynet.PTYPE_CLIENT, -- PTYPE_CLIENT = 3 10 | unpack = function() end, 11 | dispatch = function(_, address) 12 | local w = service_map[address] 13 | if w then 14 | for watcher in pairs(w) do 15 | skynet.redirect(watcher, address, "error", 0, "") 16 | end 17 | service_map[address] = false 18 | end 19 | end 20 | } 21 | 22 | local function monitor(session, watcher, command, service) 23 | assert(command, "WATCH") 24 | local w = service_map[service] 25 | if not w then 26 | if w == false then 27 | skynet.ret(skynet.pack(false)) 28 | return 29 | end 30 | w = {} 31 | service_map[service] = w 32 | end 33 | w[watcher] = true 34 | skynet.ret(skynet.pack(true)) 35 | end 36 | 37 | skynet.start(function() 38 | skynet.dispatch("lua", monitor) 39 | end) 40 | -------------------------------------------------------------------------------- /skynet/examples/simpleweb.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local socket = require "socket" 3 | local httpd = require "http.httpd" 4 | local sockethelper = require "http.sockethelper" 5 | local urllib = require "http.url" 6 | local table = table 7 | local string = string 8 | 9 | local mode = ... 10 | 11 | if mode == "agent" then 12 | 13 | local function response(id, ...) 14 | local ok, err = httpd.write_response(sockethelper.writefunc(id), ...) 15 | if not ok then 16 | -- if err == sockethelper.socket_error , that means socket closed. 17 | skynet.error(string.format("fd = %d, %s", id, err)) 18 | end 19 | end 20 | 21 | skynet.start(function() 22 | skynet.dispatch("lua", function (_,_,id) 23 | socket.start(id) 24 | -- limit request body size to 8192 (you can pass nil to unlimit) 25 | local code, url, method, header, body = httpd.read_request(sockethelper.readfunc(id), 8192) 26 | if code then 27 | if code ~= 200 then 28 | response(id, code) 29 | else 30 | local tmp = {} 31 | if header.host then 32 | table.insert(tmp, string.format("host: %s", header.host)) 33 | end 34 | local path, query = urllib.parse(url) 35 | table.insert(tmp, string.format("path: %s", path)) 36 | if query then 37 | local q = urllib.parse_query(query) 38 | for k, v in pairs(q) do 39 | table.insert(tmp, string.format("query: %s= %s", k,v)) 40 | end 41 | end 42 | table.insert(tmp, "-----header----") 43 | for k,v in pairs(header) do 44 | table.insert(tmp, string.format("%s = %s",k,v)) 45 | end 46 | table.insert(tmp, "-----body----\n" .. body) 47 | response(id, code, table.concat(tmp,"\n")) 48 | end 49 | else 50 | if url == sockethelper.socket_error then 51 | skynet.error("socket closed") 52 | else 53 | skynet.error(url) 54 | end 55 | end 56 | socket.close(id) 57 | end) 58 | end) 59 | 60 | else 61 | 62 | skynet.start(function() 63 | local agent = {} 64 | for i= 1, 20 do 65 | agent[i] = skynet.newservice(SERVICE_NAME, "agent") 66 | end 67 | local balance = 1 68 | local id = socket.listen("0.0.0.0", 8001) 69 | skynet.error("Listen web port 8001") 70 | socket.start(id , function(id, addr) 71 | skynet.error(string.format("%s connected, pass it to agent :%08x", addr, agent[balance])) 72 | skynet.send(agent[balance], "lua", id) 73 | balance = balance + 1 74 | if balance > #agent then 75 | balance = 1 76 | end 77 | end) 78 | end) 79 | 80 | end -------------------------------------------------------------------------------- /skynet/examples/userlog.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | require "skynet.manager" 3 | 4 | skynet.register_protocol { 5 | name = "text", 6 | id = skynet.PTYPE_TEXT, 7 | unpack = skynet.tostring, 8 | dispatch = function(_, address, msg) 9 | print(string.format(":%08x(%.2f): %s", address, skynet.time(), msg)) 10 | end 11 | } 12 | 13 | skynet.register_protocol { 14 | name = "SYSTEM", 15 | id = skynet.PTYPE_SYSTEM, 16 | unpack = function(...) return ... end, 17 | dispatch = function() 18 | -- reopen signal 19 | print("SIGHUP") 20 | end 21 | } 22 | 23 | skynet.start(function() 24 | skynet.register ".logger" 25 | end) -------------------------------------------------------------------------------- /skynet/examples/watchdog.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local netpack = require "netpack" 3 | 4 | local CMD = {} 5 | local SOCKET = {} 6 | local gate 7 | local agent = {} 8 | 9 | function SOCKET.open(fd, addr) 10 | skynet.error("New client from : " .. addr) 11 | agent[fd] = skynet.newservice("agent") 12 | skynet.call(agent[fd], "lua", "start", { gate = gate, client = fd, watchdog = skynet.self() }) 13 | end 14 | 15 | local function close_agent(fd) 16 | local a = agent[fd] 17 | agent[fd] = nil 18 | if a then 19 | skynet.call(gate, "lua", "kick", fd) 20 | -- disconnect never return 21 | skynet.send(a, "lua", "disconnect") 22 | end 23 | end 24 | 25 | function SOCKET.close(fd) 26 | print("socket close",fd) 27 | close_agent(fd) 28 | end 29 | 30 | function SOCKET.error(fd, msg) 31 | print("socket error",fd, msg) 32 | close_agent(fd) 33 | end 34 | 35 | function SOCKET.warning(fd, size) 36 | -- size K bytes havn't send out in fd 37 | print("socket warning", fd, size) 38 | end 39 | 40 | function SOCKET.data(fd, msg) 41 | end 42 | 43 | function CMD.start(conf) 44 | skynet.call(gate, "lua", "open" , conf) 45 | end 46 | 47 | function CMD.close(fd) 48 | close_agent(fd) 49 | end 50 | 51 | skynet.start(function() 52 | skynet.dispatch("lua", function(session, source, cmd, subcmd, ...) 53 | if cmd == "socket" then 54 | local f = SOCKET[subcmd] 55 | f(...) 56 | -- socket api don't need return 57 | else 58 | local f = assert(CMD[cmd]) 59 | skynet.ret(skynet.pack(f(subcmd, ...))) 60 | end 61 | end) 62 | 63 | gate = skynet.newservice("gate") 64 | end) 65 | -------------------------------------------------------------------------------- /skynet/lualib-src/lua-memory.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "malloc_hook.h" 5 | #include "luashrtbl.h" 6 | 7 | static int 8 | ltotal(lua_State *L) { 9 | size_t t = malloc_used_memory(); 10 | lua_pushinteger(L, (lua_Integer)t); 11 | 12 | return 1; 13 | } 14 | 15 | static int 16 | lblock(lua_State *L) { 17 | size_t t = malloc_memory_block(); 18 | lua_pushinteger(L, (lua_Integer)t); 19 | 20 | return 1; 21 | } 22 | 23 | static int 24 | ldumpinfo(lua_State *L) { 25 | memory_info_dump(); 26 | 27 | return 0; 28 | } 29 | 30 | static int 31 | ldump(lua_State *L) { 32 | dump_c_mem(); 33 | 34 | return 0; 35 | } 36 | 37 | static int 38 | lexpandshrtbl(lua_State *L) { 39 | int n = luaL_checkinteger(L, 1); 40 | luaS_expandshr(n); 41 | return 0; 42 | } 43 | 44 | static int 45 | lcurrent(lua_State *L) { 46 | lua_pushinteger(L, malloc_current_memory()); 47 | return 1; 48 | } 49 | 50 | int 51 | luaopen_memory(lua_State *L) { 52 | luaL_checkversion(L); 53 | 54 | luaL_Reg l[] = { 55 | { "total", ltotal }, 56 | { "block", lblock }, 57 | { "dumpinfo", ldumpinfo }, 58 | { "dump", ldump }, 59 | { "info", dump_mem_lua }, 60 | { "ssinfo", luaS_shrinfo }, 61 | { "ssexpand", lexpandshrtbl }, 62 | { "current", lcurrent }, 63 | { NULL, NULL }, 64 | }; 65 | 66 | luaL_newlib(L,l); 67 | 68 | return 1; 69 | } 70 | -------------------------------------------------------------------------------- /skynet/lualib-src/lua-seri.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_SERIALIZE_H 2 | #define LUA_SERIALIZE_H 3 | 4 | #include 5 | 6 | int luaseri_pack(lua_State *L); 7 | int luaseri_unpack(lua_State *L); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /skynet/lualib-src/sproto/README: -------------------------------------------------------------------------------- 1 | Check https://github.com/cloudwu/sproto for more 2 | -------------------------------------------------------------------------------- /skynet/lualib-src/sproto/msvcint.h: -------------------------------------------------------------------------------- 1 | #ifndef msvc_int_h 2 | #define msvc_int_h 3 | 4 | #ifdef _MSC_VER 5 | # define inline __inline 6 | # ifndef _MSC_STDINT_H_ 7 | # if (_MSC_VER < 1300) 8 | typedef signed char int8_t; 9 | typedef signed short int16_t; 10 | typedef signed int int32_t; 11 | typedef unsigned char uint8_t; 12 | typedef unsigned short uint16_t; 13 | typedef unsigned int uint32_t; 14 | # else 15 | typedef signed __int8 int8_t; 16 | typedef signed __int16 int16_t; 17 | typedef signed __int32 int32_t; 18 | typedef unsigned __int8 uint8_t; 19 | typedef unsigned __int16 uint16_t; 20 | typedef unsigned __int32 uint32_t; 21 | # endif 22 | typedef signed __int64 int64_t; 23 | typedef unsigned __int64 uint64_t; 24 | # endif 25 | 26 | #else 27 | 28 | #include 29 | 30 | #endif 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /skynet/lualib-src/sproto/sproto.h: -------------------------------------------------------------------------------- 1 | #ifndef sproto_h 2 | #define sproto_h 3 | 4 | #include 5 | 6 | struct sproto; 7 | struct sproto_type; 8 | 9 | #define SPROTO_REQUEST 0 10 | #define SPROTO_RESPONSE 1 11 | 12 | #define SPROTO_TINTEGER 0 13 | #define SPROTO_TBOOLEAN 1 14 | #define SPROTO_TSTRING 2 15 | #define SPROTO_TSTRUCT 3 16 | 17 | #define SPROTO_CB_ERROR -1 18 | #define SPROTO_CB_NIL -2 19 | #define SPROTO_CB_NOARRAY -3 20 | 21 | struct sproto * sproto_create(const void * proto, size_t sz); 22 | void sproto_release(struct sproto *); 23 | 24 | int sproto_prototag(const struct sproto *, const char * name); 25 | const char * sproto_protoname(const struct sproto *, int proto); 26 | // SPROTO_REQUEST(0) : request, SPROTO_RESPONSE(1): response 27 | struct sproto_type * sproto_protoquery(const struct sproto *, int proto, int what); 28 | 29 | struct sproto_type * sproto_type(const struct sproto *, const char * type_name); 30 | 31 | int sproto_pack(const void * src, int srcsz, void * buffer, int bufsz); 32 | int sproto_unpack(const void * src, int srcsz, void * buffer, int bufsz); 33 | 34 | struct sproto_arg { 35 | void *ud; 36 | const char *tagname; 37 | int tagid; 38 | int type; 39 | struct sproto_type *subtype; 40 | void *value; 41 | int length; 42 | int index; // array base 1 43 | int mainindex; // for map 44 | }; 45 | 46 | typedef int (*sproto_callback)(const struct sproto_arg *args); 47 | 48 | int sproto_decode(const struct sproto_type *, const void * data, int size, sproto_callback cb, void *ud); 49 | int sproto_encode(const struct sproto_type *, void * buffer, int size, sproto_callback cb, void *ud); 50 | 51 | // for debug use 52 | void sproto_dump(struct sproto *); 53 | const char * sproto_name(struct sproto_type *); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /skynet/lualib/cluster.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local clusterd 4 | local cluster = {} 5 | 6 | function cluster.call(node, address, ...) 7 | -- skynet.pack(...) will free by cluster.core.packrequest 8 | return skynet.call(clusterd, "lua", "req", node, address, skynet.pack(...)) 9 | end 10 | 11 | function cluster.open(port) 12 | if type(port) == "string" then 13 | skynet.call(clusterd, "lua", "listen", port) 14 | else 15 | skynet.call(clusterd, "lua", "listen", "0.0.0.0", port) 16 | end 17 | end 18 | 19 | function cluster.reload() 20 | skynet.call(clusterd, "lua", "reload") 21 | end 22 | 23 | function cluster.proxy(node, name) 24 | return skynet.call(clusterd, "lua", "proxy", node, name) 25 | end 26 | 27 | function cluster.snax(node, name, address) 28 | local snax = require "snax" 29 | if not address then 30 | address = cluster.call(node, ".service", "QUERY", "snaxd" , name) 31 | end 32 | local handle = skynet.call(clusterd, "lua", "proxy", node, address) 33 | return snax.bind(handle, name) 34 | end 35 | 36 | function cluster.register(name, addr) 37 | assert(type(name) == "string") 38 | assert(addr == nil or type(addr) == "number") 39 | return skynet.call(clusterd, "lua", "register", name, addr) 40 | end 41 | 42 | function cluster.query(node, name) 43 | return skynet.call(clusterd, "lua", "req", node, 0, skynet.pack(name)) 44 | end 45 | 46 | skynet.init(function() 47 | clusterd = skynet.uniqueservice("clusterd") 48 | end) 49 | 50 | return cluster 51 | -------------------------------------------------------------------------------- /skynet/lualib/datacenter.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local datacenter = {} 4 | 5 | function datacenter.get(...) 6 | return skynet.call("DATACENTER", "lua", "QUERY", ...) 7 | end 8 | 9 | function datacenter.set(...) 10 | return skynet.call("DATACENTER", "lua", "UPDATE", ...) 11 | end 12 | 13 | function datacenter.wait(...) 14 | return skynet.call("DATACENTER", "lua", "WAIT", ...) 15 | end 16 | 17 | return datacenter 18 | 19 | -------------------------------------------------------------------------------- /skynet/lualib/http/sockethelper.lua: -------------------------------------------------------------------------------- 1 | local socket = require "socket" 2 | 3 | local readbytes = socket.read 4 | local writebytes = socket.write 5 | 6 | local sockethelper = {} 7 | local socket_error = setmetatable({} , { __tostring = function() return "[Socket Error]" end }) 8 | 9 | sockethelper.socket_error = socket_error 10 | 11 | local function preread(fd, str) 12 | return function (sz) 13 | if str then 14 | if sz == #str or sz == nil then 15 | local ret = str 16 | str = nil 17 | return ret 18 | else 19 | if sz < #str then 20 | local ret = str:sub(1,sz) 21 | str = str:sub(sz + 1) 22 | return ret 23 | else 24 | sz = sz - #str 25 | local ret = readbytes(fd, sz) 26 | if ret then 27 | return str .. ret 28 | else 29 | error(socket_error) 30 | end 31 | end 32 | end 33 | else 34 | local ret = readbytes(fd, sz) 35 | if ret then 36 | return ret 37 | else 38 | error(socket_error) 39 | end 40 | end 41 | end 42 | end 43 | 44 | function sockethelper.readfunc(fd, pre) 45 | if pre then 46 | return preread(fd, pre) 47 | end 48 | return function (sz) 49 | local ret = readbytes(fd, sz) 50 | if ret then 51 | return ret 52 | else 53 | error(socket_error) 54 | end 55 | end 56 | end 57 | 58 | sockethelper.readall = socket.readall 59 | 60 | function sockethelper.writefunc(fd) 61 | return function(content) 62 | local ok = writebytes(fd, content) 63 | if not ok then 64 | error(socket_error) 65 | end 66 | end 67 | end 68 | 69 | function sockethelper.connect(host, port) 70 | local fd = socket.open(host, port) 71 | if fd then 72 | return fd 73 | end 74 | error(socket_error) 75 | end 76 | 77 | function sockethelper.close(fd) 78 | socket.close(fd) 79 | end 80 | 81 | return sockethelper 82 | -------------------------------------------------------------------------------- /skynet/lualib/http/url.lua: -------------------------------------------------------------------------------- 1 | local url = {} 2 | 3 | local function decode_func(c) 4 | return string.char(tonumber(c, 16)) 5 | end 6 | 7 | local function decode(str) 8 | local str = str:gsub('+', ' ') 9 | return str:gsub("%%(..)", decode_func) 10 | end 11 | 12 | function url.parse(u) 13 | local path,query = u:match "([^?]*)%??(.*)" 14 | if path then 15 | path = decode(path) 16 | end 17 | return path, query 18 | end 19 | 20 | function url.parse_query(q) 21 | local r = {} 22 | for k,v in q:gmatch "(.-)=([^&]*)&?" do 23 | r[decode(k)] = decode(v) 24 | end 25 | return r 26 | end 27 | 28 | return url 29 | -------------------------------------------------------------------------------- /skynet/lualib/loader.lua: -------------------------------------------------------------------------------- 1 | local args = {} 2 | for word in string.gmatch(..., "%S+") do 3 | table.insert(args, word) 4 | end 5 | 6 | SERVICE_NAME = args[1] 7 | 8 | local main, pattern 9 | 10 | local err = {} 11 | for pat in string.gmatch(LUA_SERVICE, "([^;]+);*") do 12 | local filename = string.gsub(pat, "?", SERVICE_NAME) 13 | local f, msg = loadfile(filename) 14 | if not f then 15 | table.insert(err, msg) 16 | else 17 | pattern = pat 18 | main = f 19 | break 20 | end 21 | end 22 | 23 | if not main then 24 | error(table.concat(err, "\n")) 25 | end 26 | 27 | LUA_SERVICE = nil 28 | package.path , LUA_PATH = LUA_PATH 29 | package.cpath , LUA_CPATH = LUA_CPATH 30 | 31 | local service_path = string.match(pattern, "(.*/)[^/?]+$") 32 | 33 | if service_path then 34 | service_path = string.gsub(service_path, "?", args[1]) 35 | package.path = service_path .. "?.lua;" .. package.path 36 | SERVICE_PATH = service_path 37 | else 38 | local p = string.match(pattern, "(.*/).+$") 39 | SERVICE_PATH = p 40 | end 41 | 42 | if LUA_PRELOAD then 43 | local f = assert(loadfile(LUA_PRELOAD)) 44 | f(table.unpack(args)) 45 | LUA_PRELOAD = nil 46 | end 47 | 48 | main(select(2, table.unpack(args))) 49 | -------------------------------------------------------------------------------- /skynet/lualib/md5.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- Modify version from https://github.com/keplerproject/md5 3 | ---------------------------------------------------------------------------- 4 | 5 | local core = require "md5.core" 6 | 7 | ---------------------------------------------------------------------------- 8 | -- @param k String with original message. 9 | -- @return String with the md5 hash value converted to hexadecimal digits 10 | 11 | function core.sumhexa (k) 12 | k = core.sum(k) 13 | return (string.gsub(k, ".", function (c) 14 | return string.format("%02x", string.byte(c)) 15 | end)) 16 | end 17 | 18 | local function get_ipad(c) 19 | return string.char(c:byte() ~ 0x36) 20 | end 21 | 22 | local function get_opad(c) 23 | return string.char(c:byte() ~ 0x5c) 24 | end 25 | 26 | function core.hmacmd5(data,key) 27 | if #key>64 then 28 | key=core.sum(key) 29 | key=key:sub(1,16) 30 | end 31 | local ipad_s=key:gsub(".", get_ipad)..string.rep("6",64-#key) 32 | local opad_s=key:gsub(".", get_opad)..string.rep("\\",64-#key) 33 | local istr=core.sum(ipad_s..data) 34 | local ostr=core.sumhexa(opad_s..istr) 35 | return ostr 36 | end 37 | 38 | return core 39 | -------------------------------------------------------------------------------- /skynet/lualib/mqueue.lua: -------------------------------------------------------------------------------- 1 | -- This is a deprecated module, use skynet.queue instead. 2 | 3 | local skynet = require "skynet" 4 | local c = require "skynet.core" 5 | 6 | local mqueue = {} 7 | local init_once 8 | local thread_id 9 | local message_queue = {} 10 | 11 | skynet.register_protocol { 12 | name = "queue", 13 | -- please read skynet.h for magic number 8 14 | id = 8, 15 | pack = skynet.pack, 16 | unpack = skynet.unpack, 17 | dispatch = function(session, from, ...) 18 | table.insert(message_queue, {session = session, addr = from, ... }) 19 | if thread_id then 20 | skynet.wakeup(thread_id) 21 | thread_id = nil 22 | end 23 | end 24 | } 25 | 26 | local function do_func(f, msg) 27 | return pcall(f, table.unpack(msg)) 28 | end 29 | 30 | local function message_dispatch(f) 31 | while true do 32 | if #message_queue==0 then 33 | thread_id = coroutine.running() 34 | skynet.wait() 35 | else 36 | local msg = table.remove(message_queue,1) 37 | local session = msg.session 38 | if session == 0 then 39 | local ok, msg = do_func(f, msg) 40 | if ok then 41 | if msg then 42 | skynet.fork(message_dispatch,f) 43 | error(string.format("[:%x] send a message to [:%x] return something", msg.addr, skynet.self())) 44 | end 45 | else 46 | skynet.fork(message_dispatch,f) 47 | error(string.format("[:%x] send a message to [:%x] throw an error : %s", msg.addr, skynet.self(),msg)) 48 | end 49 | else 50 | local data, size = skynet.pack(do_func(f,msg)) 51 | -- 1 means response 52 | c.send(msg.addr, 1, session, data, size) 53 | end 54 | end 55 | end 56 | end 57 | 58 | function mqueue.register(f) 59 | assert(init_once == nil) 60 | init_once = true 61 | skynet.fork(message_dispatch,f) 62 | end 63 | 64 | local function catch(succ, ...) 65 | if succ then 66 | return ... 67 | else 68 | error(...) 69 | end 70 | end 71 | 72 | function mqueue.call(addr, ...) 73 | return catch(skynet.call(addr, "queue", ...)) 74 | end 75 | 76 | function mqueue.send(addr, ...) 77 | return skynet.send(addr, "queue", ...) 78 | end 79 | 80 | function mqueue.size() 81 | return #message_queue 82 | end 83 | 84 | return mqueue 85 | -------------------------------------------------------------------------------- /skynet/lualib/sharedata.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local sd = require "sharedata.corelib" 3 | 4 | local service 5 | 6 | skynet.init(function() 7 | service = skynet.uniqueservice "sharedatad" 8 | end) 9 | 10 | local sharedata = {} 11 | 12 | local function monitor(name, obj, cobj) 13 | local newobj = cobj 14 | while true do 15 | newobj = skynet.call(service, "lua", "monitor", name, newobj) 16 | if newobj == nil then 17 | break 18 | end 19 | sd.update(obj, newobj) 20 | end 21 | end 22 | 23 | function sharedata.query(name) 24 | local obj = skynet.call(service, "lua", "query", name) 25 | local r = sd.box(obj) 26 | skynet.send(service, "lua", "confirm" , obj) 27 | skynet.fork(monitor,name, r, obj) 28 | return r 29 | end 30 | 31 | function sharedata.new(name, v, ...) 32 | skynet.call(service, "lua", "new", name, v, ...) 33 | end 34 | 35 | function sharedata.update(name, v, ...) 36 | skynet.call(service, "lua", "update", name, v, ...) 37 | end 38 | 39 | function sharedata.delete(name) 40 | skynet.call(service, "lua", "delete", name) 41 | end 42 | 43 | return sharedata 44 | -------------------------------------------------------------------------------- /skynet/lualib/sharemap.lua: -------------------------------------------------------------------------------- 1 | local stm = require "stm" 2 | local sprotoloader = require "sprotoloader" 3 | local sproto = require "sproto" 4 | local setmetatable = setmetatable 5 | 6 | local sharemap = {} 7 | 8 | function sharemap.register(protofile) 9 | -- use global slot 0 for type define 10 | sprotoloader.register(protofile, 0) 11 | end 12 | 13 | local sprotoobj 14 | local function loadsp() 15 | if sprotoobj == nil then 16 | sprotoobj = sprotoloader.load(0) 17 | end 18 | return sprotoobj 19 | end 20 | 21 | function sharemap:commit() 22 | self.__obj(sprotoobj:encode(self.__typename, self.__data)) 23 | end 24 | 25 | function sharemap:copy() 26 | return stm.copy(self.__obj) 27 | end 28 | 29 | function sharemap.writer(typename, obj) 30 | local sp = loadsp() 31 | obj = obj or {} 32 | local stmobj = stm.new(sp:encode(typename,obj)) 33 | local ret = { 34 | __typename = typename, 35 | __obj = stmobj, 36 | __data = obj, 37 | commit = sharemap.commit, 38 | copy = sharemap.copy, 39 | } 40 | return setmetatable(ret, { __index = obj, __newindex = obj }) 41 | end 42 | 43 | local function decode(msg, sz, self) 44 | local data = self.__data 45 | for k in pairs(data) do 46 | data[k] = nil 47 | end 48 | return sprotoobj:decode(self.__typename, msg, sz, data) 49 | end 50 | 51 | function sharemap:update() 52 | return self.__obj(decode, self) 53 | end 54 | 55 | function sharemap.reader(typename, stmcpy) 56 | local sp = loadsp() 57 | local stmobj = stm.newcopy(stmcpy) 58 | local _, data = stmobj(function(msg, sz) 59 | return sp:decode(typename, msg, sz) 60 | end) 61 | 62 | local obj = { 63 | __typename = typename, 64 | __obj = stmobj, 65 | __data = data, 66 | update = sharemap.update, 67 | } 68 | return setmetatable(obj, { __index = data, __newindex = error }) 69 | end 70 | 71 | return sharemap 72 | -------------------------------------------------------------------------------- /skynet/lualib/skynet/harbor.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local harbor = {} 4 | 5 | function harbor.globalname(name, handle) 6 | handle = handle or skynet.self() 7 | skynet.send(".cslave", "lua", "REGISTER", name, handle) 8 | end 9 | 10 | function harbor.queryname(name) 11 | return skynet.call(".cslave", "lua", "QUERYNAME", name) 12 | end 13 | 14 | function harbor.link(id) 15 | skynet.call(".cslave", "lua", "LINK", id) 16 | end 17 | 18 | function harbor.connect(id) 19 | skynet.call(".cslave", "lua", "CONNECT", id) 20 | end 21 | 22 | function harbor.linkmaster() 23 | skynet.call(".cslave", "lua", "LINKMASTER") 24 | end 25 | 26 | return harbor 27 | -------------------------------------------------------------------------------- /skynet/lualib/skynet/inject.lua: -------------------------------------------------------------------------------- 1 | local function getupvaluetable(u, func, unique) 2 | local i = 1 3 | while true do 4 | local name, value = debug.getupvalue(func, i) 5 | if name == nil then 6 | return 7 | end 8 | local t = type(value) 9 | if t == "table" then 10 | u[name] = value 11 | elseif t == "function" then 12 | if not unique[value] then 13 | unique[value] = true 14 | getupvaluetable(u, value, unique) 15 | end 16 | end 17 | i=i+1 18 | end 19 | end 20 | 21 | return function(skynet, source, filename , ...) 22 | if filename then 23 | filename = "@" .. filename 24 | else 25 | filename = "=(load)" 26 | end 27 | local output = {} 28 | 29 | local function print(...) 30 | local value = { ... } 31 | for k,v in ipairs(value) do 32 | value[k] = tostring(v) 33 | end 34 | table.insert(output, table.concat(value, "\t")) 35 | end 36 | local u = {} 37 | local unique = {} 38 | local funcs = { ... } 39 | for k, func in ipairs(funcs) do 40 | getupvaluetable(u, func, unique) 41 | end 42 | local p = {} 43 | local proto = u.proto 44 | if proto then 45 | for k,v in pairs(proto) do 46 | local name, dispatch = v.name, v.dispatch 47 | if name and dispatch and not p[name] then 48 | local pp = {} 49 | p[name] = pp 50 | getupvaluetable(pp, dispatch, unique) 51 | end 52 | end 53 | end 54 | local env = setmetatable( { print = print , _U = u, _P = p}, { __index = _ENV }) 55 | local func, err = load(source, filename, "bt", env) 56 | if not func then 57 | return { err } 58 | end 59 | local ok, err = skynet.pcall(func) 60 | if not ok then 61 | table.insert(output, err) 62 | end 63 | 64 | return output 65 | end 66 | -------------------------------------------------------------------------------- /skynet/lualib/skynet/manager.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local c = require "skynet.core" 3 | 4 | function skynet.launch(...) 5 | local addr = c.command("LAUNCH", table.concat({...}," ")) 6 | if addr then 7 | return tonumber("0x" .. string.sub(addr , 2)) 8 | end 9 | end 10 | 11 | function skynet.kill(name) 12 | if type(name) == "number" then 13 | skynet.send(".launcher","lua","REMOVE",name, true) 14 | name = skynet.address(name) 15 | end 16 | c.command("KILL",name) 17 | end 18 | 19 | function skynet.abort() 20 | c.command("ABORT") 21 | end 22 | 23 | local function globalname(name, handle) 24 | local c = string.sub(name,1,1) 25 | assert(c ~= ':') 26 | if c == '.' then 27 | return false 28 | end 29 | 30 | assert(#name <= 16) -- GLOBALNAME_LENGTH is 16, defined in skynet_harbor.h 31 | assert(tonumber(name) == nil) -- global name can't be number 32 | 33 | local harbor = require "skynet.harbor" 34 | 35 | harbor.globalname(name, handle) 36 | 37 | return true 38 | end 39 | 40 | function skynet.register(name) 41 | if not globalname(name) then 42 | c.command("REG", name) 43 | end 44 | end 45 | 46 | function skynet.name(name, handle) 47 | if not globalname(name, handle) then 48 | c.command("NAME", name .. " " .. skynet.address(handle)) 49 | end 50 | end 51 | 52 | local dispatch_message = skynet.dispatch_message 53 | 54 | function skynet.forward_type(map, start_func) 55 | c.callback(function(ptype, msg, sz, ...) 56 | local prototype = map[ptype] 57 | if prototype then 58 | dispatch_message(prototype, msg, sz, ...) 59 | else 60 | dispatch_message(ptype, msg, sz, ...) 61 | c.trash(msg, sz) 62 | end 63 | end, true) 64 | skynet.timeout(0, function() 65 | skynet.init_service(start_func) 66 | end) 67 | end 68 | 69 | function skynet.filter(f ,start_func) 70 | c.callback(function(...) 71 | dispatch_message(f(...)) 72 | end) 73 | skynet.timeout(0, function() 74 | skynet.init_service(start_func) 75 | end) 76 | end 77 | 78 | function skynet.monitor(service, query) 79 | local monitor 80 | if query then 81 | monitor = skynet.queryservice(true, service) 82 | else 83 | monitor = skynet.uniqueservice(true, service) 84 | end 85 | assert(monitor, "Monitor launch failed") 86 | c.command("MONITOR", string.format(":%08x", monitor)) 87 | return monitor 88 | end 89 | 90 | return skynet 91 | -------------------------------------------------------------------------------- /skynet/lualib/skynet/queue.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local coroutine = coroutine 3 | local xpcall = xpcall 4 | local traceback = debug.traceback 5 | local table = table 6 | 7 | function skynet.queue() 8 | local current_thread 9 | local ref = 0 10 | local thread_queue = {} 11 | 12 | local function xpcall_ret(ok, ...) 13 | ref = ref - 1 14 | if ref == 0 then 15 | current_thread = table.remove(thread_queue,1) 16 | if current_thread then 17 | skynet.wakeup(current_thread) 18 | end 19 | end 20 | assert(ok, (...)) 21 | return ... 22 | end 23 | 24 | return function(f, ...) 25 | local thread = coroutine.running() 26 | if current_thread and current_thread ~= thread then 27 | table.insert(thread_queue, thread) 28 | skynet.wait() 29 | assert(ref == 0) -- current_thread == thread 30 | end 31 | current_thread = thread 32 | 33 | ref = ref + 1 34 | return xpcall_ret(xpcall(f, traceback, ...)) 35 | end 36 | end 37 | 38 | return skynet.queue 39 | -------------------------------------------------------------------------------- /skynet/lualib/snax/interface.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | return function (name , G, loader) 4 | loader = loader or loadfile 5 | local mainfunc 6 | 7 | local function func_id(id, group) 8 | local tmp = {} 9 | local function count( _, name, func) 10 | if type(name) ~= "string" then 11 | error (string.format("%s method only support string", group)) 12 | end 13 | if type(func) ~= "function" then 14 | error (string.format("%s.%s must be function"), group, name) 15 | end 16 | if tmp[name] then 17 | error (string.format("%s.%s duplicate definition", group, name)) 18 | end 19 | tmp[name] = true 20 | table.insert(id, { #id + 1, group, name, func} ) 21 | end 22 | return setmetatable({}, { __newindex = count }) 23 | end 24 | 25 | do 26 | assert(getmetatable(G) == nil) 27 | assert(G.init == nil) 28 | assert(G.exit == nil) 29 | 30 | assert(G.accept == nil) 31 | assert(G.response == nil) 32 | end 33 | 34 | local temp_global = {} 35 | local env = setmetatable({} , { __index = temp_global }) 36 | local func = {} 37 | 38 | local system = { "init", "exit", "hotfix" } 39 | 40 | do 41 | for k, v in ipairs(system) do 42 | system[v] = k 43 | func[k] = { k , "system", v } 44 | end 45 | end 46 | 47 | env.accept = func_id(func, "accept") 48 | env.response = func_id(func, "response") 49 | 50 | local function init_system(t, name, f) 51 | local index = system[name] 52 | if index then 53 | if type(f) ~= "function" then 54 | error (string.format("%s must be a function", name)) 55 | end 56 | func[index][4] = f 57 | else 58 | temp_global[name] = f 59 | end 60 | end 61 | 62 | local pattern 63 | 64 | do 65 | local path = assert(skynet.getenv "snax" , "please set snax in config file") 66 | 67 | local errlist = {} 68 | 69 | for pat in string.gmatch(path,"[^;]+") do 70 | local filename = string.gsub(pat, "?", name) 71 | local f , err = loader(filename, "bt", G) 72 | if f then 73 | pattern = pat 74 | mainfunc = f 75 | break 76 | else 77 | table.insert(errlist, err) 78 | end 79 | end 80 | 81 | if mainfunc == nil then 82 | error(table.concat(errlist, "\n")) 83 | end 84 | end 85 | 86 | setmetatable(G, { __index = env , __newindex = init_system }) 87 | local ok, err = pcall(mainfunc) 88 | setmetatable(G, nil) 89 | assert(ok,err) 90 | 91 | for k,v in pairs(temp_global) do 92 | G[k] = v 93 | end 94 | 95 | return func, pattern 96 | end 97 | -------------------------------------------------------------------------------- /skynet/lualib/sprotoloader.lua: -------------------------------------------------------------------------------- 1 | local parser = require "sprotoparser" 2 | local core = require "sproto.core" 3 | local sproto = require "sproto" 4 | 5 | local loader = {} 6 | 7 | function loader.register(filename, index) 8 | local f = assert(io.open(filename), "Can't open sproto file") 9 | local data = f:read "a" 10 | f:close() 11 | local sp = core.newproto(parser.parse(data)) 12 | core.saveproto(sp, index) 13 | end 14 | 15 | function loader.save(bin, index) 16 | local sp = core.newproto(bin) 17 | core.saveproto(sp, index) 18 | end 19 | 20 | function loader.load(index) 21 | local sp = core.loadproto(index) 22 | -- no __gc in metatable 23 | return sproto.sharenew(sp) 24 | end 25 | 26 | return loader 27 | 28 | -------------------------------------------------------------------------------- /skynet/pbc/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O2 -fPIC -Wall 3 | AR = ar rc 4 | 5 | BUILD = build 6 | 7 | .PHONY : all lib clean tool 8 | 9 | LIBSRCS = context.c varint.c array.c pattern.c register.c proto.c map.c alloc.c rmessage.c wmessage.c bootstrap.c stringpool.c decode.c 10 | LIBNAME = libpbc.a 11 | 12 | TESTSRCS = addressbook.c pattern.c pbc.c float.c map.c test.c decode.c 13 | PROTOSRCS = addressbook.proto descriptor.proto float.proto test.proto 14 | 15 | BUILD_O = $(BUILD)/o 16 | 17 | all : lib 18 | 19 | lib : $(LIBNAME) 20 | 21 | clean : 22 | rm -rf $(BUILD) 23 | 24 | $(BUILD) : $(BUILD_O) 25 | 26 | $(BUILD_O) : 27 | mkdir -p $@ 28 | 29 | TOOL := $(BUILD)/dump 30 | 31 | tool : $(TOOL) 32 | 33 | $(TOOL) : | $(BUILD) 34 | $(TOOL) : $(LIBNAME) 35 | $(TOOL) : tool/dump.c 36 | cd $(BUILD) && $(CC) $(CFLAGS) -I.. -L. -o dump ../$< -lpbc 37 | 38 | LIB_O := 39 | 40 | define BUILD_temp 41 | TAR := $(BUILD_O)/$(notdir $(basename $(1))) 42 | LIB_O := $(LIB_O) $$(TAR).o 43 | $$(TAR).o : | $(BUILD_O) 44 | -include $$(TAR).d 45 | $$(TAR).o : src/$(1) 46 | $(CC) $(CFLAGS) -c -Isrc -I. -o $$@ -MMD $$< 47 | endef 48 | 49 | $(foreach s,$(LIBSRCS),$(eval $(call BUILD_temp,$(s)))) 50 | 51 | $(LIBNAME) : $(LIB_O) 52 | cd $(BUILD) && $(AR) $(LIBNAME) $(addprefix ../,$^) 53 | 54 | TEST := 55 | 56 | define TEST_temp 57 | TAR := $(BUILD)/$(notdir $(basename $(1))) 58 | TEST := $(TEST) $$(TAR) 59 | $$(TAR) : | $(BUILD) 60 | $$(TAR) : $(LIBNAME) 61 | $$(TAR) : test/$(1) 62 | cd $(BUILD) && $(CC) $(CFLAGS) -I.. -L. -o $$(notdir $$@) ../$$< -lpbc 63 | endef 64 | 65 | $(foreach s,$(TESTSRCS),$(eval $(call TEST_temp,$(s)))) 66 | 67 | test : $(TEST) proto 68 | 69 | PROTO := 70 | 71 | define PROTO_temp 72 | TAR := $(BUILD)/$(notdir $(basename $(1))) 73 | PROTO := $(PROTO) $$(TAR).pb 74 | $$(TAR).pb : | $(BUILD) 75 | $$(TAR).pb : test/$(1) 76 | protoc -o$$@ $$< 77 | endef 78 | 79 | $(foreach s,$(PROTOSRCS),$(eval $(call PROTO_temp,$(s)))) 80 | 81 | proto : $(PROTO) 82 | 83 | .PHONY : all lib test proto clean 84 | 85 | -------------------------------------------------------------------------------- /skynet/pbc/README.md: -------------------------------------------------------------------------------- 1 | ## PBC 2 | 3 | [![travis-ci status](https://travis-ci.org/cloudwu/pbc.svg?branch=master)](https://travis-ci.org/cloudwu/pbc) 4 | 5 | PBC is a google protocol buffers library for C without code generation. 6 | 7 | ## Quick Example 8 | 9 | package tutorial; 10 | 11 | message Person { 12 | required string name = 1; 13 | required int32 id = 2; // Unique ID number for this person. 14 | optional string email = 3; 15 | 16 | enum PhoneType { 17 | MOBILE = 0; 18 | HOME = 1; 19 | WORK = 2; 20 | } 21 | 22 | message PhoneNumber { 23 | required string number = 1; 24 | optional PhoneType type = 2 [default = HOME]; 25 | } 26 | 27 | repeated PhoneNumber phone = 4; 28 | } 29 | 30 | ```C 31 | struct pbc_rmessage * m = pbc_rmessage_new(env, "tutorial.Person", slice); 32 | printf("name = %s\n", pbc_rmessage_string(m , "name" , 0 , NULL)); 33 | printf("id = %d\n", pbc_rmessage_integer(m , "id" , 0 , NULL)); 34 | printf("email = %s\n", pbc_rmessage_string(m , "email" , 0 , NULL)); 35 | 36 | int phone_n = pbc_rmessage_size(m, "phone"); 37 | int i; 38 | 39 | for (i=0;i 2 | #include 3 | 4 | static int _g = 0; 5 | 6 | void * _pbcM_malloc(size_t sz) { 7 | ++ _g; 8 | return malloc(sz); 9 | } 10 | 11 | void _pbcM_free(void *p) { 12 | if (p) { 13 | -- _g; 14 | free(p); 15 | } 16 | } 17 | 18 | void* _pbcM_realloc(void *p, size_t sz) { 19 | return realloc(p,sz); 20 | } 21 | 22 | void _pbcM_memory() { 23 | printf("%d\n",_g); 24 | } 25 | 26 | struct heap_page { 27 | struct heap_page * next; 28 | }; 29 | 30 | struct heap { 31 | struct heap_page *current; 32 | int size; 33 | int used; 34 | }; 35 | 36 | struct heap * 37 | _pbcH_new(int pagesize) { 38 | int cap = 1024; 39 | while(cap < pagesize) { 40 | cap *= 2; 41 | } 42 | struct heap * h = (struct heap *)_pbcM_malloc(sizeof(struct heap)); 43 | h->current = (struct heap_page *)_pbcM_malloc(sizeof(struct heap_page) + cap); 44 | h->size = cap; 45 | h->used = 0; 46 | h->current->next = NULL; 47 | return h; 48 | } 49 | 50 | void 51 | _pbcH_delete(struct heap *h) { 52 | struct heap_page * p = h->current; 53 | struct heap_page * next = p->next; 54 | for(;;) { 55 | _pbcM_free(p); 56 | if (next == NULL) 57 | break; 58 | p = next; 59 | next = p->next; 60 | } 61 | _pbcM_free(h); 62 | } 63 | 64 | void* 65 | _pbcH_alloc(struct heap *h, int size) { 66 | size = (size + 3) & ~3; 67 | if (h->size - h->used < size) { 68 | struct heap_page * p; 69 | if (size < h->size) { 70 | p = (struct heap_page *)_pbcM_malloc(sizeof(struct heap_page) + h->size); 71 | } else { 72 | p = (struct heap_page *)_pbcM_malloc(sizeof(struct heap_page) + size); 73 | } 74 | p->next = h->current; 75 | h->current = p; 76 | h->used = size; 77 | return (p+1); 78 | } else { 79 | char * buffer = (char *)(h->current + 1); 80 | buffer += h->used; 81 | h->used += size; 82 | return buffer; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /skynet/pbc/src/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTOBUF_C_ALLOC_H 2 | #define PROTOBUF_C_ALLOC_H 3 | 4 | #include 5 | #include 6 | 7 | void * _pbcM_malloc(size_t sz); 8 | void _pbcM_free(void *p); 9 | void * _pbcM_realloc(void *p, size_t sz); 10 | void _pbcM_memory(); 11 | 12 | struct heap; 13 | 14 | struct heap * _pbcH_new(int pagesize); 15 | void _pbcH_delete(struct heap *); 16 | void* _pbcH_alloc(struct heap *, int size); 17 | 18 | #define HMALLOC(size) ((h) ? _pbcH_alloc(h, size) : _pbcM_malloc(size)) 19 | 20 | #define malloc _pbcM_malloc 21 | #define free _pbcM_free 22 | #define realloc _pbcM_realloc 23 | #define memory _pbcM_memory 24 | 25 | #ifdef _WIN32 26 | 27 | #include 28 | 29 | #endif 30 | 31 | #ifdef _MSC_VER 32 | 33 | #define alloca _alloca 34 | 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /skynet/pbc/src/array.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTOBUF_C_ARRAY_H 2 | #define PROTOBUF_C_ARRAY_H 3 | 4 | #include "varint.h" 5 | #include "pbc.h" 6 | #include "alloc.h" 7 | 8 | typedef union _pbc_var { 9 | struct longlong integer; 10 | double real; 11 | struct { 12 | const char * str; 13 | int len; 14 | } s; 15 | struct { 16 | int id; 17 | const char * name; 18 | } e; 19 | struct pbc_slice m; 20 | void * p[2]; 21 | } pbc_var[1]; 22 | 23 | void _pbcA_open(pbc_array); 24 | void _pbcA_open_heap(pbc_array, struct heap *h); 25 | void _pbcA_close(pbc_array); 26 | 27 | void _pbcA_push(pbc_array, pbc_var var); 28 | void _pbcA_index(pbc_array , int idx, pbc_var var); 29 | void * _pbcA_index_p(pbc_array _array, int idx); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /skynet/pbc/src/bootstrap.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTOBUF_C_BOOTSTRAP_H 2 | #define PROTOBUF_C_BOOTSTRAP_H 3 | 4 | #include "proto.h" 5 | #include "pbc.h" 6 | 7 | void _pbcB_init(struct pbc_env *); 8 | void _pbcB_register_fields(struct pbc_env *, pbc_array queue); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /skynet/pbc/src/map.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTOBUF_C_MAP_H 2 | #define PROTOBUF_C_MAP_H 3 | 4 | #include "alloc.h" 5 | 6 | struct map_ip; 7 | struct map_si; 8 | struct map_sp; 9 | 10 | struct map_kv { 11 | int id; 12 | void *pointer; 13 | }; 14 | 15 | struct map_si * _pbcM_si_new(struct map_kv * table, int size); 16 | int _pbcM_si_query(struct map_si *map, const char *key, int *result); 17 | void _pbcM_si_delete(struct map_si *map); 18 | 19 | struct map_ip * _pbcM_ip_new(struct map_kv * table, int size); 20 | struct map_ip * _pbcM_ip_combine(struct map_ip * a, struct map_ip * b); 21 | void * _pbcM_ip_query(struct map_ip * map, int id); 22 | void _pbcM_ip_delete(struct map_ip *map); 23 | 24 | struct map_sp * _pbcM_sp_new(int max, struct heap *h); 25 | void _pbcM_sp_insert(struct map_sp *map, const char *key, void * value); 26 | void * _pbcM_sp_query(struct map_sp *map, const char *key); 27 | void ** _pbcM_sp_query_insert(struct map_sp *map, const char *key); 28 | void _pbcM_sp_delete(struct map_sp *map); 29 | void _pbcM_sp_foreach(struct map_sp *map, void (*func)(void *p)); 30 | void _pbcM_sp_foreach_ud(struct map_sp *map, void (*func)(void *p, void *ud), void *ud); 31 | void * _pbcM_sp_next(struct map_sp *map, const char ** key); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /skynet/pbc/src/pattern.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTOBUF_C_PATTERN_H 2 | #define PROTOBUF_C_PATTERN_H 3 | 4 | #include "pbc.h" 5 | #include "context.h" 6 | #include "array.h" 7 | 8 | struct _pattern_field { 9 | int id; 10 | int offset; 11 | int ptype; 12 | int ctype; 13 | int label; 14 | pbc_var defv; 15 | }; 16 | 17 | struct pbc_pattern { 18 | struct pbc_env * env; 19 | int count; 20 | struct _pattern_field f[1]; 21 | }; 22 | 23 | struct pbc_pattern * _pbcP_new(struct pbc_env * env, int n); 24 | int _pbcP_unpack_packed(uint8_t *buffer, int size, int ptype, pbc_array array); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /skynet/pbc/src/proto.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTOBUFC_PROTO_H 2 | #define PROTOBUFC_PROTO_H 3 | 4 | #include "pbc.h" 5 | #include "map.h" 6 | #include "array.h" 7 | #ifndef _MSC_VER 8 | #include 9 | #endif 10 | #include 11 | 12 | struct map_ip; 13 | struct map_si; 14 | struct map_sp; 15 | struct _message; 16 | struct _enum; 17 | 18 | #define LABEL_OPTIONAL 0 19 | #define LABEL_REQUIRED 1 20 | #define LABEL_REPEATED 2 21 | #define LABEL_PACKED 3 22 | 23 | struct _field { 24 | int id; 25 | const char *name; 26 | int type; 27 | int label; 28 | pbc_var default_v; 29 | union { 30 | const char * n; 31 | struct _message * m; 32 | struct _enum * e; 33 | } type_name; 34 | }; 35 | 36 | struct _message { 37 | const char * key; 38 | struct map_ip * id; // id -> _field 39 | struct map_sp * name; // string -> _field 40 | struct pbc_rmessage * def; // default message 41 | struct pbc_env * env; 42 | }; 43 | 44 | struct _enum { 45 | const char * key; 46 | struct map_ip * id; 47 | struct map_si * name; 48 | pbc_var default_v; 49 | }; 50 | 51 | struct pbc_env { 52 | struct map_sp * files; // string -> void * 53 | struct map_sp * enums; // string -> _enum 54 | struct map_sp * msgs; // string -> _message 55 | const char * lasterror; 56 | }; 57 | 58 | struct _message * _pbcP_init_message(struct pbc_env * p, const char *name); 59 | void _pbcP_push_message(struct pbc_env * p, const char *name, struct _field *f , pbc_array queue); 60 | struct _enum * _pbcP_push_enum(struct pbc_env * p, const char *name, struct map_kv *table, int sz ); 61 | int _pbcP_message_default(struct _message * m, const char * name, pbc_var defv); 62 | struct _message * _pbcP_get_message(struct pbc_env * p, const char *name); 63 | int _pbcP_type(struct _field * field, const char **type); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /skynet/pbc/src/stringpool.c: -------------------------------------------------------------------------------- 1 | #include "alloc.h" 2 | 3 | #include 4 | #include 5 | 6 | #define PAGE_SIZE 256 7 | 8 | struct _stringpool { 9 | char * buffer; 10 | size_t len; 11 | struct _stringpool *next; 12 | }; 13 | 14 | struct _stringpool * 15 | _pbcS_new(void) { 16 | struct _stringpool * ret = (struct _stringpool *)malloc(sizeof(struct _stringpool) + PAGE_SIZE); 17 | ret->buffer = (char *)(ret + 1); 18 | ret->len = 0; 19 | ret->next = NULL; 20 | return ret; 21 | } 22 | 23 | void 24 | _pbcS_delete(struct _stringpool *pool) { 25 | while(pool) { 26 | struct _stringpool *next = pool->next; 27 | free(pool); 28 | pool = next; 29 | } 30 | } 31 | 32 | const char * 33 | _pbcS_build(struct _stringpool *pool, const char * str , int sz) { 34 | size_t s = sz + 1; 35 | if (s < PAGE_SIZE - pool->len) { 36 | char * ret = pool->buffer + pool->len; 37 | memcpy(pool->buffer + pool->len, str, s); 38 | pool->len += s; 39 | return ret; 40 | } 41 | if (s > PAGE_SIZE) { 42 | struct _stringpool * next = (struct _stringpool *)malloc(sizeof(struct _stringpool) + s); 43 | next->buffer = (char *)(next + 1); 44 | memcpy(next->buffer, str, s); 45 | next->len = s; 46 | next->next = pool->next; 47 | pool->next = next; 48 | return next->buffer; 49 | } 50 | struct _stringpool *next = (struct _stringpool *)malloc(sizeof(struct _stringpool) + PAGE_SIZE); 51 | next->buffer = pool->buffer; 52 | next->next = pool->next; 53 | next->len = pool->len; 54 | 55 | pool->next = next; 56 | pool->buffer = (char *)(next + 1); 57 | memcpy(pool->buffer, str, s); 58 | pool->len = s; 59 | return pool->buffer; 60 | } 61 | -------------------------------------------------------------------------------- /skynet/pbc/src/stringpool.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTOBUF_C_STRINGPOOL_H 2 | #define PROTOBUF_C_STRINGPOOL_H 3 | 4 | struct _stringpool; 5 | 6 | struct _stringpool * _pbcS_new(void); 7 | void _pbcS_delete(struct _stringpool *pool); 8 | const char * _pbcS_build(struct _stringpool *pool, const char * str , int sz); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /skynet/pbc/src/varint.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTOBUF_C_VARINT_H 2 | #define PROTOBUF_C_VARINT_H 3 | 4 | #include 5 | 6 | struct longlong { 7 | uint32_t low; 8 | uint32_t hi; 9 | }; 10 | 11 | int _pbcV_encode32(uint32_t number, uint8_t buffer[10]); 12 | int _pbcV_encode(uint64_t number, uint8_t buffer[10]); 13 | int _pbcV_zigzag32(int32_t number, uint8_t buffer[10]); 14 | int _pbcV_zigzag(int64_t number, uint8_t buffer[10]); 15 | 16 | int _pbcV_decode(uint8_t buffer[10], struct longlong *result); 17 | void _pbcV_dezigzag64(struct longlong *r); 18 | void _pbcV_dezigzag32(struct longlong *r); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /skynet/platform.mk: -------------------------------------------------------------------------------- 1 | PLAT ?= none 2 | PLATS = linux freebsd macosx 3 | 4 | CC ?= gcc 5 | 6 | .PHONY : none $(PLATS) clean all cleanall 7 | 8 | #ifneq ($(PLAT), none) 9 | 10 | .PHONY : default 11 | 12 | default : 13 | $(MAKE) $(PLAT) 14 | 15 | #endif 16 | 17 | none : 18 | @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" 19 | @echo " $(PLATS)" 20 | 21 | SKYNET_LIBS := -lpthread -lm 22 | SHARED := -fPIC --shared 23 | EXPORT := -Wl,-E 24 | 25 | linux : PLAT = linux 26 | macosx : PLAT = macosx 27 | freebsd : PLAT = freebsd 28 | 29 | macosx : SHARED := -fPIC -dynamiclib -Wl,-undefined,dynamic_lookup 30 | macosx : EXPORT := 31 | macosx linux : SKYNET_LIBS += -ldl 32 | linux freebsd : SKYNET_LIBS += -lrt 33 | 34 | # Turn off jemalloc and malloc hook on macosx 35 | 36 | macosx : MALLOC_STATICLIB := 37 | macosx : SKYNET_DEFINES :=-DNOUSE_JEMALLOC 38 | 39 | linux macosx freebsd : 40 | $(MAKE) all PLAT=$@ SKYNET_LIBS="$(SKYNET_LIBS)" SHARED="$(SHARED)" EXPORT="$(EXPORT)" MALLOC_STATICLIB="$(MALLOC_STATICLIB)" SKYNET_DEFINES="$(SKYNET_DEFINES)" 41 | -------------------------------------------------------------------------------- /skynet/service-src/service_logger.c: -------------------------------------------------------------------------------- 1 | #include "skynet.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct logger { 10 | FILE * handle; 11 | char * filename; 12 | int close; 13 | }; 14 | 15 | struct logger * 16 | logger_create(void) { 17 | struct logger * inst = skynet_malloc(sizeof(*inst)); 18 | inst->handle = NULL; 19 | inst->close = 0; 20 | inst->filename = NULL; 21 | 22 | return inst; 23 | } 24 | 25 | void 26 | logger_release(struct logger * inst) { 27 | if (inst->close) { 28 | fclose(inst->handle); 29 | } 30 | skynet_free(inst->filename); 31 | skynet_free(inst); 32 | } 33 | 34 | static int 35 | logger_cb(struct skynet_context * context, void *ud, int type, int session, uint32_t source, const void * msg, size_t sz) { 36 | struct logger * inst = ud; 37 | switch (type) { 38 | case PTYPE_SYSTEM: 39 | if (inst->filename) { 40 | inst->handle = freopen(inst->filename, "a", inst->handle); 41 | } 42 | break; 43 | case PTYPE_TEXT: 44 | { 45 | char timestamp[64]; 46 | time_t ti = time(0); 47 | strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", localtime(&ti)); 48 | fprintf(inst->handle, "[:%s][:%08x] ",timestamp, source); 49 | fwrite(msg, sz , 1, inst->handle); 50 | fprintf(inst->handle, "\n"); 51 | fflush(inst->handle); 52 | } 53 | break; 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | int 60 | logger_init(struct logger * inst, struct skynet_context *ctx, const char * parm) { 61 | if (parm) { 62 | inst->handle = fopen(parm,"w"); 63 | if (inst->handle == NULL) { 64 | return 1; 65 | } 66 | inst->filename = skynet_malloc(strlen(parm)+1); 67 | strcpy(inst->filename, parm); 68 | inst->close = 1; 69 | } else { 70 | inst->handle = stdout; 71 | } 72 | if (inst->handle) { 73 | skynet_callback(ctx, inst, logger_cb); 74 | skynet_command(ctx, "REG", ".logger"); 75 | return 0; 76 | } 77 | return 1; 78 | } 79 | -------------------------------------------------------------------------------- /skynet/service/bootstrap.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local harbor = require "skynet.harbor" 3 | require "skynet.manager" -- import skynet.launch, ... 4 | local memory = require "memory" 5 | 6 | skynet.start(function() 7 | local sharestring = tonumber(skynet.getenv "sharestring" or 4096) 8 | memory.ssexpand(sharestring) 9 | 10 | local standalone = skynet.getenv "standalone" 11 | 12 | local launcher = assert(skynet.launch("snlua","launcher")) 13 | skynet.name(".launcher", launcher) 14 | 15 | local harbor_id = tonumber(skynet.getenv "harbor" or 0) 16 | if harbor_id == 0 then 17 | assert(standalone == nil) 18 | standalone = true 19 | skynet.setenv("standalone", "true") 20 | 21 | local ok, slave = pcall(skynet.newservice, "cdummy") 22 | if not ok then 23 | skynet.abort() 24 | end 25 | skynet.name(".cslave", slave) 26 | 27 | else 28 | if standalone then 29 | if not pcall(skynet.newservice,"cmaster") then 30 | skynet.abort() 31 | end 32 | end 33 | 34 | local ok, slave = pcall(skynet.newservice, "cslave") 35 | if not ok then 36 | skynet.abort() 37 | end 38 | skynet.name(".cslave", slave) 39 | end 40 | 41 | if standalone then 42 | local datacenter = skynet.newservice "datacenterd" 43 | skynet.name("DATACENTER", datacenter) 44 | end 45 | skynet.newservice "service_mgr" 46 | pcall(skynet.newservice,skynet.getenv "start" or "main") 47 | skynet.exit() 48 | end) 49 | -------------------------------------------------------------------------------- /skynet/service/cdummy.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | require "skynet.manager" -- import skynet.launch, ... 3 | 4 | local globalname = {} 5 | local queryname = {} 6 | local harbor = {} 7 | local harbor_service 8 | 9 | skynet.register_protocol { 10 | name = "harbor", 11 | id = skynet.PTYPE_HARBOR, 12 | pack = function(...) return ... end, 13 | unpack = skynet.tostring, 14 | } 15 | 16 | skynet.register_protocol { 17 | name = "text", 18 | id = skynet.PTYPE_TEXT, 19 | pack = function(...) return ... end, 20 | unpack = skynet.tostring, 21 | } 22 | 23 | local function response_name(name) 24 | local address = globalname[name] 25 | if queryname[name] then 26 | local tmp = queryname[name] 27 | queryname[name] = nil 28 | for _,resp in ipairs(tmp) do 29 | resp(true, address) 30 | end 31 | end 32 | end 33 | 34 | function harbor.REGISTER(name, handle) 35 | assert(globalname[name] == nil) 36 | globalname[name] = handle 37 | response_name(name) 38 | skynet.redirect(harbor_service, handle, "harbor", 0, "N " .. name) 39 | end 40 | 41 | function harbor.QUERYNAME(name) 42 | if name:byte() == 46 then -- "." , local name 43 | skynet.ret(skynet.pack(skynet.localname(name))) 44 | return 45 | end 46 | local result = globalname[name] 47 | if result then 48 | skynet.ret(skynet.pack(result)) 49 | return 50 | end 51 | local queue = queryname[name] 52 | if queue == nil then 53 | queue = { skynet.response() } 54 | queryname[name] = queue 55 | else 56 | table.insert(queue, skynet.response()) 57 | end 58 | end 59 | 60 | function harbor.LINK(id) 61 | skynet.ret() 62 | end 63 | 64 | function harbor.CONNECT(id) 65 | skynet.error("Can't connect to other harbor in single node mode") 66 | end 67 | 68 | skynet.start(function() 69 | local harbor_id = tonumber(skynet.getenv "harbor") 70 | assert(harbor_id == 0) 71 | 72 | skynet.dispatch("lua", function (session,source,command,...) 73 | local f = assert(harbor[command]) 74 | f(...) 75 | end) 76 | skynet.dispatch("text", function(session,source,command) 77 | -- ignore all the command 78 | end) 79 | 80 | harbor_service = assert(skynet.launch("harbor", harbor_id, skynet.self())) 81 | end) 82 | -------------------------------------------------------------------------------- /skynet/service/clusterproxy.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local cluster = require "cluster" 3 | require "skynet.manager" -- inject skynet.forward_type 4 | 5 | local node, address = ... 6 | 7 | skynet.register_protocol { 8 | name = "system", 9 | id = skynet.PTYPE_SYSTEM, 10 | unpack = function (...) return ... end, 11 | } 12 | 13 | local forward_map = { 14 | [skynet.PTYPE_SNAX] = skynet.PTYPE_SYSTEM, 15 | [skynet.PTYPE_LUA] = skynet.PTYPE_SYSTEM, 16 | [skynet.PTYPE_RESPONSE] = skynet.PTYPE_RESPONSE, -- don't free response message 17 | } 18 | 19 | skynet.forward_type( forward_map ,function() 20 | local clusterd = skynet.uniqueservice("clusterd") 21 | local n = tonumber(address) 22 | if n then 23 | address = n 24 | end 25 | skynet.dispatch("system", function (session, source, msg, sz) 26 | skynet.ret(skynet.rawcall(clusterd, "lua", skynet.pack("req", node, address, msg, sz))) 27 | end) 28 | end) 29 | -------------------------------------------------------------------------------- /skynet/service/cmemory.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local memory = require "memory" 3 | 4 | memory.dumpinfo() 5 | --memory.dump() 6 | local info = memory.info() 7 | for k,v in pairs(info) do 8 | print(string.format(":%08x %gK",k,v/1024)) 9 | end 10 | 11 | print("Total memory:", memory.total()) 12 | print("Total block:", memory.block()) 13 | 14 | skynet.start(function() skynet.exit() end) 15 | -------------------------------------------------------------------------------- /skynet/service/console.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local snax = require "snax" 3 | local socket = require "socket" 4 | 5 | local function split_cmdline(cmdline) 6 | local split = {} 7 | for i in string.gmatch(cmdline, "%S+") do 8 | table.insert(split,i) 9 | end 10 | return split 11 | end 12 | 13 | local function console_main_loop() 14 | local stdin = socket.stdin() 15 | socket.lock(stdin) 16 | while true do 17 | local cmdline = socket.readline(stdin, "\n") 18 | local split = split_cmdline(cmdline) 19 | local command = split[1] 20 | if command == "snax" then 21 | pcall(snax.newservice, select(2, table.unpack(split))) 22 | elseif cmdline ~= "" then 23 | pcall(skynet.newservice, cmdline) 24 | end 25 | end 26 | socket.unlock(stdin) 27 | end 28 | 29 | skynet.start(function() 30 | skynet.fork(console_main_loop) 31 | end) 32 | -------------------------------------------------------------------------------- /skynet/service/datacenterd.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local command = {} 4 | local database = {} 5 | local wait_queue = {} 6 | local mode = {} 7 | 8 | local function query(db, key, ...) 9 | if key == nil then 10 | return db 11 | else 12 | return query(db[key], ...) 13 | end 14 | end 15 | 16 | function command.QUERY(key, ...) 17 | local d = database[key] 18 | if d then 19 | return query(d, ...) 20 | end 21 | end 22 | 23 | local function update(db, key, value, ...) 24 | if select("#",...) == 0 then 25 | local ret = db[key] 26 | db[key] = value 27 | return ret, value 28 | else 29 | if db[key] == nil then 30 | db[key] = {} 31 | end 32 | return update(db[key], value, ...) 33 | end 34 | end 35 | 36 | local function wakeup(db, key1, ...) 37 | if key1 == nil then 38 | return 39 | end 40 | local q = db[key1] 41 | if q == nil then 42 | return 43 | end 44 | if q[mode] == "queue" then 45 | db[key1] = nil 46 | if select("#", ...) ~= 1 then 47 | -- throw error because can't wake up a branch 48 | for _,response in ipairs(q) do 49 | response(false) 50 | end 51 | else 52 | return q 53 | end 54 | else 55 | -- it's branch 56 | return wakeup(q , ...) 57 | end 58 | end 59 | 60 | function command.UPDATE(...) 61 | local ret, value = update(database, ...) 62 | if ret or value == nil then 63 | return ret 64 | end 65 | local q = wakeup(wait_queue, ...) 66 | if q then 67 | for _, response in ipairs(q) do 68 | response(true,value) 69 | end 70 | end 71 | end 72 | 73 | local function waitfor(db, key1, key2, ...) 74 | if key2 == nil then 75 | -- push queue 76 | local q = db[key1] 77 | if q == nil then 78 | q = { [mode] = "queue" } 79 | db[key1] = q 80 | else 81 | assert(q[mode] == "queue") 82 | end 83 | table.insert(q, skynet.response()) 84 | else 85 | local q = db[key1] 86 | if q == nil then 87 | q = { [mode] = "branch" } 88 | db[key1] = q 89 | else 90 | assert(q[mode] == "branch") 91 | end 92 | return waitfor(q, key2, ...) 93 | end 94 | end 95 | 96 | skynet.start(function() 97 | skynet.dispatch("lua", function (_, _, cmd, ...) 98 | if cmd == "WAIT" then 99 | local ret = command.QUERY(...) 100 | if ret then 101 | skynet.ret(skynet.pack(ret)) 102 | else 103 | waitfor(wait_queue, ...) 104 | end 105 | else 106 | local f = assert(command[cmd]) 107 | skynet.ret(skynet.pack(f(...))) 108 | end 109 | end) 110 | end) 111 | -------------------------------------------------------------------------------- /skynet/service/dbg.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local cmd = { ... } 4 | 5 | local function format_table(t) 6 | local index = {} 7 | for k in pairs(t) do 8 | table.insert(index, k) 9 | end 10 | table.sort(index) 11 | local result = {} 12 | for _,v in ipairs(index) do 13 | table.insert(result, string.format("%s:%s",v,tostring(t[v]))) 14 | end 15 | return table.concat(result,"\t") 16 | end 17 | 18 | local function dump_line(key, value) 19 | if type(value) == "table" then 20 | print(key, format_table(value)) 21 | else 22 | print(key,tostring(value)) 23 | end 24 | end 25 | 26 | local function dump_list(list) 27 | local index = {} 28 | for k in pairs(list) do 29 | table.insert(index, k) 30 | end 31 | table.sort(index) 32 | for _,v in ipairs(index) do 33 | dump_line(v, list[v]) 34 | end 35 | end 36 | 37 | skynet.start(function() 38 | local list = skynet.call(".launcher","lua", table.unpack(cmd)) 39 | if list then 40 | dump_list(list) 41 | end 42 | skynet.exit() 43 | end) -------------------------------------------------------------------------------- /skynet/service/debug_agent.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local debugchannel = require "debugchannel" 3 | 4 | local CMD = {} 5 | 6 | local channel 7 | 8 | function CMD.start(address, fd) 9 | assert(channel == nil, "start more than once") 10 | skynet.error(string.format("Attach to :%08x", address)) 11 | local handle 12 | channel, handle = debugchannel.create() 13 | skynet.call(address, "debug", "REMOTEDEBUG", fd, handle) 14 | -- todo hook 15 | skynet.ret(skynet.pack(nil)) 16 | skynet.exit() 17 | end 18 | 19 | function CMD.cmd(cmdline) 20 | channel:write(cmdline) 21 | end 22 | 23 | skynet.start(function() 24 | skynet.dispatch("lua", function(_,_,cmd,...) 25 | local f = CMD[cmd] 26 | f(...) 27 | end) 28 | end) 29 | -------------------------------------------------------------------------------- /skynet/service/gate.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local gateserver = require "snax.gateserver" 3 | local netpack = require "netpack" 4 | 5 | local watchdog 6 | local connection = {} -- fd -> connection : { fd , client, agent , ip, mode } 7 | local forwarding = {} -- agent -> connection 8 | 9 | skynet.register_protocol { 10 | name = "client", 11 | id = skynet.PTYPE_CLIENT, 12 | } 13 | 14 | local handler = {} 15 | 16 | function handler.open(source, conf) 17 | watchdog = conf.watchdog or source 18 | end 19 | 20 | function handler.message(fd, msg, sz) 21 | -- recv a package, forward it 22 | local c = connection[fd] 23 | local agent = c.agent 24 | if agent then 25 | skynet.redirect(agent, c.client, "client", 0, msg, sz) 26 | else 27 | skynet.send(watchdog, "lua", "socket", "data", fd, netpack.tostring(msg, sz)) 28 | end 29 | end 30 | 31 | function handler.connect(fd, addr) 32 | local c = { 33 | fd = fd, 34 | ip = addr, 35 | } 36 | connection[fd] = c 37 | skynet.send(watchdog, "lua", "socket", "open", fd, addr) 38 | end 39 | 40 | local function unforward(c) 41 | if c.agent then 42 | forwarding[c.agent] = nil 43 | c.agent = nil 44 | c.client = nil 45 | end 46 | end 47 | 48 | local function close_fd(fd) 49 | local c = connection[fd] 50 | if c then 51 | unforward(c) 52 | connection[fd] = nil 53 | end 54 | end 55 | 56 | function handler.disconnect(fd) 57 | close_fd(fd) 58 | skynet.send(watchdog, "lua", "socket", "close", fd) 59 | end 60 | 61 | function handler.error(fd, msg) 62 | close_fd(fd) 63 | skynet.send(watchdog, "lua", "socket", "error", fd, msg) 64 | end 65 | 66 | function handler.warning(fd, size) 67 | skynet.send(watchdog, "lua", "socket", "warning", fd, size) 68 | end 69 | 70 | local CMD = {} 71 | 72 | function CMD.forward(source, fd, client, address) 73 | local c = assert(connection[fd]) 74 | unforward(c) 75 | c.client = client or 0 76 | c.agent = address or source 77 | forwarding[c.agent] = c 78 | gateserver.openclient(fd) 79 | end 80 | 81 | function CMD.accept(source, fd) 82 | local c = assert(connection[fd]) 83 | unforward(c) 84 | gateserver.openclient(fd) 85 | end 86 | 87 | function CMD.kick(source, fd) 88 | gateserver.closeclient(fd) 89 | end 90 | 91 | function handler.command(cmd, source, ...) 92 | local f = assert(CMD[cmd]) 93 | return f(source, ...) 94 | end 95 | 96 | gateserver.start(handler) 97 | -------------------------------------------------------------------------------- /skynet/service/snaxd.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local c = require "skynet.core" 3 | local snax_interface = require "snax.interface" 4 | local profile = require "profile" 5 | local snax = require "snax" 6 | 7 | local snax_name = tostring(...) 8 | local func, pattern = snax_interface(snax_name, _ENV) 9 | local snax_path = pattern:sub(1,pattern:find("?", 1, true)-1) .. snax_name .. "/" 10 | package.path = snax_path .. "?.lua;" .. package.path 11 | 12 | SERVICE_NAME = snax_name 13 | SERVICE_PATH = snax_path 14 | 15 | local profile_table = {} 16 | 17 | local function update_stat(name, ti) 18 | local t = profile_table[name] 19 | if t == nil then 20 | t = { count = 0, time = 0 } 21 | profile_table[name] = t 22 | end 23 | t.count = t.count + 1 24 | t.time = t.time + ti 25 | end 26 | 27 | local traceback = debug.traceback 28 | 29 | local function return_f(f, ...) 30 | return skynet.ret(skynet.pack(f(...))) 31 | end 32 | 33 | local function timing( method, ... ) 34 | local err, msg 35 | profile.start() 36 | if method[2] == "accept" then 37 | -- no return 38 | err,msg = xpcall(method[4], traceback, ...) 39 | else 40 | err,msg = xpcall(return_f, traceback, method[4], ...) 41 | end 42 | local ti = profile.stop() 43 | update_stat(method[3], ti) 44 | assert(err,msg) 45 | end 46 | 47 | skynet.start(function() 48 | local init = false 49 | local function dispatcher( session , source , id, ...) 50 | local method = func[id] 51 | 52 | if method[2] == "system" then 53 | local command = method[3] 54 | if command == "hotfix" then 55 | local hotfix = require "snax.hotfix" 56 | skynet.ret(skynet.pack(hotfix(func, ...))) 57 | elseif command == "init" then 58 | assert(not init, "Already init") 59 | local initfunc = method[4] or function() end 60 | initfunc(...) 61 | skynet.ret() 62 | skynet.info_func(function() 63 | return profile_table 64 | end) 65 | init = true 66 | else 67 | assert(init, "Never init") 68 | assert(command == "exit") 69 | local exitfunc = method[4] or function() end 70 | exitfunc(...) 71 | skynet.ret() 72 | init = false 73 | skynet.exit() 74 | end 75 | else 76 | assert(init, "Init first") 77 | timing(method, ...) 78 | end 79 | end 80 | skynet.dispatch("snax", dispatcher) 81 | 82 | -- set lua dispatcher 83 | function snax.enablecluster() 84 | skynet.dispatch("lua", dispatcher) 85 | end 86 | end) 87 | -------------------------------------------------------------------------------- /skynet/skynet-src/atomic.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_ATOMIC_H 2 | #define SKYNET_ATOMIC_H 3 | 4 | #define ATOM_CAS(ptr, oval, nval) __sync_bool_compare_and_swap(ptr, oval, nval) 5 | #define ATOM_CAS_POINTER(ptr, oval, nval) __sync_bool_compare_and_swap(ptr, oval, nval) 6 | #define ATOM_INC(ptr) __sync_add_and_fetch(ptr, 1) 7 | #define ATOM_FINC(ptr) __sync_fetch_and_add(ptr, 1) 8 | #define ATOM_DEC(ptr) __sync_sub_and_fetch(ptr, 1) 9 | #define ATOM_FDEC(ptr) __sync_fetch_and_sub(ptr, 1) 10 | #define ATOM_ADD(ptr,n) __sync_add_and_fetch(ptr, n) 11 | #define ATOM_SUB(ptr,n) __sync_sub_and_fetch(ptr, n) 12 | #define ATOM_AND(ptr,n) __sync_and_and_fetch(ptr, n) 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /skynet/skynet-src/luashrtbl.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_SHORT_STRING_TABLE_H 2 | #define LUA_SHORT_STRING_TABLE_H 3 | 4 | #include "lstring.h" 5 | 6 | // If you use modified lua, this macro would be defined in lstring.h 7 | #ifndef ENABLE_SHORT_STRING_TABLE 8 | 9 | static inline int luaS_shrinfo(lua_State *L) { return 0; } 10 | static inline void luaS_initshr() {} 11 | static inline void luaS_exitshr() {} 12 | static inline void luaS_expandshr(int n) {} 13 | 14 | #endif 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /skynet/skynet-src/malloc_hook.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_MALLOC_HOOK_H 2 | #define SKYNET_MALLOC_HOOK_H 3 | 4 | #include 5 | #include 6 | 7 | extern size_t malloc_used_memory(void); 8 | extern size_t malloc_memory_block(void); 9 | extern void memory_info_dump(void); 10 | extern size_t mallctl_int64(const char* name, size_t* newval); 11 | extern int mallctl_opt(const char* name, int* newval); 12 | extern void dump_c_mem(void); 13 | extern int dump_mem_lua(lua_State *L); 14 | extern size_t malloc_current_memory(void); 15 | 16 | #endif /* SKYNET_MALLOC_HOOK_H */ 17 | 18 | -------------------------------------------------------------------------------- /skynet/skynet-src/rwlock.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_RWLOCK_H 2 | #define SKYNET_RWLOCK_H 3 | 4 | #ifndef USE_PTHREAD_LOCK 5 | 6 | struct rwlock { 7 | int write; 8 | int read; 9 | }; 10 | 11 | static inline void 12 | rwlock_init(struct rwlock *lock) { 13 | lock->write = 0; 14 | lock->read = 0; 15 | } 16 | 17 | static inline void 18 | rwlock_rlock(struct rwlock *lock) { 19 | for (;;) { 20 | while(lock->write) { 21 | __sync_synchronize(); 22 | } 23 | __sync_add_and_fetch(&lock->read,1); 24 | if (lock->write) { 25 | __sync_sub_and_fetch(&lock->read,1); 26 | } else { 27 | break; 28 | } 29 | } 30 | } 31 | 32 | static inline void 33 | rwlock_wlock(struct rwlock *lock) { 34 | while (__sync_lock_test_and_set(&lock->write,1)) {} 35 | while(lock->read) { 36 | __sync_synchronize(); 37 | } 38 | } 39 | 40 | static inline void 41 | rwlock_wunlock(struct rwlock *lock) { 42 | __sync_lock_release(&lock->write); 43 | } 44 | 45 | static inline void 46 | rwlock_runlock(struct rwlock *lock) { 47 | __sync_sub_and_fetch(&lock->read,1); 48 | } 49 | 50 | #else 51 | 52 | #include 53 | 54 | // only for some platform doesn't have __sync_* 55 | // todo: check the result of pthread api 56 | 57 | struct rwlock { 58 | pthread_rwlock_t lock; 59 | }; 60 | 61 | static inline void 62 | rwlock_init(struct rwlock *lock) { 63 | pthread_rwlock_init(&lock->lock, NULL); 64 | } 65 | 66 | static inline void 67 | rwlock_rlock(struct rwlock *lock) { 68 | pthread_rwlock_rdlock(&lock->lock); 69 | } 70 | 71 | static inline void 72 | rwlock_wlock(struct rwlock *lock) { 73 | pthread_rwlock_wrlock(&lock->lock); 74 | } 75 | 76 | static inline void 77 | rwlock_wunlock(struct rwlock *lock) { 78 | pthread_rwlock_unlock(&lock->lock); 79 | } 80 | 81 | static inline void 82 | rwlock_runlock(struct rwlock *lock) { 83 | pthread_rwlock_unlock(&lock->lock); 84 | } 85 | 86 | #endif 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_H 2 | #define SKYNET_H 3 | 4 | #include "skynet_malloc.h" 5 | 6 | #include 7 | #include 8 | 9 | #define PTYPE_TEXT 0 10 | #define PTYPE_RESPONSE 1 11 | #define PTYPE_MULTICAST 2 12 | #define PTYPE_CLIENT 3 13 | #define PTYPE_SYSTEM 4 14 | #define PTYPE_HARBOR 5 15 | #define PTYPE_SOCKET 6 16 | // read lualib/skynet.lua examples/simplemonitor.lua 17 | #define PTYPE_ERROR 7 18 | // read lualib/skynet.lua lualib/mqueue.lua lualib/snax.lua 19 | #define PTYPE_RESERVED_QUEUE 8 20 | #define PTYPE_RESERVED_DEBUG 9 21 | #define PTYPE_RESERVED_LUA 10 22 | #define PTYPE_RESERVED_SNAX 11 23 | 24 | #define PTYPE_TAG_DONTCOPY 0x10000 25 | #define PTYPE_TAG_ALLOCSESSION 0x20000 26 | 27 | struct skynet_context; 28 | 29 | void skynet_error(struct skynet_context * context, const char *msg, ...); 30 | const char * skynet_command(struct skynet_context * context, const char * cmd , const char * parm); 31 | uint32_t skynet_queryname(struct skynet_context * context, const char * name); 32 | int skynet_send(struct skynet_context * context, uint32_t source, uint32_t destination , int type, int session, void * msg, size_t sz); 33 | int skynet_sendname(struct skynet_context * context, uint32_t source, const char * destination , int type, int session, void * msg, size_t sz); 34 | 35 | int skynet_isremote(struct skynet_context *, uint32_t handle, int * harbor); 36 | 37 | typedef int (*skynet_cb)(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz); 38 | void skynet_callback(struct skynet_context * context, void *ud, skynet_cb cb); 39 | 40 | uint32_t skynet_current_handle(void); 41 | uint64_t skynet_now(void); 42 | void skynet_debug_memory(const char *info); // for debug use, output current service memory to stderr 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_daemon.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "skynet_daemon.h" 10 | 11 | static int 12 | check_pid(const char *pidfile) { 13 | int pid = 0; 14 | FILE *f = fopen(pidfile,"r"); 15 | if (f == NULL) 16 | return 0; 17 | int n = fscanf(f,"%d", &pid); 18 | fclose(f); 19 | 20 | if (n !=1 || pid == 0 || pid == getpid()) { 21 | return 0; 22 | } 23 | 24 | if (kill(pid, 0) && errno == ESRCH) 25 | return 0; 26 | 27 | return pid; 28 | } 29 | 30 | static int 31 | write_pid(const char *pidfile) { 32 | FILE *f; 33 | int pid = 0; 34 | int fd = open(pidfile, O_RDWR|O_CREAT, 0644); 35 | if (fd == -1) { 36 | fprintf(stderr, "Can't create %s.\n", pidfile); 37 | return 0; 38 | } 39 | f = fdopen(fd, "r+"); 40 | if (f == NULL) { 41 | fprintf(stderr, "Can't open %s.\n", pidfile); 42 | return 0; 43 | } 44 | 45 | if (flock(fd, LOCK_EX|LOCK_NB) == -1) { 46 | int n = fscanf(f, "%d", &pid); 47 | fclose(f); 48 | if (n != 1) { 49 | fprintf(stderr, "Can't lock and read pidfile.\n"); 50 | } else { 51 | fprintf(stderr, "Can't lock pidfile, lock is held by pid %d.\n", pid); 52 | } 53 | return 0; 54 | } 55 | 56 | pid = getpid(); 57 | if (!fprintf(f,"%d\n", pid)) { 58 | fprintf(stderr, "Can't write pid.\n"); 59 | close(fd); 60 | return 0; 61 | } 62 | fflush(f); 63 | 64 | return pid; 65 | } 66 | 67 | int 68 | daemon_init(const char *pidfile) { 69 | int pid = check_pid(pidfile); 70 | 71 | if (pid) { 72 | fprintf(stderr, "Skynet is already running, pid = %d.\n", pid); 73 | return 1; 74 | } 75 | 76 | #ifdef __APPLE__ 77 | fprintf(stderr, "'daemon' is deprecated: first deprecated in OS X 10.5 , use launchd instead.\n"); 78 | #else 79 | if (daemon(1,0)) { 80 | fprintf(stderr, "Can't daemonize.\n"); 81 | return 1; 82 | } 83 | #endif 84 | 85 | pid = write_pid(pidfile); 86 | if (pid == 0) { 87 | return 1; 88 | } 89 | 90 | return 0; 91 | } 92 | 93 | int 94 | daemon_exit(const char *pidfile) { 95 | return unlink(pidfile); 96 | } 97 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_daemon.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_daemon_h 2 | #define skynet_daemon_h 3 | 4 | int daemon_init(const char *pidfile); 5 | int daemon_exit(const char *pidfile); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_env.c: -------------------------------------------------------------------------------- 1 | #include "skynet.h" 2 | #include "skynet_env.h" 3 | #include "spinlock.h" 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | struct skynet_env { 12 | struct spinlock lock; 13 | lua_State *L; 14 | }; 15 | 16 | static struct skynet_env *E = NULL; 17 | 18 | const char * 19 | skynet_getenv(const char *key) { 20 | SPIN_LOCK(E) 21 | 22 | lua_State *L = E->L; 23 | 24 | lua_getglobal(L, key); 25 | const char * result = lua_tostring(L, -1); 26 | lua_pop(L, 1); 27 | 28 | SPIN_UNLOCK(E) 29 | 30 | return result; 31 | } 32 | 33 | void 34 | skynet_setenv(const char *key, const char *value) { 35 | SPIN_LOCK(E) 36 | 37 | lua_State *L = E->L; 38 | lua_getglobal(L, key); 39 | assert(lua_isnil(L, -1)); 40 | lua_pop(L,1); 41 | lua_pushstring(L,value); 42 | lua_setglobal(L,key); 43 | 44 | SPIN_UNLOCK(E) 45 | } 46 | 47 | void 48 | skynet_env_init() { 49 | E = skynet_malloc(sizeof(*E)); 50 | SPIN_INIT(E) 51 | E->L = luaL_newstate(); 52 | } 53 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_env.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_ENV_H 2 | #define SKYNET_ENV_H 3 | 4 | const char * skynet_getenv(const char *key); 5 | void skynet_setenv(const char *key, const char *value); 6 | 7 | void skynet_env_init(); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_error.c: -------------------------------------------------------------------------------- 1 | #include "skynet.h" 2 | #include "skynet_handle.h" 3 | #include "skynet_mq.h" 4 | #include "skynet_server.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define LOG_MESSAGE_SIZE 256 12 | 13 | void 14 | skynet_error(struct skynet_context * context, const char *msg, ...) { 15 | static uint32_t logger = 0; 16 | if (logger == 0) { 17 | logger = skynet_handle_findname("logger"); 18 | } 19 | if (logger == 0) { 20 | return; 21 | } 22 | 23 | char tmp[LOG_MESSAGE_SIZE]; 24 | char *data = NULL; 25 | 26 | va_list ap; 27 | 28 | va_start(ap,msg); 29 | int len = vsnprintf(tmp, LOG_MESSAGE_SIZE, msg, ap); 30 | va_end(ap); 31 | if (len >=0 && len < LOG_MESSAGE_SIZE) { 32 | data = skynet_strdup(tmp); 33 | } else { 34 | int max_size = LOG_MESSAGE_SIZE; 35 | for (;;) { 36 | max_size *= 2; 37 | data = skynet_malloc(max_size); 38 | va_start(ap,msg); 39 | len = vsnprintf(data, max_size, msg, ap); 40 | va_end(ap); 41 | if (len < max_size) { 42 | break; 43 | } 44 | skynet_free(data); 45 | } 46 | } 47 | if (len < 0) { 48 | skynet_free(data); 49 | perror("vsnprintf error :"); 50 | return; 51 | } 52 | 53 | 54 | struct skynet_message smsg; 55 | if (context == NULL) { 56 | smsg.source = 0; 57 | } else { 58 | smsg.source = skynet_context_handle(context); 59 | } 60 | smsg.session = 0; 61 | smsg.data = data; 62 | smsg.sz = len | ((size_t)PTYPE_TEXT << MESSAGE_TYPE_SHIFT); 63 | skynet_context_push(logger, &smsg); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_handle.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_CONTEXT_HANDLE_H 2 | #define SKYNET_CONTEXT_HANDLE_H 3 | 4 | #include 5 | 6 | // reserve high 8 bits for remote id 7 | #define HANDLE_MASK 0xffffff 8 | #define HANDLE_REMOTE_SHIFT 24 9 | 10 | struct skynet_context; 11 | 12 | uint32_t skynet_handle_register(struct skynet_context *); 13 | int skynet_handle_retire(uint32_t handle); 14 | struct skynet_context * skynet_handle_grab(uint32_t handle); 15 | void skynet_handle_retireall(); 16 | 17 | uint32_t skynet_handle_findname(const char * name); 18 | const char * skynet_handle_namehandle(uint32_t handle, const char *name); 19 | 20 | void skynet_handle_init(int harbor); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_harbor.c: -------------------------------------------------------------------------------- 1 | #include "skynet.h" 2 | #include "skynet_harbor.h" 3 | #include "skynet_server.h" 4 | #include "skynet_mq.h" 5 | #include "skynet_handle.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | static struct skynet_context * REMOTE = 0; 12 | static unsigned int HARBOR = ~0; 13 | 14 | void 15 | skynet_harbor_send(struct remote_message *rmsg, uint32_t source, int session) { 16 | int type = rmsg->sz >> MESSAGE_TYPE_SHIFT; 17 | rmsg->sz &= MESSAGE_TYPE_MASK; 18 | assert(type != PTYPE_SYSTEM && type != PTYPE_HARBOR && REMOTE); 19 | skynet_context_send(REMOTE, rmsg, sizeof(*rmsg) , source, type , session); 20 | } 21 | 22 | int 23 | skynet_harbor_message_isremote(uint32_t handle) { 24 | assert(HARBOR != ~0); 25 | int h = (handle & ~HANDLE_MASK); 26 | return h != HARBOR && h !=0; 27 | } 28 | 29 | void 30 | skynet_harbor_init(int harbor) { 31 | HARBOR = (unsigned int)harbor << HANDLE_REMOTE_SHIFT; 32 | } 33 | 34 | void 35 | skynet_harbor_start(void *ctx) { 36 | // the HARBOR must be reserved to ensure the pointer is valid. 37 | // It will be released at last by calling skynet_harbor_exit 38 | skynet_context_reserve(ctx); 39 | REMOTE = ctx; 40 | } 41 | 42 | void 43 | skynet_harbor_exit() { 44 | struct skynet_context * ctx = REMOTE; 45 | REMOTE= NULL; 46 | if (ctx) { 47 | skynet_context_release(ctx); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_harbor.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_HARBOR_H 2 | #define SKYNET_HARBOR_H 3 | 4 | #include 5 | #include 6 | 7 | #define GLOBALNAME_LENGTH 16 8 | #define REMOTE_MAX 256 9 | 10 | struct remote_name { 11 | char name[GLOBALNAME_LENGTH]; 12 | uint32_t handle; 13 | }; 14 | 15 | struct remote_message { 16 | struct remote_name destination; 17 | const void * message; 18 | size_t sz; 19 | }; 20 | 21 | void skynet_harbor_send(struct remote_message *rmsg, uint32_t source, int session); 22 | int skynet_harbor_message_isremote(uint32_t handle); 23 | void skynet_harbor_init(int harbor); 24 | void skynet_harbor_start(void * ctx); 25 | void skynet_harbor_exit(); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_imp.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_IMP_H 2 | #define SKYNET_IMP_H 3 | 4 | struct skynet_config { 5 | int thread; 6 | int harbor; 7 | const char * daemon; 8 | const char * module_path; 9 | const char * bootstrap; 10 | const char * logger; 11 | const char * logservice; 12 | }; 13 | 14 | #define THREAD_WORKER 0 15 | #define THREAD_MAIN 1 16 | #define THREAD_SOCKET 2 17 | #define THREAD_TIMER 3 18 | #define THREAD_MONITOR 4 19 | 20 | void skynet_start(struct skynet_config * config); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_log.c: -------------------------------------------------------------------------------- 1 | #include "skynet_log.h" 2 | #include "skynet_timer.h" 3 | #include "skynet.h" 4 | #include "skynet_socket.h" 5 | #include 6 | #include 7 | 8 | FILE * 9 | skynet_log_open(struct skynet_context * ctx, uint32_t handle) { 10 | const char * logpath = skynet_getenv("logpath"); 11 | if (logpath == NULL) 12 | return NULL; 13 | size_t sz = strlen(logpath); 14 | char tmp[sz + 16]; 15 | sprintf(tmp, "%s/%08x.log", logpath, handle); 16 | FILE *f = fopen(tmp, "ab"); 17 | if (f) { 18 | uint32_t starttime = skynet_starttime(); 19 | uint64_t currenttime = skynet_now(); 20 | time_t ti = starttime + currenttime/100; 21 | skynet_error(ctx, "Open log file %s", tmp); 22 | fprintf(f, "open time: %u %s", (uint32_t)currenttime, ctime(&ti)); 23 | fflush(f); 24 | } else { 25 | skynet_error(ctx, "Open log file %s fail", tmp); 26 | } 27 | return f; 28 | } 29 | 30 | void 31 | skynet_log_close(struct skynet_context * ctx, FILE *f, uint32_t handle) { 32 | skynet_error(ctx, "Close log file :%08x", handle); 33 | fprintf(f, "close time: %u\n", (uint32_t)skynet_now()); 34 | fclose(f); 35 | } 36 | 37 | static void 38 | log_blob(FILE *f, void * buffer, size_t sz) { 39 | size_t i; 40 | uint8_t * buf = buffer; 41 | for (i=0;i!=sz;i++) { 42 | fprintf(f, "%02x", buf[i]); 43 | } 44 | } 45 | 46 | static void 47 | log_socket(FILE * f, struct skynet_socket_message * message, size_t sz) { 48 | fprintf(f, "[socket] %d %d %d ", message->type, message->id, message->ud); 49 | 50 | if (message->buffer == NULL) { 51 | const char *buffer = (const char *)(message + 1); 52 | sz -= sizeof(*message); 53 | const char * eol = memchr(buffer, '\0', sz); 54 | if (eol) { 55 | sz = eol - buffer; 56 | } 57 | fprintf(f, "[%*s]", (int)sz, (const char *)buffer); 58 | } else { 59 | sz = message->ud; 60 | log_blob(f, message->buffer, sz); 61 | } 62 | fprintf(f, "\n"); 63 | fflush(f); 64 | } 65 | 66 | void 67 | skynet_log_output(FILE *f, uint32_t source, int type, int session, void * buffer, size_t sz) { 68 | if (type == PTYPE_SOCKET) { 69 | log_socket(f, buffer, sz); 70 | } else { 71 | uint32_t ti = (uint32_t)skynet_now(); 72 | fprintf(f, ":%08x %d %d %u ", source, type, session, ti); 73 | log_blob(f, buffer, sz); 74 | fprintf(f,"\n"); 75 | fflush(f); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_log.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_log_h 2 | #define skynet_log_h 3 | 4 | #include "skynet_env.h" 5 | #include "skynet.h" 6 | 7 | #include 8 | #include 9 | 10 | FILE * skynet_log_open(struct skynet_context * ctx, uint32_t handle); 11 | void skynet_log_close(struct skynet_context * ctx, FILE *f, uint32_t handle); 12 | void skynet_log_output(FILE *f, uint32_t source, int type, int session, void * buffer, size_t sz); 13 | 14 | #endif -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_malloc_h 2 | #define skynet_malloc_h 3 | 4 | #include 5 | 6 | #define skynet_malloc malloc 7 | #define skynet_calloc calloc 8 | #define skynet_realloc realloc 9 | #define skynet_free free 10 | 11 | void * skynet_malloc(size_t sz); 12 | void * skynet_calloc(size_t nmemb,size_t size); 13 | void * skynet_realloc(void *ptr, size_t size); 14 | void skynet_free(void *ptr); 15 | char * skynet_strdup(const char *str); 16 | void * skynet_lalloc(void *ptr, size_t osize, size_t nsize); // use for lua 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_module.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_MODULE_H 2 | #define SKYNET_MODULE_H 3 | 4 | struct skynet_context; 5 | 6 | typedef void * (*skynet_dl_create)(void); 7 | typedef int (*skynet_dl_init)(void * inst, struct skynet_context *, const char * parm); 8 | typedef void (*skynet_dl_release)(void * inst); 9 | typedef void (*skynet_dl_signal)(void * inst, int signal); 10 | 11 | struct skynet_module { 12 | const char * name; 13 | void * module; 14 | skynet_dl_create create; 15 | skynet_dl_init init; 16 | skynet_dl_release release; 17 | skynet_dl_signal signal; 18 | }; 19 | 20 | void skynet_module_insert(struct skynet_module *mod); 21 | struct skynet_module * skynet_module_query(const char * name); 22 | void * skynet_module_instance_create(struct skynet_module *); 23 | int skynet_module_instance_init(struct skynet_module *, void * inst, struct skynet_context *ctx, const char * parm); 24 | void skynet_module_instance_release(struct skynet_module *, void *inst); 25 | void skynet_module_instance_signal(struct skynet_module *, void *inst, int signal); 26 | 27 | void skynet_module_init(const char *path); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_monitor.c: -------------------------------------------------------------------------------- 1 | #include "skynet.h" 2 | 3 | #include "skynet_monitor.h" 4 | #include "skynet_server.h" 5 | #include "skynet.h" 6 | #include "atomic.h" 7 | 8 | #include 9 | #include 10 | 11 | struct skynet_monitor { 12 | int version; 13 | int check_version; 14 | uint32_t source; 15 | uint32_t destination; 16 | }; 17 | 18 | struct skynet_monitor * 19 | skynet_monitor_new() { 20 | struct skynet_monitor * ret = skynet_malloc(sizeof(*ret)); 21 | memset(ret, 0, sizeof(*ret)); 22 | return ret; 23 | } 24 | 25 | void 26 | skynet_monitor_delete(struct skynet_monitor *sm) { 27 | skynet_free(sm); 28 | } 29 | 30 | void 31 | skynet_monitor_trigger(struct skynet_monitor *sm, uint32_t source, uint32_t destination) { 32 | sm->source = source; 33 | sm->destination = destination; 34 | ATOM_INC(&sm->version); 35 | } 36 | 37 | void 38 | skynet_monitor_check(struct skynet_monitor *sm) { 39 | if (sm->version == sm->check_version) { 40 | if (sm->destination) { 41 | skynet_context_endless(sm->destination); 42 | skynet_error(NULL, "A message from [ :%08x ] to [ :%08x ] maybe in an endless loop (version = %d)", sm->source , sm->destination, sm->version); 43 | } 44 | } else { 45 | sm->check_version = sm->version; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_monitor.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_MONITOR_H 2 | #define SKYNET_MONITOR_H 3 | 4 | #include 5 | 6 | struct skynet_monitor; 7 | 8 | struct skynet_monitor * skynet_monitor_new(); 9 | void skynet_monitor_delete(struct skynet_monitor *); 10 | void skynet_monitor_trigger(struct skynet_monitor *, uint32_t source, uint32_t destination); 11 | void skynet_monitor_check(struct skynet_monitor *); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_mq.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_MESSAGE_QUEUE_H 2 | #define SKYNET_MESSAGE_QUEUE_H 3 | 4 | #include 5 | #include 6 | 7 | struct skynet_message { 8 | uint32_t source; 9 | int session; 10 | void * data; 11 | size_t sz; 12 | }; 13 | 14 | // type is encoding in skynet_message.sz high 8bit 15 | #define MESSAGE_TYPE_MASK (SIZE_MAX >> 8) 16 | #define MESSAGE_TYPE_SHIFT ((sizeof(size_t)-1) * 8) 17 | 18 | struct message_queue; 19 | 20 | void skynet_globalmq_push(struct message_queue * queue); 21 | struct message_queue * skynet_globalmq_pop(void); 22 | 23 | struct message_queue * skynet_mq_create(uint32_t handle); 24 | void skynet_mq_mark_release(struct message_queue *q); 25 | 26 | typedef void (*message_drop)(struct skynet_message *, void *); 27 | 28 | void skynet_mq_release(struct message_queue *q, message_drop drop_func, void *ud); 29 | uint32_t skynet_mq_handle(struct message_queue *); 30 | 31 | // 0 for success 32 | int skynet_mq_pop(struct message_queue *q, struct skynet_message *message); 33 | void skynet_mq_push(struct message_queue *q, struct skynet_message *message); 34 | 35 | // return the length of message queue, for debug 36 | int skynet_mq_length(struct message_queue *q); 37 | int skynet_mq_overload(struct message_queue *q); 38 | 39 | void skynet_mq_init(); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_server.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_SERVER_H 2 | #define SKYNET_SERVER_H 3 | 4 | #include 5 | #include 6 | 7 | struct skynet_context; 8 | struct skynet_message; 9 | struct skynet_monitor; 10 | 11 | struct skynet_context * skynet_context_new(const char * name, const char * parm); 12 | void skynet_context_grab(struct skynet_context *); 13 | void skynet_context_reserve(struct skynet_context *ctx); 14 | struct skynet_context * skynet_context_release(struct skynet_context *); 15 | uint32_t skynet_context_handle(struct skynet_context *); 16 | int skynet_context_push(uint32_t handle, struct skynet_message *message); 17 | void skynet_context_send(struct skynet_context * context, void * msg, size_t sz, uint32_t source, int type, int session); 18 | int skynet_context_newsession(struct skynet_context *); 19 | struct message_queue * skynet_context_message_dispatch(struct skynet_monitor *, struct message_queue *, int weight); // return next queue 20 | int skynet_context_total(); 21 | void skynet_context_dispatchall(struct skynet_context * context); // for skynet_error output before exit 22 | 23 | void skynet_context_endless(uint32_t handle); // for monitor 24 | 25 | void skynet_globalinit(void); 26 | void skynet_globalexit(void); 27 | void skynet_initthread(int m); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_socket.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_socket_h 2 | #define skynet_socket_h 3 | 4 | struct skynet_context; 5 | 6 | #define SKYNET_SOCKET_TYPE_DATA 1 7 | #define SKYNET_SOCKET_TYPE_CONNECT 2 8 | #define SKYNET_SOCKET_TYPE_CLOSE 3 9 | #define SKYNET_SOCKET_TYPE_ACCEPT 4 10 | #define SKYNET_SOCKET_TYPE_ERROR 5 11 | #define SKYNET_SOCKET_TYPE_UDP 6 12 | #define SKYNET_SOCKET_TYPE_WARNING 7 13 | 14 | struct skynet_socket_message { 15 | int type; 16 | int id; 17 | int ud; 18 | char * buffer; 19 | }; 20 | 21 | void skynet_socket_init(); 22 | void skynet_socket_exit(); 23 | void skynet_socket_free(); 24 | int skynet_socket_poll(); 25 | 26 | int skynet_socket_send(struct skynet_context *ctx, int id, void *buffer, int sz); 27 | void skynet_socket_send_lowpriority(struct skynet_context *ctx, int id, void *buffer, int sz); 28 | int skynet_socket_listen(struct skynet_context *ctx, const char *host, int port, int backlog); 29 | int skynet_socket_connect(struct skynet_context *ctx, const char *host, int port); 30 | int skynet_socket_bind(struct skynet_context *ctx, int fd); 31 | void skynet_socket_close(struct skynet_context *ctx, int id); 32 | void skynet_socket_shutdown(struct skynet_context *ctx, int id); 33 | void skynet_socket_start(struct skynet_context *ctx, int id); 34 | void skynet_socket_nodelay(struct skynet_context *ctx, int id); 35 | 36 | int skynet_socket_udp(struct skynet_context *ctx, const char * addr, int port); 37 | int skynet_socket_udp_connect(struct skynet_context *ctx, int id, const char * addr, int port); 38 | int skynet_socket_udp_send(struct skynet_context *ctx, int id, const char * address, const void *buffer, int sz); 39 | const char * skynet_socket_udp_address(struct skynet_socket_message *, int *addrsz); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /skynet/skynet-src/skynet_timer.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_TIMER_H 2 | #define SKYNET_TIMER_H 3 | 4 | #include 5 | 6 | int skynet_timeout(uint32_t handle, int time, int session); 7 | void skynet_updatetime(void); 8 | uint32_t skynet_starttime(void); 9 | 10 | void skynet_timer_init(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /skynet/skynet-src/socket_epoll.h: -------------------------------------------------------------------------------- 1 | #ifndef poll_socket_epoll_h 2 | #define poll_socket_epoll_h 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static bool 14 | sp_invalid(int efd) { 15 | return efd == -1; 16 | } 17 | 18 | static int 19 | sp_create() { 20 | return epoll_create(1024); 21 | } 22 | 23 | static void 24 | sp_release(int efd) { 25 | close(efd); 26 | } 27 | 28 | static int 29 | sp_add(int efd, int sock, void *ud) { 30 | struct epoll_event ev; 31 | ev.events = EPOLLIN; 32 | ev.data.ptr = ud; 33 | if (epoll_ctl(efd, EPOLL_CTL_ADD, sock, &ev) == -1) { 34 | return 1; 35 | } 36 | return 0; 37 | } 38 | 39 | static void 40 | sp_del(int efd, int sock) { 41 | epoll_ctl(efd, EPOLL_CTL_DEL, sock , NULL); 42 | } 43 | 44 | static void 45 | sp_write(int efd, int sock, void *ud, bool enable) { 46 | struct epoll_event ev; 47 | ev.events = EPOLLIN | (enable ? EPOLLOUT : 0); 48 | ev.data.ptr = ud; 49 | epoll_ctl(efd, EPOLL_CTL_MOD, sock, &ev); 50 | } 51 | 52 | static int 53 | sp_wait(int efd, struct event *e, int max) { 54 | struct epoll_event ev[max]; 55 | int n = epoll_wait(efd , ev, max, -1); 56 | int i; 57 | for (i=0;i 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static bool 14 | sp_invalid(int kfd) { 15 | return kfd == -1; 16 | } 17 | 18 | static int 19 | sp_create() { 20 | return kqueue(); 21 | } 22 | 23 | static void 24 | sp_release(int kfd) { 25 | close(kfd); 26 | } 27 | 28 | static void 29 | sp_del(int kfd, int sock) { 30 | struct kevent ke; 31 | EV_SET(&ke, sock, EVFILT_READ, EV_DELETE, 0, 0, NULL); 32 | kevent(kfd, &ke, 1, NULL, 0, NULL); 33 | EV_SET(&ke, sock, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); 34 | kevent(kfd, &ke, 1, NULL, 0, NULL); 35 | } 36 | 37 | static int 38 | sp_add(int kfd, int sock, void *ud) { 39 | struct kevent ke; 40 | EV_SET(&ke, sock, EVFILT_READ, EV_ADD, 0, 0, ud); 41 | if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1) { 42 | return 1; 43 | } 44 | EV_SET(&ke, sock, EVFILT_WRITE, EV_ADD, 0, 0, ud); 45 | if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1) { 46 | EV_SET(&ke, sock, EVFILT_READ, EV_DELETE, 0, 0, NULL); 47 | kevent(kfd, &ke, 1, NULL, 0, NULL); 48 | return 1; 49 | } 50 | EV_SET(&ke, sock, EVFILT_WRITE, EV_DISABLE, 0, 0, ud); 51 | if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1) { 52 | sp_del(kfd, sock); 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | 58 | static void 59 | sp_write(int kfd, int sock, void *ud, bool enable) { 60 | struct kevent ke; 61 | EV_SET(&ke, sock, EVFILT_WRITE, enable ? EV_ENABLE : EV_DISABLE, 0, 0, ud); 62 | if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1) { 63 | // todo: check error 64 | } 65 | } 66 | 67 | static int 68 | sp_wait(int kfd, struct event *e, int max) { 69 | struct kevent ev[max]; 70 | int n = kevent(kfd, NULL, 0, ev, max, NULL); 71 | 72 | int i; 73 | for (i=0;i 5 | 6 | typedef int poll_fd; 7 | 8 | struct event { 9 | void * s; 10 | bool read; 11 | bool write; 12 | }; 13 | 14 | static bool sp_invalid(poll_fd fd); 15 | static poll_fd sp_create(); 16 | static void sp_release(poll_fd fd); 17 | static int sp_add(poll_fd fd, int sock, void *ud); 18 | static void sp_del(poll_fd fd, int sock); 19 | static void sp_write(poll_fd, int sock, void *ud, bool enable); 20 | static int sp_wait(poll_fd, struct event *e, int max); 21 | static void sp_nonblocking(int sock); 22 | 23 | #ifdef __linux__ 24 | #include "socket_epoll.h" 25 | #endif 26 | 27 | #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__) 28 | #include "socket_kqueue.h" 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /skynet/skynet-src/spinlock.h: -------------------------------------------------------------------------------- 1 | #ifndef SKYNET_SPINLOCK_H 2 | #define SKYNET_SPINLOCK_H 3 | 4 | #define SPIN_INIT(q) spinlock_init(&(q)->lock); 5 | #define SPIN_LOCK(q) spinlock_lock(&(q)->lock); 6 | #define SPIN_UNLOCK(q) spinlock_unlock(&(q)->lock); 7 | #define SPIN_DESTROY(q) spinlock_destroy(&(q)->lock); 8 | 9 | #ifndef USE_PTHREAD_LOCK 10 | 11 | struct spinlock { 12 | int lock; 13 | }; 14 | 15 | static inline void 16 | spinlock_init(struct spinlock *lock) { 17 | lock->lock = 0; 18 | } 19 | 20 | static inline void 21 | spinlock_lock(struct spinlock *lock) { 22 | while (__sync_lock_test_and_set(&lock->lock,1)) {} 23 | } 24 | 25 | static inline int 26 | spinlock_trylock(struct spinlock *lock) { 27 | return __sync_lock_test_and_set(&lock->lock,1) == 0; 28 | } 29 | 30 | static inline void 31 | spinlock_unlock(struct spinlock *lock) { 32 | __sync_lock_release(&lock->lock); 33 | } 34 | 35 | static inline void 36 | spinlock_destroy(struct spinlock *lock) { 37 | (void) lock; 38 | } 39 | 40 | #else 41 | 42 | #include 43 | 44 | // we use mutex instead of spinlock for some reason 45 | // you can also replace to pthread_spinlock 46 | 47 | struct spinlock { 48 | pthread_mutex_t lock; 49 | }; 50 | 51 | static inline void 52 | spinlock_init(struct spinlock *lock) { 53 | pthread_mutex_init(&lock->lock, NULL); 54 | } 55 | 56 | static inline void 57 | spinlock_lock(struct spinlock *lock) { 58 | pthread_mutex_lock(&lock->lock); 59 | } 60 | 61 | static inline int 62 | spinlock_trylock(struct spinlock *lock) { 63 | return pthread_mutex_trylock(&lock->lock) == 0; 64 | } 65 | 66 | static inline void 67 | spinlock_unlock(struct spinlock *lock) { 68 | pthread_mutex_unlock(&lock->lock); 69 | } 70 | 71 | static inline void 72 | spinlock_destroy(struct spinlock *lock) { 73 | pthread_mutex_destroy(&lock->lock); 74 | } 75 | 76 | #endif 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /skynet/test/pingserver.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local queue = require "skynet.queue" 3 | local snax = require "snax" 4 | 5 | local i = 0 6 | local hello = "hello" 7 | 8 | function response.ping(hello) 9 | skynet.sleep(100) 10 | return hello 11 | end 12 | 13 | -- response.sleep and accept.hello share one lock 14 | local lock 15 | 16 | function accept.sleep(queue, n) 17 | if queue then 18 | lock( 19 | function() 20 | print("queue=",queue, n) 21 | skynet.sleep(n) 22 | end) 23 | else 24 | print("queue=",queue, n) 25 | skynet.sleep(n) 26 | end 27 | end 28 | 29 | function accept.hello() 30 | lock(function() 31 | i = i + 1 32 | print (i, hello) 33 | end) 34 | end 35 | 36 | function accept.exit(...) 37 | snax.exit(...) 38 | end 39 | 40 | function response.error() 41 | error "throw an error" 42 | end 43 | 44 | function init( ... ) 45 | print ("ping server start:", ...) 46 | snax.enablecluster() -- enable cluster call 47 | -- init queue 48 | lock = queue() 49 | end 50 | 51 | function exit(...) 52 | print ("ping server exit:", ...) 53 | end 54 | -------------------------------------------------------------------------------- /skynet/test/sharemap.sp: -------------------------------------------------------------------------------- 1 | .foobar { 2 | x 0 : integer 3 | y 1 : integer 4 | s 2 : string 5 | } 6 | -------------------------------------------------------------------------------- /skynet/test/testbson.lua: -------------------------------------------------------------------------------- 1 | local bson = require "bson" 2 | 3 | sub = bson.encode_order( "hello", 1, "world", 2 ) 4 | 5 | local function tbl_next(...) 6 | print("--- next.a", ...) 7 | local k, v = next(...) 8 | print("--- next.b", k, v) 9 | return k, v 10 | end 11 | 12 | local function tbl_pairs(obj) 13 | return tbl_next, obj.__data, nil 14 | end 15 | 16 | local obj_a = { 17 | __data = { 18 | [1] = 2, 19 | [3] = 4, 20 | [5] = 6, 21 | } 22 | } 23 | 24 | setmetatable( 25 | obj_a, 26 | { 27 | __index = obj_a.__data, 28 | __pairs = tbl_pairs, 29 | } 30 | ) 31 | 32 | local obj_b = { 33 | __data = { 34 | [7] = 8, 35 | [9] = 10, 36 | [11] = obj_a, 37 | } 38 | } 39 | 40 | setmetatable( 41 | obj_b, 42 | { 43 | __index = obj_b.__data, 44 | __pairs = tbl_pairs, 45 | } 46 | ) 47 | 48 | local metaarray = setmetatable({ n = 5 }, { 49 | __len = function(self) return self.n end, 50 | __index = function(self, idx) return tostring(idx) end, 51 | }) 52 | 53 | b = bson.encode { 54 | a = 1, 55 | b = true, 56 | c = bson.null, 57 | d = { 1,2,3,4 }, 58 | e = bson.binary "hello", 59 | f = bson.regex ("*","i"), 60 | g = bson.regex "hello", 61 | h = bson.date (os.time()), 62 | i = bson.timestamp(os.time()), 63 | j = bson.objectid(), 64 | k = { a = false, b = true }, 65 | l = {}, 66 | m = bson.minkey, 67 | n = bson.maxkey, 68 | o = sub, 69 | p = 2^32-1, 70 | q = obj_b, 71 | r = metaarray, 72 | } 73 | 74 | print "\n[before replace]" 75 | t = b:decode() 76 | 77 | for k, v in pairs(t) do 78 | print(k,type(v)) 79 | end 80 | 81 | for k,v in ipairs(t.r) do 82 | print(k,v) 83 | end 84 | 85 | b:makeindex() 86 | b.a = 2 87 | b.b = false 88 | b.h = bson.date(os.time()) 89 | b.i = bson.timestamp(os.time()) 90 | b.j = bson.objectid() 91 | 92 | print "\n[after replace]" 93 | t = b:decode() 94 | 95 | print("o.hello", bson.type(t.o.hello)) 96 | -------------------------------------------------------------------------------- /skynet/test/testcoroutine.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | -- You should use skynet.coroutine instead of origin coroutine in skynet 3 | local coroutine = require "skynet.coroutine" 4 | local profile = require "profile" 5 | 6 | local function status(co) 7 | repeat 8 | local status = coroutine.status(co) 9 | print("STATUS", status) 10 | skynet.sleep(100) 11 | until status == "suspended" 12 | 13 | repeat 14 | local ok, n = assert(coroutine.resume(co)) 15 | print("status thread", n) 16 | until not n 17 | skynet.exit() 18 | end 19 | 20 | local function test(n) 21 | local co = coroutine.running() 22 | print ("begin", co, coroutine.thread(co)) -- false 23 | skynet.fork(status, co) 24 | for i=1,n do 25 | skynet.sleep(100) 26 | coroutine.yield(i) 27 | end 28 | print ("end", co) 29 | end 30 | 31 | local function main() 32 | local f = coroutine.wrap(test) 33 | coroutine.yield "begin" 34 | for i=1,3 do 35 | local n = f(5) 36 | print("main thread",n) 37 | end 38 | coroutine.yield "end" 39 | print("main thread time:", profile.stop(coroutine.thread())) 40 | end 41 | 42 | skynet.start(function() 43 | print("Main thead :", coroutine.thread()) -- true 44 | print(coroutine.resume(coroutine.running())) -- always return false 45 | 46 | profile.start() 47 | 48 | local f = coroutine.wrap(main) 49 | print("main step", f()) 50 | print("main step", f()) 51 | print("main step", f()) 52 | -- print("main thread time:", profile.stop()) 53 | end) 54 | -------------------------------------------------------------------------------- /skynet/test/testdatacenter.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local datacenter = require "datacenter" 3 | 4 | local function f1() 5 | print("====1==== wait hello") 6 | print("\t1>",datacenter.wait ("hello")) 7 | print("====1==== wait key.foobar") 8 | print("\t1>", pcall(datacenter.wait,"key")) -- will failed, because "key" is a branch 9 | print("\t1>",datacenter.wait ("key", "foobar")) 10 | end 11 | 12 | local function f2() 13 | skynet.sleep(10) 14 | print("====2==== set key.foobar") 15 | datacenter.set("key", "foobar", "bingo") 16 | end 17 | 18 | skynet.start(function() 19 | datacenter.set("hello", "world") 20 | print(datacenter.get "hello") 21 | skynet.fork(f1) 22 | skynet.fork(f2) 23 | end) 24 | -------------------------------------------------------------------------------- /skynet/test/testdeadcall.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local mode = ... 4 | 5 | if mode == "test" then 6 | 7 | skynet.start(function() 8 | skynet.dispatch("lua", function (...) 9 | print("====>", ...) 10 | skynet.exit() 11 | end) 12 | end) 13 | 14 | elseif mode == "dead" then 15 | 16 | skynet.start(function() 17 | skynet.dispatch("lua", function (...) 18 | skynet.sleep(100) 19 | print("return", skynet.ret "") 20 | end) 21 | end) 22 | 23 | else 24 | 25 | skynet.start(function() 26 | local test = skynet.newservice(SERVICE_NAME, "test") -- launch self in test mode 27 | 28 | print(pcall(function() 29 | skynet.call(test,"lua", "dead call") 30 | end)) 31 | 32 | local dead = skynet.newservice(SERVICE_NAME, "dead") -- launch self in dead mode 33 | 34 | skynet.timeout(0, skynet.exit) -- exit after a while, so the call never return 35 | skynet.call(dead, "lua", "whould not return") 36 | end) 37 | end 38 | -------------------------------------------------------------------------------- /skynet/test/testdeadloop.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local function dead_loop() 3 | while true do 4 | skynet.sleep(0) 5 | end 6 | end 7 | 8 | skynet.start(function() 9 | skynet.fork(dead_loop) 10 | end) 11 | -------------------------------------------------------------------------------- /skynet/test/testdns.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local dns = require "dns" 3 | 4 | skynet.start(function() 5 | print("nameserver:", dns.server()) -- set nameserver 6 | -- you can specify the server like dns.server("8.8.4.4", 53) 7 | local ip, ips = dns.resolve "github.com" 8 | for k,v in ipairs(ips) do 9 | print("github.com",v) 10 | end 11 | end) 12 | -------------------------------------------------------------------------------- /skynet/test/testecho.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local mode = ... 4 | 5 | if mode == "slave" then 6 | 7 | skynet.start(function() 8 | skynet.dispatch("lua", function(_,_, ...) 9 | skynet.ret(skynet.pack(...)) 10 | end) 11 | end) 12 | 13 | else 14 | 15 | skynet.start(function() 16 | local slave = skynet.newservice(SERVICE_NAME, "slave") 17 | local n = 100000 18 | local start = skynet.now() 19 | print("call salve", n, "times in queue") 20 | for i=1,n do 21 | skynet.call(slave, "lua") 22 | end 23 | print("qps = ", n/ (skynet.now() - start) * 100) 24 | 25 | start = skynet.now() 26 | 27 | local worker = 10 28 | local task = n/worker 29 | print("call salve", n, "times in parallel, worker = ", worker) 30 | 31 | for i=1,worker do 32 | skynet.fork(function() 33 | for i=1,task do 34 | skynet.call(slave, "lua") 35 | end 36 | worker = worker -1 37 | if worker == 0 then 38 | print("qps = ", n/ (skynet.now() - start) * 100) 39 | end 40 | end) 41 | end 42 | end) 43 | 44 | end 45 | -------------------------------------------------------------------------------- /skynet/test/testharborlink.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local harbor = require "skynet.harbor" 3 | 4 | skynet.start(function() 5 | print("wait for harbor 2") 6 | print("run skynet examples/config_log please") 7 | harbor.connect(2) 8 | print("harbor 2 connected") 9 | print("LOG =", skynet.address(harbor.queryname "LOG")) 10 | harbor.link(2) 11 | print("disconnected") 12 | end) 13 | -------------------------------------------------------------------------------- /skynet/test/testhttp.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local httpc = require "http.httpc" 3 | local dns = require "dns" 4 | 5 | skynet.start(function() 6 | httpc.dns() -- set dns server 7 | print("GET baidu.com") 8 | local respheader = {} 9 | local status, body = httpc.get("baidu.com", "/", respheader) 10 | print("[header] =====>") 11 | for k,v in pairs(respheader) do 12 | print(k,v) 13 | end 14 | print("[body] =====>", status) 15 | print(body) 16 | 17 | local respheader = {} 18 | dns.server() 19 | local ip = dns.resolve "baidu.com" 20 | print(string.format("GET %s (baidu.com)", ip)) 21 | local status, body = httpc.get("baidu.com", "/", respheader, { host = "baidu.com" }) 22 | print(status) 23 | 24 | skynet.exit() 25 | end) 26 | -------------------------------------------------------------------------------- /skynet/test/testmemlimit.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local names = {"cluster", "dns", "mongo", "mysql", "redis", "sharedata", "socket", "sproto"} 4 | 5 | -- set sandbox memory limit to 1M, must set here (at start, out of skynet.start) 6 | skynet.memlimit(1 * 1024 * 1024) 7 | 8 | skynet.start(function() 9 | local a = {} 10 | local limit 11 | local ok, err = pcall(function() 12 | for i=1, 12355 do 13 | limit = i 14 | table.insert(a, {}) 15 | end 16 | end) 17 | local libs = {} 18 | for k,v in ipairs(names) do 19 | local ok, m = pcall(require, v) 20 | if ok then 21 | libs[v] = m 22 | end 23 | end 24 | skynet.error(limit, err) 25 | skynet.exit() 26 | end) 27 | -------------------------------------------------------------------------------- /skynet/test/testmulticast.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local mc = require "multicast" 3 | local dc = require "datacenter" 4 | 5 | local mode = ... 6 | 7 | if mode == "sub" then 8 | 9 | skynet.start(function() 10 | skynet.dispatch("lua", function (_,_, cmd, channel) 11 | assert(cmd == "init") 12 | local c = mc.new { 13 | channel = channel , 14 | dispatch = function (channel, source, ...) 15 | print(string.format("%s <=== %s %s",skynet.address(skynet.self()),skynet.address(source), channel), ...) 16 | end 17 | } 18 | print(skynet.address(skynet.self()), "sub", c) 19 | c:subscribe() 20 | skynet.ret(skynet.pack()) 21 | end) 22 | end) 23 | 24 | else 25 | 26 | skynet.start(function() 27 | local channel = mc.new() 28 | print("New channel", channel) 29 | for i=1,10 do 30 | local sub = skynet.newservice(SERVICE_NAME, "sub") 31 | skynet.call(sub, "lua", "init", channel.channel) 32 | end 33 | 34 | dc.set("MCCHANNEL", channel.channel) -- for multi node test 35 | 36 | print(skynet.address(skynet.self()), "===>", channel) 37 | channel:publish("Hello World") 38 | end) 39 | 40 | end -------------------------------------------------------------------------------- /skynet/test/testmulticast2.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local dc = require "datacenter" 3 | local mc = require "multicast" 4 | 5 | skynet.start(function() 6 | print("remote start") 7 | local console = skynet.newservice("console") 8 | local channel = dc.get "MCCHANNEL" 9 | if channel then 10 | print("remote channel", channel) 11 | else 12 | print("create local channel") 13 | end 14 | for i=1,10 do 15 | local sub = skynet.newservice("testmulticast", "sub") 16 | skynet.call(sub, "lua", "init", channel) 17 | end 18 | local c = mc.new { 19 | channel = channel , 20 | dispatch = function(...) print("======>", ...) end, 21 | } 22 | c:subscribe() 23 | c:publish("Remote message") 24 | c:unsubscribe() 25 | c:publish("Remote message2") 26 | c:delete() 27 | skynet.exit() 28 | end) 29 | -------------------------------------------------------------------------------- /skynet/test/testoverload.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local mode = ... 4 | 5 | if mode == "slave" then 6 | 7 | local CMD = {} 8 | 9 | function CMD.sum(n) 10 | skynet.error("for loop begin") 11 | local s = 0 12 | for i = 1, n do 13 | s = s + i 14 | end 15 | skynet.error("for loop end") 16 | end 17 | 18 | function CMD.blackhole() 19 | end 20 | 21 | skynet.start(function() 22 | skynet.dispatch("lua", function(_,_, cmd, ...) 23 | local f = CMD[cmd] 24 | f(...) 25 | end) 26 | end) 27 | 28 | else 29 | 30 | skynet.start(function() 31 | local slave = skynet.newservice(SERVICE_NAME, "slave") 32 | for step = 1, 20 do 33 | skynet.error("overload test ".. step) 34 | for i = 1, 512 * step do 35 | skynet.send(slave, "lua", "blackhole") 36 | end 37 | skynet.sleep(step) 38 | end 39 | local n = 1000000000 40 | skynet.error(string.format("endless test n=%d", n)) 41 | skynet.send(slave, "lua", "sum", n) 42 | end) 43 | 44 | end 45 | -------------------------------------------------------------------------------- /skynet/test/testping.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local snax = require "snax" 3 | 4 | skynet.start(function() 5 | local ps = snax.newservice ("pingserver", "hello world") 6 | print(ps.req.ping("foobar")) 7 | print(ps.post.hello()) 8 | print(pcall(ps.req.error)) 9 | print("Hotfix (i) :", snax.hotfix(ps, [[ 10 | 11 | local i 12 | local hello 13 | 14 | function accept.hello() 15 | i = i + 1 16 | print ("fix", i, hello) 17 | end 18 | 19 | function hotfix(...) 20 | local temp = i 21 | i = 100 22 | return temp 23 | end 24 | 25 | ]])) 26 | print(ps.post.hello()) 27 | 28 | local info = skynet.call(ps.handle, "debug", "INFO") 29 | 30 | for name,v in pairs(info) do 31 | print(string.format("%s\tcount:%d time:%f", name, v.count, v.time)) 32 | end 33 | 34 | print(ps.post.exit("exit")) -- == snax.kill(ps, "exit") 35 | skynet.exit() 36 | end) 37 | -------------------------------------------------------------------------------- /skynet/test/testpipeline.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local redis = require "redis" 3 | 4 | local conf = { 5 | host = "127.0.0.1", 6 | port = 6379, 7 | db = 0 8 | } 9 | 10 | local function read_table(t) 11 | local result = { } 12 | for i = 1, #t, 2 do result[t[i]] = t[i + 1] end 13 | return result 14 | end 15 | 16 | skynet.start(function() 17 | local db = redis.connect(conf) 18 | 19 | db.pipelining = function (self, block) 20 | local ops = {} 21 | 22 | block(setmetatable({}, { 23 | __index = function (_, name) 24 | return function (_, ...) 25 | table.insert(ops, {name, ...}) 26 | end 27 | end 28 | })) 29 | 30 | return self:pipeline(ops) 31 | end 32 | 33 | do 34 | print("test function") 35 | local ret = db:pipelining(function (red) 36 | red:multi() 37 | red:hincrby("hello", 1, 1) 38 | red:del("hello") 39 | red:hmset("hello", 1, 1, 2, 2, 3, 3) 40 | red:hgetall("hello") 41 | red:exec() 42 | end) 43 | -- ret is the result of red:exec() 44 | for k, v in pairs(read_table(ret[4])) do 45 | print(k, v) 46 | end 47 | end 48 | 49 | do 50 | print("test table") 51 | local ret = db:pipeline({ 52 | {"hincrby", "hello", 1, 1}, 53 | {"del", "hello"}, 54 | {"hmset", "hello", 1, 1, 2, 2, 3, 3}, 55 | {"hgetall", "hello"}, 56 | }, {}) -- offer a {} for result 57 | 58 | print(ret[1].out) 59 | print(ret[2].out) 60 | print(ret[3].out) 61 | 62 | for k, v in pairs(read_table(ret[4].out)) do 63 | print(k, v) 64 | end 65 | end 66 | 67 | db:disconnect() 68 | skynet.exit() 69 | end) 70 | 71 | -------------------------------------------------------------------------------- /skynet/test/testqueue.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local snax = require "snax" 3 | 4 | skynet.start(function() 5 | local ps = snax.uniqueservice ("pingserver", "test queue") 6 | for i=1, 10 do 7 | ps.post.sleep(true,i*10) 8 | ps.post.hello() 9 | end 10 | for i=1, 10 do 11 | ps.post.sleep(false,i*10) 12 | ps.post.hello() 13 | end 14 | 15 | skynet.exit() 16 | end) 17 | 18 | 19 | -------------------------------------------------------------------------------- /skynet/test/testredis.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local redis = require "redis" 3 | 4 | local conf = { 5 | host = "127.0.0.1" , 6 | port = 6379 , 7 | db = 0 8 | } 9 | 10 | local function watching() 11 | local w = redis.watch(conf) 12 | w:subscribe "foo" 13 | w:psubscribe "hello.*" 14 | while true do 15 | print("Watch", w:message()) 16 | end 17 | end 18 | 19 | skynet.start(function() 20 | skynet.fork(watching) 21 | local db = redis.connect(conf) 22 | 23 | db:del "C" 24 | db:set("A", "hello") 25 | db:set("B", "world") 26 | db:sadd("C", "one") 27 | 28 | print(db:get("A")) 29 | print(db:get("B")) 30 | 31 | db:del "D" 32 | for i=1,10 do 33 | db:hset("D",i,i) 34 | end 35 | local r = db:hvals "D" 36 | for k,v in pairs(r) do 37 | print(k,v) 38 | end 39 | 40 | db:multi() 41 | db:get "A" 42 | db:get "B" 43 | local t = db:exec() 44 | for k,v in ipairs(t) do 45 | print("Exec", v) 46 | end 47 | 48 | print(db:exists "A") 49 | print(db:get "A") 50 | print(db:set("A","hello world")) 51 | print(db:get("A")) 52 | print(db:sismember("C","one")) 53 | print(db:sismember("C","two")) 54 | 55 | print("===========publish============") 56 | 57 | for i=1,10 do 58 | db:publish("foo", i) 59 | end 60 | for i=11,20 do 61 | db:publish("hello.foo", i) 62 | end 63 | 64 | db:disconnect() 65 | -- skynet.exit() 66 | end) 67 | 68 | -------------------------------------------------------------------------------- /skynet/test/testredis2.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local redis = require "redis" 3 | 4 | local db 5 | 6 | function add1(key, count) 7 | local t = {} 8 | for i = 1, count do 9 | t[2*i -1] = "key" ..i 10 | t[2*i] = "value" .. i 11 | end 12 | db:hmset(key, table.unpack(t)) 13 | end 14 | 15 | function add2(key, count) 16 | local t = {} 17 | for i = 1, count do 18 | t[2*i -1] = "key" ..i 19 | t[2*i] = "value" .. i 20 | end 21 | table.insert(t, 1, key) 22 | db:hmset(t) 23 | end 24 | 25 | function __init__() 26 | db = redis.connect { 27 | host = "127.0.0.1", 28 | port = 6300, 29 | db = 0, 30 | auth = "foobared" 31 | } 32 | print("dbsize:", db:dbsize()) 33 | local ok, msg = xpcall(add1, debug.traceback, "test1", 250000) 34 | if not ok then 35 | print("add1 failed", msg) 36 | else 37 | print("add1 succeed") 38 | 39 | end 40 | 41 | local ok, msg = xpcall(add2, debug.traceback, "test2", 250000) 42 | if not ok then 43 | print("add2 failed", msg) 44 | else 45 | print("add2 succeed") 46 | end 47 | print("dbsize:", db:dbsize()) 48 | 49 | print("redistest launched") 50 | end 51 | 52 | skynet.start(__init__) 53 | 54 | -------------------------------------------------------------------------------- /skynet/test/testresponse.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local mode = ... 4 | 5 | if mode == "TICK" then 6 | -- this service whould response the request every 1s. 7 | 8 | local response_queue = {} 9 | 10 | local function response() 11 | while true do 12 | skynet.sleep(100) -- sleep 1s 13 | for k,v in ipairs(response_queue) do 14 | v(true, skynet.now()) -- true means succ, false means error 15 | response_queue[k] = nil 16 | end 17 | end 18 | end 19 | 20 | skynet.start(function() 21 | skynet.fork(response) 22 | skynet.dispatch("lua", function() 23 | table.insert(response_queue, skynet.response()) 24 | end) 25 | end) 26 | 27 | else 28 | 29 | local function request(tick, i) 30 | print(i, "call", skynet.now()) 31 | print(i, "response", skynet.call(tick, "lua")) 32 | print(i, "end", skynet.now()) 33 | end 34 | 35 | skynet.start(function() 36 | local tick = skynet.newservice(SERVICE_NAME, "TICK") 37 | 38 | for i=1,5 do 39 | skynet.fork(request, tick, i) 40 | skynet.sleep(10) 41 | end 42 | end) 43 | 44 | end -------------------------------------------------------------------------------- /skynet/test/testsm.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local sharemap = require "sharemap" 3 | 4 | local mode = ... 5 | 6 | if mode == "slave" then 7 | --slave 8 | 9 | local function dump(reader) 10 | reader:update() 11 | print("x=", reader.x) 12 | print("y=", reader.y) 13 | print("s=", reader.s) 14 | end 15 | 16 | skynet.start(function() 17 | local reader 18 | skynet.dispatch("lua", function(_,_,cmd,...) 19 | if cmd == "init" then 20 | reader = sharemap.reader(...) 21 | else 22 | assert(cmd == "ping") 23 | dump(reader) 24 | end 25 | skynet.ret() 26 | end) 27 | end) 28 | 29 | else 30 | -- master 31 | skynet.start(function() 32 | -- register share type schema 33 | sharemap.register("./test/sharemap.sp") 34 | local slave = skynet.newservice(SERVICE_NAME, "slave") 35 | local writer = sharemap.writer("foobar", { x=0,y=0,s="hello" }) 36 | skynet.call(slave, "lua", "init", "foobar", writer:copy()) 37 | writer.x = 1 38 | writer:commit() 39 | skynet.call(slave, "lua", "ping") 40 | writer.y = 2 41 | writer:commit() 42 | skynet.call(slave, "lua", "ping") 43 | writer.s = "world" 44 | writer:commit() 45 | skynet.call(slave, "lua", "ping") 46 | end) 47 | 48 | end -------------------------------------------------------------------------------- /skynet/test/testsocket.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local socket = require "socket" 3 | 4 | local mode , id = ... 5 | 6 | local function echo(id) 7 | socket.start(id) 8 | 9 | while true do 10 | local str = socket.read(id) 11 | if str then 12 | socket.write(id, str) 13 | else 14 | socket.close(id) 15 | return 16 | end 17 | end 18 | end 19 | 20 | if mode == "agent" then 21 | id = tonumber(id) 22 | 23 | skynet.start(function() 24 | skynet.fork(function() 25 | echo(id) 26 | skynet.exit() 27 | end) 28 | end) 29 | else 30 | local function accept(id) 31 | socket.start(id) 32 | socket.write(id, "Hello Skynet\n") 33 | skynet.newservice(SERVICE_NAME, "agent", id) 34 | -- notice: Some data on this connection(id) may lost before new service start. 35 | -- So, be careful when you want to use start / abandon / start . 36 | socket.abandon(id) 37 | end 38 | 39 | skynet.start(function() 40 | local id = socket.listen("127.0.0.1", 8001) 41 | print("Listen socket :", "127.0.0.1", 8001) 42 | 43 | socket.start(id , function(id, addr) 44 | print("connect from " .. addr .. " " .. id) 45 | -- you have choices : 46 | -- 1. skynet.newservice("testsocket", "agent", id) 47 | -- 2. skynet.fork(echo, id) 48 | -- 3. accept(id) 49 | accept(id) 50 | end) 51 | end) 52 | end -------------------------------------------------------------------------------- /skynet/test/teststm.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local stm = require "stm" 3 | 4 | local mode = ... 5 | 6 | if mode == "slave" then 7 | 8 | skynet.start(function() 9 | skynet.dispatch("lua", function (_,_, obj) 10 | local obj = stm.newcopy(obj) 11 | print("read:", obj(skynet.unpack)) 12 | skynet.ret() 13 | skynet.error("sleep and read") 14 | for i=1,10 do 15 | skynet.sleep(10) 16 | print("read:", obj(skynet.unpack)) 17 | end 18 | skynet.exit() 19 | end) 20 | end) 21 | 22 | else 23 | 24 | skynet.start(function() 25 | local slave = skynet.newservice(SERVICE_NAME, "slave") 26 | local obj = stm.new(skynet.pack(1,2,3,4,5)) 27 | local copy = stm.copy(obj) 28 | skynet.call(slave, "lua", copy) 29 | for i=1,5 do 30 | skynet.sleep(20) 31 | print("write", i) 32 | obj(skynet.pack("hello world", i)) 33 | end 34 | skynet.exit() 35 | end) 36 | end 37 | -------------------------------------------------------------------------------- /skynet/test/testterm.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local function term() 4 | skynet.error("Sleep one second, and term the call to UNEXIST") 5 | skynet.sleep(100) 6 | local self = skynet.self() 7 | skynet.send(skynet.self(), "debug", "TERM", "UNEXIST") 8 | end 9 | 10 | skynet.start(function() 11 | skynet.fork(term) 12 | skynet.error("call an unexist named service UNEXIST, may block") 13 | pcall(skynet.call, "UNEXIST", "lua", "test") 14 | skynet.error("unblock the unexisted service call") 15 | end) 16 | -------------------------------------------------------------------------------- /skynet/test/testtimer.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local function timeout(t) 4 | print(t) 5 | end 6 | 7 | local function wakeup(co) 8 | for i=1,5 do 9 | skynet.sleep(50) 10 | skynet.wakeup(co) 11 | end 12 | end 13 | 14 | local function test() 15 | skynet.timeout(10, function() print("test timeout 10") end) 16 | for i=1,10 do 17 | print("test sleep",i,skynet.now()) 18 | skynet.sleep(1) 19 | end 20 | end 21 | 22 | skynet.start(function() 23 | test() 24 | 25 | skynet.fork(wakeup, coroutine.running()) 26 | skynet.timeout(300, function() timeout "Hello World" end) 27 | for i = 1, 10 do 28 | print(i, skynet.now()) 29 | print(skynet.sleep(100)) 30 | end 31 | skynet.exit() 32 | print("Test timer exit") 33 | 34 | end) 35 | -------------------------------------------------------------------------------- /skynet/test/testudp.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local socket = require "socket" 3 | 4 | local function server() 5 | local host 6 | host = socket.udp(function(str, from) 7 | print("server recv", str, socket.udp_address(from)) 8 | socket.sendto(host, from, "OK " .. str) 9 | end , "127.0.0.1", 8765) -- bind an address 10 | end 11 | 12 | local function client() 13 | local c = socket.udp(function(str, from) 14 | print("client recv", str, socket.udp_address(from)) 15 | end) 16 | socket.udp_connect(c, "127.0.0.1", 8765) 17 | for i=1,20 do 18 | socket.write(c, "hello " .. i) -- write to the address by udp_connect binding 19 | end 20 | end 21 | 22 | skynet.start(function() 23 | skynet.fork(server) 24 | skynet.fork(client) 25 | end) 26 | -------------------------------------------------------------------------------- /skynet/test/time.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | skynet.start(function() 3 | print(skynet.starttime()) 4 | print(skynet.now()) 5 | 6 | skynet.timeout(1, function() 7 | print("in 1", skynet.now()) 8 | end) 9 | skynet.timeout(2, function() 10 | print("in 2", skynet.now()) 11 | end) 12 | skynet.timeout(3, function() 13 | print("in 3", skynet.now()) 14 | end) 15 | 16 | skynet.timeout(4, function() 17 | print("in 4", skynet.now()) 18 | end) 19 | skynet.timeout(100, function() 20 | print("in 100", skynet.now()) 21 | end) 22 | end) 23 | --------------------------------------------------------------------------------