使用不安全代码将 bytes::BytesMut 转换为 bytes::Bytes,而不使用 freeze

问题描述 投票:0回答:1
// create buf to hold each udp packet to avoid creating allocations
let mut buf = BytesMut::with_capacity(2000);

loop {

    // Receive data from the socket:
    let (len, src_ep_sip) = udp_sip.recv_from(&mut buf).await.unwrap();

    // in real code I check for errors instead of using unwrap. but this is not the question
    
    // I now need a Bytes object because a lot of my functions that I must call depends on that.

    // I cannot do this because it will not compile. 
    //  let request = buf.clone().freeze();

    // So instead I do this. Is this safe?
    let unsafe_bytes: Bytes = unsafe { Bytes::from_static(std::slice::from_raw_parts(buf.as_ptr(), len)) };

    // FROM NOW ON IT IS VERY IMPORTANT TO NOT MODIFY buf. It will not be modified until next iteration

    // call the functions that depend on this
    func_1(unsafe_bytes);
    func_2(unsafe_bytes);
    // etc

    if something {
        
        // in here I will have to allocate memory since I will be creating a new async task..
        let request_clone = Bytes::copy_from_slice(&buf);

        tokio::spawn(async move {
            // can safely use request_clone...
        }
    }
}

此代码可以编译并运行。 ChatGPT 表示使用它是有风险的,因为

from_static
不引用静态内存。我之所以想用这个是因为:

  1. 我不必重构我的代码和测试。我有很多东西取决于
    Bytes
  2. 我知道我可以克隆我的
    buf
    并避免出现不安全的代码,但最好避免每个数据包分配一次。
  3. 使用 freeze 将
    BytesMut
    转换为
    Bytes
    使我的代码无法编译。如果我没有循环,它就可以工作。

但缺点是我不希望我的程序在半夜崩溃。我知道解决方案是使用

&[u8]
或其他不同的东西,因为我从不操纵数据。但由于我所有的方法都已经依赖于 Bytes,如果我能拥有这个不安全的代码那就太好了。即使我没有写入缓冲区并将其视为只读,这是否很危险?即使不是静态数据,使用
from_static
有危险吗?

rust unsafe
1个回答
0
投票

您可以在调用 freeze 之前克隆

BytesMut
对象:

let mut buf = BytesMut::with_capacity(2000);

loop {
    let (len, src_ep_sip) = udp_sip.recv_from(&mut buf).await.unwrap();

    let bytes = buf.clone().freeze();
    call_function(bytes);
    call_functino_2(bytes);
}
© www.soinside.com 2019 - 2024. All rights reserved.