Repair reimported, attenuated references.
This commit is contained in:
parent
40a239c9eb
commit
0b72b4029b
|
@ -29,6 +29,7 @@ use preserves::value::Map;
|
||||||
use preserves::value::NestedValue;
|
use preserves::value::NestedValue;
|
||||||
use preserves::value::NoEmbeddedDomainCodec;
|
use preserves::value::NoEmbeddedDomainCodec;
|
||||||
use preserves::value::PackedWriter;
|
use preserves::value::PackedWriter;
|
||||||
|
use preserves::value::Set;
|
||||||
use preserves::value::TextWriter;
|
use preserves::value::TextWriter;
|
||||||
use preserves::value::ViaCodec;
|
use preserves::value::ViaCodec;
|
||||||
use preserves::value::Writer;
|
use preserves::value::Writer;
|
||||||
|
@ -76,6 +77,7 @@ struct Membranes {
|
||||||
exported: Membrane,
|
exported: Membrane,
|
||||||
imported: Membrane,
|
imported: Membrane,
|
||||||
next_export_oid: usize,
|
next_export_oid: usize,
|
||||||
|
reimported_attenuations: Map<sturdy::Oid, Set<Arc<Cap>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Input {
|
pub enum Input {
|
||||||
|
@ -172,6 +174,11 @@ impl Membrane {
|
||||||
ws
|
ws
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove(&mut self, ws: &Arc<WireSymbol>) {
|
||||||
|
self.oid_map.remove(&ws.oid);
|
||||||
|
self.ref_map.remove(&ws.obj);
|
||||||
|
}
|
||||||
|
|
||||||
fn insert_inert_entity(&mut self, t: &mut Activation, oid: sturdy::Oid) -> Arc<WireSymbol> {
|
fn insert_inert_entity(&mut self, t: &mut Activation, oid: sturdy::Oid) -> Arc<WireSymbol> {
|
||||||
self.insert(oid, Cap::new(&t.inert_entity()))
|
self.insert(oid, Cap::new(&t.inert_entity()))
|
||||||
}
|
}
|
||||||
|
@ -259,6 +266,7 @@ impl TunnelRelay {
|
||||||
exported: Membrane::new(WireSymbolSide::Exported),
|
exported: Membrane::new(WireSymbolSide::Exported),
|
||||||
imported: Membrane::new(WireSymbolSide::Imported),
|
imported: Membrane::new(WireSymbolSide::Imported),
|
||||||
next_export_oid: 0,
|
next_export_oid: 0,
|
||||||
|
reimported_attenuations: Map::new(),
|
||||||
},
|
},
|
||||||
pending_outbound: Vec::new(),
|
pending_outbound: Vec::new(),
|
||||||
};
|
};
|
||||||
|
@ -550,9 +558,10 @@ impl Membranes {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn release_one(&mut self, ws: Arc<WireSymbol>) -> bool {
|
fn release_one(&mut self, ws: Arc<WireSymbol>) -> bool {
|
||||||
if ws.dec_ref() {
|
if ws.dec_ref() {
|
||||||
let membrane = self.membrane(ws.side);
|
if let WireSymbolSide::Exported = ws.side {
|
||||||
membrane.oid_map.remove(&ws.oid);
|
self.reimported_attenuations.remove(&ws.oid);
|
||||||
membrane.ref_map.remove(&ws.obj);
|
}
|
||||||
|
self.membrane(ws.side).remove(&ws);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -573,34 +582,43 @@ impl Membranes {
|
||||||
src: &'src mut S,
|
src: &'src mut S,
|
||||||
_read_annotations: bool,
|
_read_annotations: bool,
|
||||||
) -> io::Result<Arc<Cap>> {
|
) -> io::Result<Arc<Cap>> {
|
||||||
let ws = match sturdy::WireRef::deserialize(&mut src.packed(NoEmbeddedDomainCodec))? {
|
match sturdy::WireRef::deserialize(&mut src.packed(NoEmbeddedDomainCodec))? {
|
||||||
sturdy::WireRef::Mine{ oid: b } => {
|
sturdy::WireRef::Mine{ oid: b } => {
|
||||||
let oid = *b;
|
let oid = *b;
|
||||||
self.imported.oid_map.get(&oid).map(Arc::clone)
|
let ws = self.imported.oid_map.get(&oid).map(Arc::clone)
|
||||||
.unwrap_or_else(|| self.import_oid(t, relay_ref, oid))
|
.unwrap_or_else(|| self.import_oid(t, relay_ref, oid));
|
||||||
|
Ok(Arc::clone(&ws.inc_ref().obj))
|
||||||
}
|
}
|
||||||
sturdy::WireRef::Yours { oid: b, attenuation } => {
|
sturdy::WireRef::Yours { oid: b, attenuation } => {
|
||||||
let oid = *b;
|
let oid = *b;
|
||||||
|
let ws = self.exported.oid_map.get(&oid).map(Arc::clone)
|
||||||
|
.unwrap_or_else(|| self.exported.insert_inert_entity(t, oid.clone()));
|
||||||
|
|
||||||
if attenuation.is_empty() {
|
if attenuation.is_empty() {
|
||||||
self.exported.oid_map.get(&oid).map(Arc::clone).unwrap_or_else(
|
Ok(Arc::clone(&ws.inc_ref().obj))
|
||||||
|| self.exported.insert_inert_entity(t, oid))
|
|
||||||
} else {
|
} else {
|
||||||
match self.exported.oid_map.get(&oid) {
|
let attenuated_obj = ws.obj.attenuate(&attenuation)
|
||||||
None => self.exported.insert_inert_entity(t, oid),
|
.map_err(|e| {
|
||||||
Some(ws) => {
|
io::Error::new(
|
||||||
let attenuated_obj = ws.obj.attenuate(&attenuation)
|
io::ErrorKind::InvalidInput,
|
||||||
.map_err(|e| {
|
format!("Invalid capability attenuation: {:?}", e))
|
||||||
io::Error::new(
|
})?;
|
||||||
io::ErrorKind::InvalidInput,
|
|
||||||
format!("Invalid capability attenuation: {:?}", e))
|
ws.inc_ref();
|
||||||
})?;
|
|
||||||
self.exported.insert(oid, attenuated_obj)
|
let variations = self.reimported_attenuations.entry(oid).or_default();
|
||||||
|
match variations.get(&attenuated_obj) {
|
||||||
|
None => {
|
||||||
|
variations.insert(Arc::clone(&attenuated_obj));
|
||||||
|
self.exported.ref_map.insert(Arc::clone(&attenuated_obj), Arc::clone(&ws));
|
||||||
|
Ok(attenuated_obj)
|
||||||
}
|
}
|
||||||
|
Some(existing) =>
|
||||||
|
Ok(Arc::clone(existing))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
Ok(Arc::clone(&ws.inc_ref().obj))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue