我正在阅读 The Rustonomicon ,并遇到了它的 section on poisoning .类型中毒的一个书面示例是,“如果 MutexGuard(获得锁时它返回的东西)之一在 panic 期间被丢弃,则互斥锁将自身中毒。”(Rustonomicon,第 7.2 节,第 3) 段
我有点不知所措,但突然很好奇。
为了寻找类型中毒的实现演示,谷歌搜索“如何给类型下毒”会产生无用的结果,从化学毒物类型列表到口袋妖怪。 “类型中毒的代码示例”的结果大致相同。
是否有人可以用代码片段演示类型中毒?我不在乎这个例子是不是用 Rust 写的,但也许这很重要……因为在某些语言中可能只能以某些方式被毒化?
我看到中毒发生在其他语言中,或者至少 C++ function poisoning , 和 namespace poisoning . (搜索“Java 类型中毒”会从检测 java bean poisoned dogs 到 how to poison mobs in Minecraft 产生无用但有趣的结果。)
然而,这些示例缺少指向代码示例的链接。我希望看到它的实际应用。
最佳答案
中毒是通过检查std::thread::panicking
的返回值实现的在 Drop
实现中。如果它返回 true
,那么该值应该是中毒的。这是一个例子:
use std::cell::Cell;
use std::panic::{self, AssertUnwindSafe};
use std::thread;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum ResourceState {
Available,
Locked,
Poisoned,
}
struct Resource {
state: Cell<ResourceState>,
}
struct ResourceGuard<'a> {
resource: &'a Resource,
}
impl Resource {
fn new() -> Resource {
Resource {
state: Cell::new(ResourceState::Available),
}
}
fn lock(&self) -> ResourceGuard {
assert_eq!(self.state.get(), ResourceState::Available);
self.state.set(ResourceState::Locked);
ResourceGuard {
resource: self,
}
}
}
impl<'a> Drop for ResourceGuard<'a> {
fn drop(&mut self) {
self.resource.state.set(
if thread::panicking() {
ResourceState::Poisoned
} else {
ResourceState::Available
});
}
}
fn main() {
let resource = Resource::new();
println!("state: {:?}", resource.state.get()); // Available
{
println!("acquiring lock");
let _guard = resource.lock();
println!("state: {:?}", resource.state.get()); // Locked
println!("dropping lock");
}
println!("state: {:?}", resource.state.get()); // Available
let _ = panic::catch_unwind(AssertUnwindSafe(|| {
println!("acquiring lock");
let _guard = resource.lock();
println!("state: {:?}", resource.state.get()); // Locked
println!("panicking!");
panic!("panicking!");
}));
println!("state: {:?}", resource.state.get()); // Poisoned
}
关于rust - 如何证明类型中毒?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47107366/