summaryrefslogtreecommitdiff
path: root/lib/supple/comms.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lib/supple/comms.lua')
-rw-r--r--lib/supple/comms.lua29
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)