Skip to content

Add fork support functions #4971

Open
Open
@itsankitkp

Description

@itsankitkp

os.fork needs certain support functions to work properly, namely _at_fork_reinit
Basic idea is that whenever child is forked from parent, it shouldn't own locks held by its parent (parent's problem is not children's problem right?).
So whenever child gets initialized, lock object should get reallocated.
cpython code

int
_PyThread_at_fork_reinit(PyThread_type_lock *lock)
{
    PyThread_type_lock new_lock = PyThread_allocate_lock();
    if (new_lock == NULL) {
        return -1;
    }

    /* bpo-6721, bpo-40089: The old lock can be in an inconsistent state.
       fork() can be called in the middle of an operation on the lock done by
       another thread. So don't call PyThread_free_lock(*lock).

       Leak memory on purpose. Don't release the memory either since the
       address of a mutex is relevant. Putting two mutexes at the same address
       can lead to problems. */

    *lock = new_lock;
    return 0;
}

Notice, it doesn't bother cleanup up old lock object.

cpython's Add _at_fork_reinit() method to locks gives relevant details

Unknowns: LockType object is alias for Lock, but there is file called Lib/_dummy_thread.py in rustpython which I don't see in cpython.

Implementation strategy:

  1. Add _at_fork_reinit in Lock and RLock in vm/src/stdlib/thread.rs
  2. Realloc self.mu.
    For this, I can not possibly do this
        #[pymethod]
        fn _at_fork_reinit(&mut self, vm: &VirtualMachine) -> PyResult<()> {
            self.mu = RawMutex::INIT;

            Ok(())
        }

It complains about

error[E0277]: the trait bound `for<'a, 'b> fn(&'a mut RLock, &'b vm::VirtualMachine) -> Result<(), object::core::PyRef<exceptions::types::PyBaseException>> {RLock::_at_fork_reinit}: PyNativeFnInternal<_, _, _>` is not satisfied
   --> vm/src/stdlib/thread.rs:186:5
    |
186 |     #[pyclass(with(Representable))]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyNativeFnInternal<_, _, _>` is not implemented for fn item `for<'a, 'b> fn(&'a mut RLock, &'b vm::VirtualMachine) -> Result<(), object::core::PyRef<exceptions::types::PyBaseException>> {RLock::_at_fork_reinit}`
    |
note: required for `for<'a, 'b> fn(&'a mut RLock, &'b vm::VirtualMachine) -> Result<(), object::core::PyRef<exceptions::types::PyBaseException>> {RLock::_at_fork_reinit}` to implement `IntoPyNativeFn<(_, _, _)>`
   --> vm/src/function/builtin.rs:44:19
    |
44  | impl<F, T, R, VM> IntoPyNativeFn<(T, R, VM)> for F
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^     ^
45  | where
46  |     F: PyNativeFnInternal<T, R, VM>,
    |        ---------------------------- unsatisfied trait bound introduced here
    = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
error: could not compile `rustpython-vm` due to 2 previous errors

which is unfortunate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCRequest for comments

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions