fix deadlock

This commit is contained in:
Aiden McClelland
2025-08-21 18:40:53 -06:00
parent 359146f02c
commit 5bee2cef96
6 changed files with 50 additions and 166 deletions

View File

@@ -1,4 +1,5 @@
ls-files = $(shell git ls-files --cached --others --exclude-standard $1) ls-files = $(shell git ls-files --cached --others --exclude-standard $1)
PROFILE = release
PLATFORM_FILE := $(shell ./check-platform.sh) PLATFORM_FILE := $(shell ./check-platform.sh)
ENVIRONMENT_FILE := $(shell ./check-environment.sh) ENVIRONMENT_FILE := $(shell ./check-environment.sh)
@@ -23,7 +24,7 @@ WEB_INSTALL_WIZARD_SRC := $(call ls-files, web/projects/install-wizard)
PATCH_DB_CLIENT_SRC := $(shell git ls-files --recurse-submodules patch-db/client) PATCH_DB_CLIENT_SRC := $(shell git ls-files --recurse-submodules patch-db/client)
GZIP_BIN := $(shell which pigz || which gzip) GZIP_BIN := $(shell which pigz || which gzip)
TAR_BIN := $(shell which gtar || which tar) TAR_BIN := $(shell which gtar || which tar)
COMPILED_TARGETS := core/target/$(ARCH)-unknown-linux-musl/release/startbox core/target/$(ARCH)-unknown-linux-musl/release/containerbox container-runtime/rootfs.$(ARCH).squashfs COMPILED_TARGETS := core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox core/target/$(ARCH)-unknown-linux-musl/release/containerbox container-runtime/rootfs.$(ARCH).squashfs
ALL_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE) $(COMPILED_TARGETS) cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs $(PLATFORM_FILE) \ ALL_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE) $(COMPILED_TARGETS) cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs $(PLATFORM_FILE) \
$(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then \ $(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then \
echo cargo-deps/aarch64-unknown-linux-musl/release/pi-beep; \ echo cargo-deps/aarch64-unknown-linux-musl/release/pi-beep; \
@@ -133,7 +134,7 @@ results/$(BASENAME).$(IMAGE_TYPE) results/$(BASENAME).squashfs: $(IMAGE_RECIPE_S
install: $(ALL_TARGETS) install: $(ALL_TARGETS)
$(call mkdir,$(DESTDIR)/usr/bin) $(call mkdir,$(DESTDIR)/usr/bin)
$(call mkdir,$(DESTDIR)/usr/sbin) $(call mkdir,$(DESTDIR)/usr/sbin)
$(call cp,core/target/$(ARCH)-unknown-linux-musl/release/startbox,$(DESTDIR)/usr/bin/startbox) $(call cp,core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox,$(DESTDIR)/usr/bin/startbox)
$(call ln,/usr/bin/startbox,$(DESTDIR)/usr/bin/startd) $(call ln,/usr/bin/startbox,$(DESTDIR)/usr/bin/startd)
$(call ln,/usr/bin/startbox,$(DESTDIR)/usr/bin/start-cli) $(call ln,/usr/bin/startbox,$(DESTDIR)/usr/bin/start-cli)
if [ "$(PLATFORM)" = "raspberrypi" ]; then $(call cp,cargo-deps/aarch64-unknown-linux-musl/release/pi-beep,$(DESTDIR)/usr/bin/pi-beep); fi if [ "$(PLATFORM)" = "raspberrypi" ]; then $(call cp,cargo-deps/aarch64-unknown-linux-musl/release/pi-beep,$(DESTDIR)/usr/bin/pi-beep); fi
@@ -169,10 +170,10 @@ update-overlay: $(ALL_TARGETS)
$(MAKE) install REMOTE=$(REMOTE) SSHPASS=$(SSHPASS) PLATFORM=$(PLATFORM) $(MAKE) install REMOTE=$(REMOTE) SSHPASS=$(SSHPASS) PLATFORM=$(PLATFORM)
$(call ssh,"sudo systemctl start startd") $(call ssh,"sudo systemctl start startd")
wormhole: core/target/$(ARCH)-unknown-linux-musl/release/startbox wormhole: core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox
@echo "Paste the following command into the shell of your StartOS server:" @echo "Paste the following command into the shell of your StartOS server:"
@echo @echo
@wormhole send core/target/$(ARCH)-unknown-linux-musl/release/startbox 2>&1 | awk -Winteractive '/wormhole receive/ { printf "sudo /usr/lib/startos/scripts/chroot-and-upgrade \"cd /usr/bin && rm startbox && wormhole receive --accept-file %s && chmod +x startbox\"\n", $$3 }' @wormhole send core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox 2>&1 | awk -Winteractive '/wormhole receive/ { printf "sudo /usr/lib/startos/scripts/chroot-and-upgrade \"cd /usr/bin && rm startbox && wormhole receive --accept-file %s && chmod +x startbox\"\n", $$3 }'
wormhole-deb: results/$(BASENAME).deb wormhole-deb: results/$(BASENAME).deb
@echo "Paste the following command into the shell of your StartOS server:" @echo "Paste the following command into the shell of your StartOS server:"
@@ -192,10 +193,10 @@ update: $(ALL_TARGETS)
$(MAKE) install REMOTE=$(REMOTE) SSHPASS=$(SSHPASS) DESTDIR=/media/startos/next PLATFORM=$(PLATFORM) $(MAKE) install REMOTE=$(REMOTE) SSHPASS=$(SSHPASS) DESTDIR=/media/startos/next PLATFORM=$(PLATFORM)
$(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync "apt-get install -y $(shell cat ./build/lib/depends)"') $(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync "apt-get install -y $(shell cat ./build/lib/depends)"')
update-startbox: core/target/$(ARCH)-unknown-linux-musl/release/startbox # only update binary (faster than full update) update-startbox: core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox # only update binary (faster than full update)
@if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi @if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi
$(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create') $(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create')
$(call cp,core/target/$(ARCH)-unknown-linux-musl/release/startbox,/media/startos/next/usr/bin/startbox) $(call cp,core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox,/media/startos/next/usr/bin/startbox)
$(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync true') $(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync true')
update-deb: results/$(BASENAME).deb # better than update, but only available from debian update-deb: results/$(BASENAME).deb # better than update, but only available from debian
@@ -269,9 +270,9 @@ build/lib/depends build/lib/conflicts: build/dpkg-deps/*
$(FIRMWARE_ROMS): build/lib/firmware.json download-firmware.sh $(PLATFORM_FILE) $(FIRMWARE_ROMS): build/lib/firmware.json download-firmware.sh $(PLATFORM_FILE)
./download-firmware.sh $(PLATFORM) ./download-firmware.sh $(PLATFORM)
core/target/$(ARCH)-unknown-linux-musl/release/startbox: $(CORE_SRC) $(COMPRESSED_WEB_UIS) web/patchdb-ui-seed.json $(ENVIRONMENT_FILE) core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox: $(CORE_SRC) $(COMPRESSED_WEB_UIS) web/patchdb-ui-seed.json $(ENVIRONMENT_FILE)
ARCH=$(ARCH) ./core/build-startbox.sh ARCH=$(ARCH) PROFILE=$(PROFILE) ./core/build-startbox.sh
touch core/target/$(ARCH)-unknown-linux-musl/release/startbox touch core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox
core/target/$(ARCH)-unknown-linux-musl/release/containerbox: $(CORE_SRC) $(ENVIRONMENT_FILE) core/target/$(ARCH)-unknown-linux-musl/release/containerbox: $(CORE_SRC) $(ENVIRONMENT_FILE)
ARCH=$(ARCH) ./core/build-containerbox.sh ARCH=$(ARCH) ./core/build-containerbox.sh

View File

@@ -1,5 +1,10 @@
#!/bin/bash #!/bin/bash
PROFILE=${PROFILE:-release}
if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
fi
cd "$(dirname "${BASH_SOURCE[0]}")" cd "$(dirname "${BASH_SOURCE[0]}")"
set -ea set -ea
@@ -30,7 +35,7 @@ alias 'rust-musl-builder'='docker run $USE_TTY --rm -e "RUSTFLAGS=$RUSTFLAGS" -v
echo "FEATURES=\"$FEATURES\"" echo "FEATURES=\"$FEATURES\""
echo "RUSTFLAGS=\"$RUSTFLAGS\"" echo "RUSTFLAGS=\"$RUSTFLAGS\""
rust-musl-builder sh -c "cd core && cargo build --release --no-default-features --features cli,startd,$FEATURES --locked --bin startbox --target=$ARCH-unknown-linux-musl" rust-musl-builder sh -c "cd core && cargo build $BUILD_FLAGS --no-default-features --features cli,startd,$FEATURES --locked --bin startbox --target=$ARCH-unknown-linux-musl"
if [ "$(ls -nd core/target/$ARCH-unknown-linux-musl/release/startbox | awk '{ print $3 }')" != "$UID" ]; then if [ "$(ls -nd core/target/$ARCH-unknown-linux-musl/${PROFILE}/startbox | awk '{ print $3 }')" != "$UID" ]; then
rust-musl-builder sh -c "cd core && chown -R $UID:$UID target && chown -R $UID:$UID /root/.cargo" rust-musl-builder sh -c "cd core && chown -R $UID:$UID target && chown -R $UID:$UID /root/.cargo"
fi fi

View File

@@ -144,7 +144,7 @@ pub fn main(args: impl IntoIterator<Item = OsString>) {
let res = { let res = {
let rt = tokio::runtime::Builder::new_multi_thread() let rt = tokio::runtime::Builder::new_multi_thread()
.worker_threads(max(4, num_cpus::get())) .worker_threads(max(1, num_cpus::get()))
.enable_all() .enable_all()
.build() .build()
.expect("failed to initialize runtime"); .expect("failed to initialize runtime");

View File

@@ -22,6 +22,7 @@ use hickory_server::server::{Request, RequestHandler, ResponseHandler, ResponseI
use hickory_server::ServerFuture; use hickory_server::ServerFuture;
use imbl::OrdMap; use imbl::OrdMap;
use imbl_value::InternedString; use imbl_value::InternedString;
use itertools::Itertools;
use models::{GatewayId, OptionExt, PackageId}; use models::{GatewayId, OptionExt, PackageId};
use rpc_toolkit::{ use rpc_toolkit::{
from_fn_async, from_fn_blocking, Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async, from_fn_blocking, Context, HandlerArgs, HandlerExt, ParentHandler,
@@ -164,7 +165,7 @@ impl DnsClient {
if let Err::<(), Error>(e) = async { if let Err::<(), Error>(e) = async {
let mut stream = file_string_stream("/run/systemd/resolve/resolv.conf") let mut stream = file_string_stream("/run/systemd/resolve/resolv.conf")
.filter_map(|a| futures::future::ready(a.transpose())).boxed(); .filter_map(|a| futures::future::ready(a.transpose())).boxed();
let mut conf = stream let mut conf: String = stream
.next() .next()
.await .await
.or_not_found("/run/systemd/resolve/resolv.conf")??; .or_not_found("/run/systemd/resolve/resolv.conf")??;
@@ -175,6 +176,7 @@ impl DnsClient {
.lines() .lines()
.map(|l| l.trim()) .map(|l| l.trim())
.filter_map(|l| l.strip_prefix("nameserver ")) .filter_map(|l| l.strip_prefix("nameserver "))
.skip(2)
.map(|n| { .map(|n| {
n.parse::<SocketAddr>() n.parse::<SocketAddr>()
.or_else(|_| n.parse::<IpAddr>().map(|a| (a, 53).into())) .or_else(|_| n.parse::<IpAddr>().map(|a| (a, 53).into()))
@@ -408,10 +410,12 @@ impl RequestHandler for Resolver {
} }
} else { } else {
let query = query.original().clone(); let query = query.original().clone();
let mut streams = self.client.lookup(query, DnsRequestOptions::default()); let mut streams = self
.client
.lookup(dbg!(query), DnsRequestOptions::default());
let mut err = None; let mut err = None;
for stream in streams.iter_mut() { for stream in streams.iter_mut() {
match stream.next().await { match dbg!(stream.next().await) {
None => (), None => (),
Some(Err(e)) => err = Some(e), Some(Err(e)) => err = Some(e),
Some(Ok(msg)) => { Some(Ok(msg)) => {
@@ -433,18 +437,9 @@ impl RequestHandler for Resolver {
tracing::error!("{e}"); tracing::error!("{e}");
tracing::debug!("{e:?}"); tracing::debug!("{e:?}");
} }
let res = Header::response_from_request(request.header()); let mut res = Header::response_from_request(request.header());
response_handle res.set_response_code(ResponseCode::ServFail);
.send_response( Ok(res.into())
MessageResponseBuilder::from_message_request(&*request).build(
res.into(),
[],
[],
[],
[],
),
)
.await
} }
} }
.await .await

View File

@@ -25,6 +25,7 @@ use ts_rs::TS;
use zbus::proxy::{PropertyChanged, PropertyStream, SignalStream}; use zbus::proxy::{PropertyChanged, PropertyStream, SignalStream};
use zbus::zvariant::{ use zbus::zvariant::{
DeserializeDict, Dict, OwnedObjectPath, OwnedValue, Type as ZType, Value as ZValue, DeserializeDict, Dict, OwnedObjectPath, OwnedValue, Type as ZType, Value as ZValue,
DICT_ENTRY_SIG_END_STR,
}; };
use zbus::{proxy, Connection}; use zbus::{proxy, Connection};
@@ -1185,17 +1186,10 @@ impl ListenerMap {
} }
pub trait InterfaceFilter: Any + Clone + std::fmt::Debug + Eq + Ord + Send + Sync { pub trait InterfaceFilter: Any + Clone + std::fmt::Debug + Eq + Ord + Send + Sync {
#[cfg_attr(feature = "unstable", inline(never))]
fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool; fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool;
#[cfg_attr(feature = "unstable", inline(never))]
fn simplify(&self) -> &dyn DynInterfaceFilterT {
self
}
#[cfg_attr(feature = "unstable", inline(never))]
fn eq(&self, other: &dyn Any) -> bool { fn eq(&self, other: &dyn Any) -> bool {
Some(self) == other.downcast_ref::<Self>() Some(self) == other.downcast_ref::<Self>()
} }
#[cfg_attr(feature = "unstable", inline(never))]
fn cmp(&self, other: &dyn Any) -> std::cmp::Ordering { fn cmp(&self, other: &dyn Any) -> std::cmp::Ordering {
match (self as &dyn Any).type_id().cmp(&other.type_id()) { match (self as &dyn Any).type_id().cmp(&other.type_id()) {
std::cmp::Ordering::Equal => { std::cmp::Ordering::Equal => {
@@ -1204,20 +1198,10 @@ pub trait InterfaceFilter: Any + Clone + std::fmt::Debug + Eq + Ord + Send + Syn
ord => ord, ord => ord,
} }
} }
#[cfg_attr(feature = "unstable", inline(never))]
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
fn into_dyn(self) -> DynInterfaceFilter { fn into_dyn(self) -> DynInterfaceFilter {
#[cfg(feature = "unstable")]
{
let res = DynInterfaceFilter::new(self.clone());
if !DynInterfaceFilterT::eq(&self, &res) || !DynInterfaceFilterT::eq(&res, &self) {
panic!("self != self")
}
res
}
#[cfg(not(feature = "unstable"))]
DynInterfaceFilter::new(self) DynInterfaceFilter::new(self)
} }
} }
@@ -1262,47 +1246,6 @@ impl<A: InterfaceFilter, B: InterfaceFilter> InterfaceFilter for AndFilter<A, B>
fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool { fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool {
self.0.filter(id, info) && self.1.filter(id, info) self.0.filter(id, info) && self.1.filter(id, info)
} }
fn simplify(&self) -> &dyn DynInterfaceFilterT {
if InterfaceFilter::eq(&self.0, &self.1) {
&self.0
} else {
self
}
}
fn eq(&self, other: &dyn Any) -> bool {
if let Some(other) = other.downcast_ref::<Self>() {
(InterfaceFilter::eq(&self.0, other.0.as_any())
&& InterfaceFilter::eq(&self.1, other.1.as_any()))
|| (InterfaceFilter::eq(&self.0, other.1.as_any())
&& InterfaceFilter::eq(&self.1, other.0.as_any()))
} else {
false
}
}
fn cmp(&self, other: &dyn Any) -> std::cmp::Ordering {
if let Some(other) = other.downcast_ref::<Self>() {
let mut lhs: [&dyn DynInterfaceFilterT; 2] = [&self.0, &self.1];
lhs.sort_by(|a, b| a.cmp(b.as_any()));
let mut rhs: [&dyn DynInterfaceFilterT; 2] = [&other.0, &other.1];
rhs.sort_by(|a, b| a.cmp(b.as_any()));
lhs.iter()
.zip_eq(rhs)
.fold_while(std::cmp::Ordering::Equal, |acc, (a, b)| {
match a.cmp(b.as_any()) {
std::cmp::Ordering::Equal => itertools::FoldWhile::Continue(acc),
ord => itertools::FoldWhile::Done(ord),
}
})
.into_inner()
} else {
match (self as &dyn Any).type_id().cmp(&other.type_id()) {
std::cmp::Ordering::Equal => {
std::cmp::Ord::cmp(self, other.downcast_ref::<Self>().unwrap())
}
ord => ord,
}
}
}
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
@@ -1311,47 +1254,6 @@ impl<A: InterfaceFilter, B: InterfaceFilter> InterfaceFilter for OrFilter<A, B>
fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool { fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool {
self.0.filter(id, info) || self.1.filter(id, info) self.0.filter(id, info) || self.1.filter(id, info)
} }
fn simplify(&self) -> &dyn DynInterfaceFilterT {
if InterfaceFilter::eq(&self.0, &self.1) {
&self.0
} else {
self
}
}
fn eq(&self, other: &dyn Any) -> bool {
if let Some(other) = other.downcast_ref::<Self>() {
(InterfaceFilter::eq(&self.0, other.0.as_any())
&& InterfaceFilter::eq(&self.1, other.1.as_any()))
|| (InterfaceFilter::eq(&self.0, other.1.as_any())
&& InterfaceFilter::eq(&self.1, other.0.as_any()))
} else {
false
}
}
fn cmp(&self, other: &dyn Any) -> std::cmp::Ordering {
if let Some(other) = other.downcast_ref::<Self>() {
let mut lhs: [&dyn DynInterfaceFilterT; 2] = [&self.0, &self.1];
lhs.sort_by(|a, b| a.cmp(b.as_any()));
let mut rhs: [&dyn DynInterfaceFilterT; 2] = [&other.0, &other.1];
rhs.sort_by(|a, b| a.cmp(b.as_any()));
lhs.iter()
.zip_eq(rhs)
.fold_while(std::cmp::Ordering::Equal, |acc, (a, b)| {
match a.cmp(b.as_any()) {
std::cmp::Ordering::Equal => itertools::FoldWhile::Continue(acc),
ord => itertools::FoldWhile::Done(ord),
}
})
.into_inner()
} else {
match (self as &dyn Any).type_id().cmp(&other.type_id()) {
std::cmp::Ordering::Equal => {
std::cmp::Ord::cmp(self, other.downcast_ref::<Self>().unwrap())
}
ord => ord,
}
}
}
} }
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
@@ -1360,13 +1262,6 @@ impl InterfaceFilter for AnyFilter {
fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool { fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool {
self.0.iter().any(|f| InterfaceFilter::filter(f, id, info)) self.0.iter().any(|f| InterfaceFilter::filter(f, id, info))
} }
fn simplify(&self) -> &dyn DynInterfaceFilterT {
match self.0.len() {
0 => &false,
1 => self.0.first().unwrap(),
_ => self,
}
}
} }
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
@@ -1375,13 +1270,6 @@ impl InterfaceFilter for AllFilter {
fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool { fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool {
self.0.iter().all(|f| InterfaceFilter::filter(f, id, info)) self.0.iter().all(|f| InterfaceFilter::filter(f, id, info))
} }
fn simplify(&self) -> &dyn DynInterfaceFilterT {
match self.0.len() {
0 => &true,
1 => self.0.first().unwrap(),
_ => self,
}
}
} }
pub trait DynInterfaceFilterT: std::fmt::Debug + Any + Send + Sync { pub trait DynInterfaceFilterT: std::fmt::Debug + Any + Send + Sync {
@@ -1395,31 +1283,25 @@ impl<T: InterfaceFilter> DynInterfaceFilterT for T {
InterfaceFilter::filter(self, id, info) InterfaceFilter::filter(self, id, info)
} }
fn eq(&self, other: &dyn Any) -> bool { fn eq(&self, other: &dyn Any) -> bool {
let simplified = self.simplify(); InterfaceFilter::eq(self, other)
if (simplified as &dyn Any).is::<Self>() {
InterfaceFilter::eq(self, other)
} else {
dbg!(simplified.eq(other))
}
} }
fn cmp(&self, other: &dyn Any) -> std::cmp::Ordering { fn cmp(&self, other: &dyn Any) -> std::cmp::Ordering {
let simplified = self.simplify(); InterfaceFilter::cmp(self, other)
if (simplified as &dyn Any).is::<Self>() {
InterfaceFilter::cmp(self, other)
} else {
simplified.cmp(other)
}
} }
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
let simplified = self.simplify(); InterfaceFilter::as_any(self)
if (simplified as &dyn Any).is::<Self>() {
InterfaceFilter::as_any(self)
} else {
simplified.as_any()
}
} }
} }
#[test]
fn test_interface_filter_eq() {
let dyn_t = true.into_dyn();
assert!(DynInterfaceFilterT::eq(
&dyn_t,
DynInterfaceFilterT::as_any(&true),
))
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct DynInterfaceFilter(Arc<dyn DynInterfaceFilterT>); pub struct DynInterfaceFilter(Arc<dyn DynInterfaceFilterT>);
impl InterfaceFilter for DynInterfaceFilter { impl InterfaceFilter for DynInterfaceFilter {
@@ -1582,7 +1464,7 @@ impl NetworkInterfaceListener {
filter: &impl InterfaceFilter, filter: &impl InterfaceFilter,
) -> Poll<Result<Accepted, Error>> { ) -> Poll<Result<Accepted, Error>> {
while self.ip_info.poll_changed(cx).is_ready() while self.ip_info.poll_changed(cx).is_ready()
|| !InterfaceFilter::eq(&self.listeners.prev_filter, filter) || !DynInterfaceFilterT::eq(&self.listeners.prev_filter, filter.as_any())
{ {
self.ip_info self.ip_info
.peek_and_mark_seen(|ip_info| self.listeners.update(ip_info, filter))?; .peek_and_mark_seen(|ip_info| self.listeners.update(ip_info, filter))?;

View File

@@ -2,6 +2,7 @@ pub mod eq_map;
pub mod eq_set; pub mod eq_set;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::Bound;
pub use eq_map::EqMap; pub use eq_map::EqMap;
pub use eq_set::EqSet; pub use eq_set::EqSet;
@@ -26,15 +27,15 @@ impl<'a, K: Ord + Clone, V: Clone> Iterator for OrdMapIterMut<'a, K, V> {
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
unsafe { unsafe {
let map: &'a mut OrdMap<K, V> = self.map.as_mut().unwrap(); let map: &'a mut OrdMap<K, V> = self.map.as_mut().unwrap();
let res = if let Some(k) = self.prev.take() { let Some((k, _)) = (if let Some(k) = self.prev.take() {
map.get_next_mut(k) map.range((Bound::Excluded(k), Bound::Unbounded)).next()
} else { } else {
let Some((k, _)) = map.get_min() else { map.get_min().map(|(k, v)| (k, v))
return None; }) else {
}; return None;
let k = k.clone(); // hate that I have to do this but whatev
map.get_key_value_mut(&k)
}; };
let k = k.clone(); // hate that I have to do this but whatev
let res = map.get_key_value_mut(&k);
if let Some((k, _)) = &res { if let Some((k, _)) = &res {
self.prev = Some(*k); self.prev = Some(*k);
} }