103 lines
4.0 KiB
Lua

--------------------------------------------------------------------------------
------------------------------ ##### ## ------------------------------
------------------------------ ## ## # ## ------------------------------
------------------------------ ## ## ## ## ------------------------------
------------------------------ ## ## # ## ------------------------------
------------------------------ ##### ### ###### ------------------------------
-------------------------------- --------------------------------
----------------------- An Object Request Broker in Lua ------------------------
--------------------------------------------------------------------------------
-- Project: OiL - ORB in Lua: An Object Request Broker in Lua --
-- Release: 0.4 --
-- Title : Remote Object Invoker --
-- Authors: Renato Maia <maia@inf.puc-rio.br> --
--------------------------------------------------------------------------------
-- invoker:Facet
-- [results:object], [except:table] invoke(reference, operation, args...)
--
-- requester:Receptacle
-- channel:object getchannel(reference)
-- [request:table], [except:table], [requests:table] request(channel:object, reference, operation, args...)
-- [request:table], [except:table], [requests:table] getreply(channel:object, [probe:boolean])
--
-- mutex:Facet
-- locksend(channel:object)
-- freesend(channel:object)
-- lockreceive(channel:object, request:object)
-- notifyreceived(channel:object, request:object)
-- freereceive(channel:object)
--------------------------------------------------------------------------------
local ipairs = ipairs
local next = next
local newproxy = newproxy
local pairs = pairs
local rawset = rawset
local type = type
local unpack = unpack
local oo = require "oil.oo"
local Invoker = require "oil.kernel.base.Invoker" --[[VERBOSE]] local verbose = require "oil.verbose"
module "oil.kernel.cooperative.Invoker"
oo.class(_M, Invoker)
context = false
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
function receivefrom(self, channel, request, probe)
if request.success == nil then
local requester = self.context.requester
local mutex = self.context.mutex
if not mutex or mutex:lockreceive(channel, request) then
local result, except, failed
repeat
result, except, failed = requester:getreply(channel, probe)
if result then
mutex:notifyreceived(channel, result)
else
for requestid, request in pairs(failed) do
if type(requestid) == "number" then
request.success = false
request.resultcount = 1
request[1] = except
mutex:notifyreceived(channel, request)
end
end
break
end
until result == request or (probe and result == true)
mutex:freereceive(channel)
end
end
local handler = self[request.success]
if handler then
return handler(self, channel, request, probe)
end
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
function invoke(self, reference, operation, ...) --[[VERBOSE]] verbose:invoke(true, "invoke remote operation")
local context = self.context
local requester = context.requester
local result, except = requester:getchannel(reference)
if result then
local channel = result
local mutex = context.mutex
mutex:locksend(channel)
result, except = requester:newrequest(channel, reference, operation, ...)
mutex:freesend(channel)
if result then
result[InvokerKey] = self
result[ChannelKey] = channel
result = Request(result)
end
end --[[VERBOSE]] verbose:invoke(false)
return result, except
end