[][src]Function uapi::fork

pub unsafe fn fork() -> Result<pid_t>

fork(2)

Safety

fork is unsafe in multi-threaded programs.

Consider the following example:

This example is not tested
#![feature(thread_id_value)]

use std::sync::atomic::{AtomicI32, AtomicPtr};
use std::sync::atomic::Ordering::SeqCst;
use std::{thread, ptr};

pub fn f() {
    static I: AtomicI32 = AtomicI32::new(0);
    static D: AtomicPtr<i32> = AtomicPtr::new(ptr::null_mut());

    let data = Box::leak(Box::new(0));
    let tid = gettid();
    match I.load(SeqCst) {
        0 => {
            I.store(tid, SeqCst);
            /*
             * Assumption for safety: No call to `f` can have the same `tid` while we're
             * in the critical section that spans this comment.
             */
            D.store(data, SeqCst);
        },
        n if n == tid => {
            /* D has been set to a valid pointer because of the assumption above */
            let _v = unsafe { *D.load(SeqCst) };
        },
        _ => { },
    }
}

If fork is called while another thread is in the critical section, I will be initialized in the child but D won't. If the child creates a new thread, the new thread might have the same tid as the thread in the critical section. Therefore the child thread will dereference a null pointer.

Consult the upstream documentation.