Commit cb71a476 authored by Josh Kunz's avatar Josh Kunz

Add some helpful functions to avoid logical rp races

Sending and recving on the same RP can cause a logical race where the
sender receives their own capability instead of the capability they were
trying to obtain from the other end. The functions (and class) added in
this commit allow you to bootstrap an RP into two RPs that can be used
exclusively for sending or recving, thus avoiding the logical race.
parent 046e5621
......@@ -23,3 +23,54 @@ def recv_nodes(p, rp_iter):
flow = grant.flow()
nodes[info.name] = NodeProperties(node, grant, info, node_rp, flow)
return nodes
def make_safe_rps_send(p, rp):
"""Make two directional RPs from the given RP.
If both sides use the same RP they can experience race conditions where
the sender receives its own capability again.
One side should use the "_send" version and the other side should use the
"_recv" version, it doesn't really matter which uses which.
The "send" version only excutes the "send" method of the given RP, and
the "recv" versoin executes only the "recv" method of the given rp. This
guarantees that the capabilities will not race.
see also: capnet.util.SafeRP
"""
send_rp = p.create(capnet.RP)
recv_rp = p.create(capnet.RP)
rp.send(send_rp)
rp.send(recv_rp)
return send_rp, recv_rp
def make_safe_rps_recv(rp):
"see make_safe_rps_send"
recv_rp = rp.recv_wait()
send_rp = rp.recv_wait()
return send_rp, recv_rp
class SafeRP(object):
@classmethod
def from_rp_send(kls, rp):
send_rp, recv_rp = make_safe_rps_send(rp.protocol, rp)
return kls(send_rp, recv_rp)
@classmethod
def from_rp_recv(kls, rp):
send_rp, recv_rp = make_safe_rps_recv(rp)
return kls(send_rp, recv_rp)
def __init__(self, send_rp, recv_rp):
self.send_rp = send_rp
self.recv_rp = recv_rp
def send(self, cap=None, msg=None):
return self.send_rp.send(cap=cap, msg=msg)
def recv_wait(self, timeout=None):
return self.recv_rp.recv_wait(timeout=timeout)
def recv(self):
return self.recv_rp.recv()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment