rust - 如何证明类型中毒?

标签 rust

我正在阅读 The Rustonomicon ,并遇到了它的 section on poisoning .类型中毒的一个书面示例是,“如果 MutexGuard(获得锁时它返回的东西)之一在 panic 期间被丢弃,则互斥锁将自身中毒。”(Rustonomicon,第 7.2 节,第 3) 段

我有点不知所措,但突然很好奇。

为了寻找类型中毒的实现演示,谷歌搜索“如何给类型下毒”会产生无用的结果,从化学毒物类型列表到口袋妖怪。 “类型中毒的代码示例”的结果大致相同。

是否有人可以用代码片段演示类型中毒?我不在乎这个例子是不是用 Rust 写的,但也许这很重要……因为在某些语言中可能只能以某些方式被毒化?

我看到中毒发生在其他语言中,或者至少 C++ function poisoning , 和 namespace poisoning . (搜索“Java 类型中毒”会从检测 java bean poisoned dogshow 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/

相关文章:

rust - 如何从actix SyncContext向另一个参与者发送消息?

arrays - Rust中的耦合数组

rust - 有两个结构互相引用 - Rust

rust - 如何从函数返回反转的字符串?

rust - 如何在函数中返回自定义字符串引用?

rust - 重新打开AboutDialog将显示一个空白对话框

rust - 在 rust 中使用 u32 整数类型

io - 如何从 Rust 中的文件中读取结构?

rust - 你如何结合使用rust 的生命周期?

rust - Reqwest 的 Client.post() 返回 400 错误的 File.io API 请求