From: "nagachika (Tomoyuki Chikanaga) via ruby-core" <ruby-core@...>
Date: 2024-07-06T06:34:54+00:00
Subject: [ruby-core:118459] [Ruby master Bug#20393] `after_fork_ruby` clears all pending interrupts for both parent and child process.

Issue #20393 has been updated by nagachika (Tomoyuki Chikanaga).

Backport changed from 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED, 3.3: DONE to 3.0: REQUIRED, 3.1: REQUIRED, 3.2: DONE, 3.3: DONE

ruby_3_2 commit:5577e5d396cc8f062833b67d6280db6cc8501e7a merged revision(s) commit:a7ff264477105b5dc0ade6facad4176a1b73df0b.

----------------------------------------
Bug #20393: `after_fork_ruby` clears all pending interrupts for both parent and child process.
https://bugs.ruby-lang.org/issues/20393#change-108973

* Author: ioquatix (Samuel Williams)
* Status: Closed
* Assignee: ioquatix (Samuel Williams)
* Backport: 3.0: REQUIRED, 3.1: REQUIRED, 3.2: DONE, 3.3: DONE
----------------------------------------
In the following program, the behaviour of the parent process is affected by whether `Process.fork` is invoked or not.

```ruby
Thread.handle_interrupt(RuntimeError => :never) do
  Thread.current.raise(RuntimeError, "Queued error")
  
  puts "Pending interrupt: #{Thread.pending_interrupt?}" # true
  
  pid = Process.fork do
    puts "Pending interrupt (child process): #{Thread.pending_interrupt?}"
    Thread.handle_interrupt(RuntimeError => :immediate){}
  end
  
  _, status = Process.waitpid2(pid)
  puts "Child process status: #{status.inspect}"
  
  puts "Pending interrupt: #{Thread.pending_interrupt?}" # false
end

puts "Exiting..."
```

I don't think the parent process pending interrupts should be cleared by `after_fork_ruby`:

```c
static void
after_fork_ruby(rb_pid_t pid)
{
    rb_threadptr_pending_interrupt_clear(GET_THREAD());
    if (pid == 0) {
        // child
        clear_pid_cache();
        rb_thread_atfork();
    }
    else {
        // parent
        after_exec();
    }
}
```

How about this implementation:

```c
static void
after_fork_ruby(rb_pid_t pid)
{
    if (pid == 0) {
        // child
        rb_threadptr_pending_interrupt_clear(GET_THREAD());
        clear_pid_cache();
        rb_thread_atfork();
    }
    else {
        // parent
        after_exec();
    }
}
```

cc @ko1



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/