File tree Expand file tree Collapse file tree 2 files changed +14
-2
lines changed
Expand file tree Collapse file tree 2 files changed +14
-2
lines changed Original file line number Diff line number Diff line change @@ -4988,8 +4988,13 @@ mod _io {
49884988 }
49894989
49904990 /// Reinit per-object IO buffer locks on std streams after `fork()`.
4991+ ///
4992+ /// # Safety
4993+ ///
4994+ /// Must only be called from the single-threaded child process immediately
4995+ /// after `fork()`, before any other thread is created.
49914996 #[ cfg( all( unix, feature = "threading" ) ) ]
4992- pub fn reinit_std_streams_after_fork ( vm : & VirtualMachine ) {
4997+ pub unsafe fn reinit_std_streams_after_fork ( vm : & VirtualMachine ) {
49934998 for name in [ "stdin" , "stdout" , "stderr" ] {
49944999 let Ok ( stream) = vm. sys_module . get_attr ( name, vm) else {
49955000 continue ;
@@ -5006,11 +5011,18 @@ mod _io {
50065011 unsafe { reinit_thread_mutex_after_fork ( & tio. data ) } ;
50075012 if let Some ( guard) = tio. data . lock ( ) {
50085013 if let Some ( ref data) = * guard {
5014+ if let Some ( ref decoder) = data. decoder {
5015+ reinit_io_locks ( decoder) ;
5016+ }
50095017 reinit_io_locks ( & data. buffer ) ;
50105018 }
50115019 }
50125020 return ;
50135021 }
5022+ if let Some ( nl) = obj. downcast_ref :: < IncrementalNewlineDecoder > ( ) {
5023+ unsafe { reinit_thread_mutex_after_fork ( & nl. data ) } ;
5024+ return ;
5025+ }
50145026 if let Some ( br) = obj. downcast_ref :: < BufferedReader > ( ) {
50155027 unsafe { reinit_thread_mutex_after_fork ( & br. data ) } ;
50165028 return ;
Original file line number Diff line number Diff line change @@ -723,7 +723,7 @@ pub mod module {
723723 // BufferedReader/Writer/TextIOWrapper use PyThreadMutex which can be
724724 // held by dead parent threads, causing deadlocks on any IO in the child.
725725 #[ cfg( feature = "threading" ) ]
726- crate :: stdlib:: io:: reinit_std_streams_after_fork ( vm) ;
726+ unsafe { crate :: stdlib:: io:: reinit_std_streams_after_fork ( vm) } ;
727727
728728 // Phase 2: Reset low-level atomic state (no locks needed).
729729 crate :: signal:: clear_after_fork ( ) ;
You can’t perform that action at this time.
0 commit comments