diff options
Diffstat (limited to 'lib/supple/comms.lua')
-rw-r--r-- | lib/supple/comms.lua | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/lib/supple/comms.lua b/lib/supple/comms.lua index e72f8f1..ae2779c 100644 --- a/lib/supple/comms.lua +++ b/lib/supple/comms.lua @@ -14,6 +14,7 @@ local luxio = require "luxio" local capi = require "supple.capi" local request = require "supple.request" local objects = require "supple.objects" +local track = require "supple.track" local unpack = unpack local tonumber = tonumber @@ -34,6 +35,7 @@ local function send_msg(msg) error("Message too long") end local msglen = ("%05d"):format(#msg) + track.record("XMIT", msg) luxio.write(fd, msglen .. msg) end @@ -53,6 +55,7 @@ local function recv_msg() if type(str) ~= "string" or #str ~= len then error("Unable to read " .. tostring(len) .. " bytes of msg") end + track.record("RECV", str) return str end @@ -64,7 +67,8 @@ local function captcha(msg) return info.short_src:match("/supple/[^%.]+%.lua$") end while info and info.func ~= xpcall do - if info.currentline > 0 and not in_supple() then +-- if info.currentline > 0 and not in_supple() then + if true then local ttype, tag = objects.find_tag(info.func) if ttype then info.name = tag @@ -78,7 +82,7 @@ local function captcha(msg) level = level + 1 info = getinfo(level, "Snlf") end - return {msg, concat(traceback, "\n") or ""} + return {msg, (concat(traceback, "\n") or "") .. "\nComms track:\n" .. track.stop()} end local limits = {} @@ -111,7 +115,23 @@ end local function wait_for_response() repeat + -- We *MUST* disable GC for the duration of receiving and parsing the + -- message, lest we send a __gc transaction between the first and second + -- read operations. Or indeed if we GC and object between receiving the + -- message and deserialising and thus anchoring the object. If we error + -- out here, we don't really care about restarting gc since we won't + -- survive long anyhow. + gc "stop" + -- Also anchor all the objects just in case + local anchor = objects.get_object_anchor() + -- Now receive and deserialise (thus anchoring relevant objects) local back = request.deserialise(recv_msg()) + -- Now that the request is anchored, release the extra anchor and + -- re-allow GC + anchor = nil + gc "restart" + -- And get on with parsing the message we received.. + -- back could be three things -- an error (raise it) if back.error then @@ -182,9 +202,12 @@ local function wait_for_response() end local function make_call(object, method, ...) + track.enter("make_call", object, method) local req = request.request(object, method, ...) send_msg(req) - return wait_for_response() + local ret = {wait_for_response()} + track.leave("make_call", object, method) + return unpack(ret) end local function set_limits(newlimits) |