| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
📝 Walkthrough
WalkthroughRefactors VM signal handler storage from an Option to a OnceCell-backed lazy container, adds a crate helper to create the handler array, enforces main-thread-only signal operations, and ensures signal handlers are initialized in forked child processes. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
rect rgba(200,220,255,0.5)
participant Py as Python code
participant VM as VirtualMachine
participant SIG as signal_handlers (OnceCell<Box<RefCell...>>)
participant OS as OS/Thread
end
Py->>VM: call signal.signal(signum, handler)
VM->>OS: check is_main_thread()
alt not main thread
VM-->>Py: raise ValueError
else main thread
VM->>SIG: get_or_init(new_signal_handlers)
SIG->>SIG: borrow & store handler at index
SIG-->>VM: stored
VM-->>Py: return old handler
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem🚥 Pre-merge checks | ✅ 3 ✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick commentscrates/vm/src/stdlib/signal.rs (1) Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. ❤️ ShareComment @coderabbitai help to get the list of available commands and usage tips. |
Sorry, something went wrong.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)crates/vm/src/stdlib/posix.rs (1)783-798: ⚠️ Potential issue | 🟡 Minor
fork() does not handle libc::fork() returning -1 (error).
If libc::fork() fails it returns -1, but the function unconditionally runs py_os_after_fork_parent on the error path (since -1 != 0). This is pre-existing behavior and not introduced by this PR, but worth noting: the -1 is also returned directly to the Python caller without raising OSError.
In `@crates/vm/src/stdlib/signal.rs`: - Around line 380-381: The error message in set_wakeup_fd is wrong; locate the branch that checks vm.is_main_thread() inside the set_wakeup_fd implementation and change the ValueError text from "signal only works in main thread" to "set_wakeup_fd only works in main thread" so the raised error accurately names the function (ensure the change occurs in the function/method named set_wakeup_fd and only affects the vm.new_value_error call in that check). - Around line 258-260: The getsignal() implementation currently enforces a main-thread check using vm.is_main_thread() and returns Err(vm.new_value_error(...)); remove that main-thread restriction so getsignal() no longer returns an error for non-main threads: locate the getsignal function in signal.rs, delete or bypass the vm.is_main_thread() check and its Err return, and ensure the function simply returns the current handler value for the given signal regardless of thread; keep the main-thread check only in signal.signal() if present.
crates/vm/src/stdlib/posix.rs (1)crates/vm/src/stdlib/signal.rs (1)714-718: Duplicated signal_handlers initialization expression across files.
The Box::new(const { RefCell::new([const { None }; NSIG]) }) pattern is repeated here, in signal.rs (lines 250, 263), and in vm/mod.rs (line 187). Consider extracting a helper (e.g., signal_handlers_default()) to keep this in one place and reduce divergence risk.
Example helper// In crates/vm/src/signal.rs or a shared location: pub(crate) fn new_signal_handlers() -> Box<RefCell<[Option<PyObjectRef>; NSIG]>> { Box::new(const { RefCell::new([const { None }; NSIG]) }) }Then each call site becomes:
-vm.signal_handlers.get_or_init(|| { - Box::new(const { core::cell::RefCell::new([const { None }; crate::signal::NSIG]) }) -}); +vm.signal_handlers.get_or_init(signal::new_signal_handlers);181-181: get().unwrap() in init_signal_handlers could panic if called on a worker thread.
Unlike signal() / getsignal() which use get_or_init, this uses get().unwrap(). This is safe today because module_exec runs during main-thread initialization where the OnceCell is pre-filled, but it's fragile. Consider using get_or_init for consistency, or adding a debug assertion with a clear message.
Proposed fix-vm.signal_handlers.get().unwrap().borrow_mut()[signum] = py_handler; +vm.signal_handlers + .get_or_init(|| Box::new(const { RefCell::new([const { None }; signal::NSIG]) })) + .borrow_mut()[signum] = py_handler;
Sorry, something went wrong.
- Change `signal_handlers` type from `Option<Box<...>>` to `OnceCell<Box<...>>` so fork children can lazily initialize it - Add `VirtualMachine::is_main_thread()` using runtime thread ID comparison instead of structural `signal_handlers.is_none()` check - Initialize signal handlers in `py_os_after_fork_child()` via `get_or_init()` for workers that fork - Use `get_or_init()` in `signal()` and `getsignal()` functions - Remove `set_wakeup_fd(-1)` special-case workaround (d6d0303) - Extract `signal::new_signal_handlers()` to deduplicate init expr - Allow `getsignal()` from any thread (matches CPython behavior) - Fix `set_wakeup_fd` error message to name the correct function
| Back | FazBrowse Home | New Git URL |
Summary by CodeRabbit