139 Commits
Author SHA1 Message Date
Samuel Williams 5b6f593531 Introduce (internal) IO::Buffer::Storage and Slice. (#19186) 2026-10-03 10:46:24 +13:00
Hiroshi SHIBATAandClaude Opus 5.5 475082545b Fix lost signal in TestFiberMutex#test_condition_variable
ConditionVariable#signal is lost when no fiber is waiting. If the scheduler thread stalls for 0.1 seconds after the first signal, Scheduler#run_once resumes the signalling fiber from its timer before the ready waiter, and the waiter then waits forever for a signal that never comes. Count the signals and wait only while none is pending.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 11:04:34 +09:00
Tavian Barnes c4f93eb297 io: preserve errno across rb_io_wait() call. (#19121)
[Bug #22391]
2026-09-30 10:08:39 +13:00
Samuel Williams 4d56c955c4 Revalidate IO::Buffer byte access after Ruby callbacks. (#19086)
Treat encoding coercion, `to_io`, and scheduler capability checks as
callouts that can change the buffer before byte access begins.

- Copy `get_string` bytes through the existing locked-for-reading helper
  after encoding coercion, without retaining metadata pointers across it.
- Obtain the writable buffer after `to_io` conversion in `read` and `pread`.
- Reacquire and validate the buffer before native I/O fallback when the
  scheduler does not handle `read`, `write`, `pread`, or `pwrite`.

Add regression coverage using the existing buffer and slice APIs. Scheduler
probes shrink a slice without freeing its underlying storage, making stale
length handling observable without accessing released memory. Also cover
encoding callbacks and frozen-state changes during I/O coercion.

This is an independent correctness extraction from #18911. It introduces
no new classes, slice representation, or public API.
2026-09-28 15:07:20 +13:00
Samuel Williams aaf83bcebe Scope fiber_interrupt with an operation proxy. (#18793)
[Bug #21918]
2026-09-13 14:48:19 +12:00
Hiroshi SHIBATAandClaude Opus 5 934c31a6b3 Say what actually keeps test_epipe_on_read off Windows
nonblock= works there; what does not happen is the write failing.  The
peer being closed leaves the next write on an AF_UNIX socket succeeding
instead of raising EPIPE.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 08:49:38 +09:00
Kasumi Hanazuki ae5a02b056 Free temporary IO::Buffer objects when I/O hooks raise. (#18666) 2026-09-12 19:48:37 +12:00
Nobuyoshi Nakada 9ee713a92c Revert "Adjust indent [ci skip]"
This reverts commit c0a526dd97.
2026-08-27 09:27:53 +09:00
Nobuyoshi Nakada c0a526dd97 Adjust indent [ci skip] 2026-08-27 09:26:49 +09:00
Samuel Williams 0968fd4b3b Require Fiber::Scheduler#fiber_interrupt. (#18513) 2026-08-27 09:52:46 +12:00
Samuel Williams 44da9d7384 Make IO::Buffer I/O operations single-transfer and composable. (#18483) 2026-08-25 14:46:49 +12:00
Nobuyoshi Nakada 937f6c22b3 Use assert_include instead of assert_includes 2026-08-08 14:46:58 +09:00
Sorah Fukumori bf920ef6af test_thread_join_hang: join leaked inner sleeper (#17068)
SleepingUnblockScheduler#unblock deliberately breaks the join path,
so the inner Thread.new{sleep(0.01)} created inside Fiber.schedule
is abandoned mid-sleep when the outer thread exits. It eventually
wakes and lingers in Thread.list, breaking cleanup_threads in later
test files (e.g. test/-ext-/thread/test_instrumentation_api.rb).
Capture the inner thread and join it in an ensure.

     18) Failure:
    TestThreadInstrumentation#test_thread_pass_multi_thread [/build/ruby4.0/test/-ext-/thread/test_instrumentation_api.rb:289]:
    <[#<Thread:0x00007f8dbc9b7f48 run>]> expected but was
    <[#<Thread:0x00007f8dbc9b7f48 run>,
     #<Thread:0x00007f8dbc9f45b0 /build/ruby4.0/test/fiber/test_thread.rb:165 sleep>]>.
2026-05-21 07:19:38 +00:00
Samuel Williams 30d9782c5c Tidy up fiber scheduler tests. 2025-12-24 14:10:09 +13:00
Samuel Williams 2df72c0c1a Fix flaky test. 2025-12-24 14:10:09 +13:00
Koichi Sasada 04e90fe200 skip TestFiberScheduler#test_io_write_on_flush because it makes GC.stat test fragile 2025-12-20 03:49:50 +09:00
Sharon Rosner 9ee2243bed Fiber scheduler: invoke #io_write hook on IO flush (#15609)
Previously, calling IO#flush or closing an IO with unflushed buffered
writes would just invoke `#blocking_operation_wait` and flush the write
buffer using a `write` syscall. This change adds flushing through the
fiber scheduler by invoking the `#io_write` hook.

* Prefer IO::Buffer#write in IOScheduler

* Use Dir.tmpdir for test file

* Correctly handle errors in io_flush_buffer_fiber_scheduler
2025-12-19 23:58:26 +13:00
Samuel Williams eafaff9443 Re-introduce support for io_close hook. (#15434) 2025-12-08 00:55:13 +13:00
Samuel Williams 42f5654b69 Yield to scheduler if interrupts are pending. (#14700) 2025-12-06 21:44:14 +13:00
Sharon Rosner 5f6b31c23f Correctly handle Process.fork with an active Fiber.scheduler. (#15385)
In the child process, nullify the current fiber scheduler and set the current fiber to blocking.
2025-12-05 18:20:39 +13:00
Samuel Williams ead14b19aa Fix blocking_operation_wait use-after-free bug. 2025-06-06 13:13:16 +09:00
Samuel Williams 81a23c5793 rb_io_blocking_operation_exit should not execute with pending interrupts. 2025-06-06 13:13:16 +09:00
Samuel Williams f0cf4dce65 Handle spurious wakeups in Thread#join. (#13532) 2025-06-06 09:38:57 +09:00
Jean Boussier 553753cd3e Fix scheduler warning
```
test/fiber/test_scheduler.rb:98: warning: Scheduler should implement #fiber_interrupt
```
2025-06-03 21:55:37 +02:00
Koichi Sasada ef2bb61018 Ractor::Port
* Added `Ractor::Port`
  * `Ractor::Port#receive` (support multi-threads)
  * `Rcator::Port#close`
  * `Ractor::Port#closed?`
* Added some methods
  * `Ractor#join`
  * `Ractor#value`
  * `Ractor#monitor`
  * `Ractor#unmonitor`
* Removed some methods
  * `Ractor#take`
  * `Ractor.yield`
* Change the spec
  * `Racotr.select`

You can wait for multiple sequences of messages with `Ractor::Port`.

```ruby
ports = 3.times.map{ Ractor::Port.new }
ports.map.with_index do |port, ri|
  Ractor.new port,ri do |port, ri|
    3.times{|i| port << "r#{ri}-#{i}"}
  end
end

p ports.each{|port| pp 3.times.map{port.receive}}

```

In this example, we use 3 ports, and 3 Ractors send messages to them respectively.
We can receive a series of messages from each port.

You can use `Ractor#value` to get the last value of a Ractor's block:

```ruby
result = Ractor.new do
  heavy_task()
end.value
```

You can wait for the termination of a Ractor with `Ractor#join` like this:

```ruby
Ractor.new do
  some_task()
end.join
```

`#value` and `#join` are similar to `Thread#value` and `Thread#join`.

To implement `#join`, `Ractor#monitor` (and `Ractor#unmonitor`) is introduced.

This commit changes `Ractor.select()` method.
It now only accepts ports or Ractors, and returns when a port receives a message or a Ractor terminates.

We removes `Ractor.yield` and `Ractor#take` because:
* `Ractor::Port` supports most of similar use cases in a simpler manner.
* Removing them significantly simplifies the code.

We also change the internal thread scheduler code (thread_pthread.c):
* During barrier synchronization, we keep the `ractor_sched` lock to avoid deadlocks.
  This lock is released by `rb_ractor_sched_barrier_end()`
  which is called at the end of operations that require the barrier.
* fix potential deadlock issues by checking interrupts just before setting UBF.

https://bugs.ruby-lang.org/issues/21262
2025-05-31 04:01:33 +09:00
Samuel Williams 73c9d6ccaa Allow IO#close to interrupt IO operations on fibers using fiber_interrupt hook. (#12839) 2025-05-23 14:55:05 +09:00
Samuel Williams c1dbd01c67 Increase fiber sleep test tolerance. (#13152) 2025-04-23 01:17:15 +00:00
Alan WuandAaron Patterson 08b3a45bc9 Push a real iseq in rb_vm_push_frame_fname()
Previously, vm_make_env_each() (used during proc
creation and for the debug inspector C API) picked up the
non-GC-allocated iseq that rb_vm_push_frame_fname() creates,
which led to a SEGV when the GC tried to mark the non GC object.

Put a real iseq imemo instead. Speed should be about the same since
the old code also did a imemo allocation and a malloc allocation.

Real iseq allows ironing out the special-casing of dummy frames in
rb_execution_context_mark() and rb_execution_context_update(). A check
is added to RubyVM::ISeq#eval, though, to stop attempts to run dummy
iseqs.

[Bug #21180]

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2025-03-12 15:00:26 -04:00
Samuel Williams a8c2d5e7be Ensure fiber scheduler re-acquires mutex when interrupted from sleep. (#12158)
[Bug #20907]
2024-11-23 23:54:12 +00:00
Samuel Williams 9c268302bf Introduce Fiber::Scheduler#blocking_operation_wait. (#12016)
Redirect `rb_nogvl` blocking operations to the fiber scheduler if possible
to prevent stalling the event loop.

[Feature #20876]
2024-11-20 19:40:17 +13:00
Samuel Williams 3b9896acfc Revert "Introduce Fiber Scheduler blocking_region hook. (#11963)" (#12013)
This reverts some of commit 87fb44dff6.

We will rename and propose a slightly different interface.
2024-11-06 22:19:40 +13:00
Samuel Williams 87fb44dff6 Introduce Fiber Scheduler blocking_region hook. (#11963) 2024-10-31 17:26:37 +13:00
Yusuke Endoh d84b062b63 Prevent warning: assigned but unused variable - message 2024-09-17 13:56:04 +09:00
KJ Tsanaktsidis e08d5239b6 Ensure fiber scheduler is woken up when close interrupts read
If one thread is reading and another closes that socket, the close
blocks waiting for the read to abort cleanly. This ensures that Ruby is
totally done with the file descriptor _BEFORE_ we tell the OS to close
and potentially re-use it.

When the read is correctly terminated, the close should be unblocked.
That currently works if closing is happening on a thread, but if it's
happening on a fiber with a fiber scheduler, it does NOT work.

This patch ensures that if the close happened in a fiber scheduled
thread, that the scheduler is notified that the fiber is unblocked.

[Bug #20723]
2024-09-17 10:11:44 +10:00
Samuel Williams 5d1702e01a Enumerator should use a non-blocking fiber, change rb_fiber_new to be non-blocking by default. (#10481) 2024-04-08 00:49:01 +12:00
Samuel Williams b473d304d4 Revert "Enumerator should use a non-blocking fiber. (#10478)" (#10480)
This reverts commit dfa0897de8.

This commit accidentally included some change in `parse.h`. Reverting
and re-applying the relevant changes.
2024-04-07 10:20:22 +00:00
Samuel Williams bdb1fc1e5b Prefer to use Fiber#transfer in scheduler implementation. (#10479) 2024-04-07 19:57:15 +12:00
Samuel Williams dfa0897de8 Enumerator should use a non-blocking fiber. (#10478) 2024-04-07 19:18:09 +12:00
Hiroshi SHIBATA 53d0cf442a Use exit 0 instead of true on windows platform 2024-01-24 18:00:12 +09:00
Misaki Shioi 52f6de4196 Replace SocketError with Socket::ResolutionError in rsock_raise_socket_error
rsock_raise_socket_error is called only when getaddrinfo and getaddrname fail
2023-11-30 13:27:19 +09:00
Jun Aruga 3eaae72855 test/fiber/test_queue.rb: Make the stuck test fail. (#8791)
test/fiber/test_queue.rb: Make the stuck tests fail.

We observed the 2 tests in the `test/fiber/test_queue.rb` getting stuck
in some GCC compilers in Ubuntu ppc64le focal/jammy, even when the timeout
`queue.pop(timeout: 0.0001)` is set in the code.

This commit is to make the tests fail rather than getting stuck.
2023-10-28 11:10:30 +02:00
Nobuyoshi Nakada ab637cad2b [Bug #19624] Clean up backquote IO
It should not be hidden, since it can be grabbed by a fiber scheduler.
2023-09-21 10:23:14 +09:00
Samuel Williams 05aaff2191 Reduce number of iterations in TestFiberScheduler#test_autoload. (#8391)
`ppc64le` appears to be struggling with this test due to timeout. Let's see
if reducing the number of iterations can help improve the test performance.
2023-09-07 13:53:51 +12:00
Samuel Williams 901b6d9c50 Validate the typed data before dereferencing the internal struct. (#8315) 2023-08-29 20:04:14 +12:00
Nobuyoshi Nakada 5dd969892f Wait for sleepr thread to finish not to leak 2023-07-13 13:12:52 +09:00
Samuel Williams 0402193723 Fix Thread#join(timeout) when running inside the fiber scheduler. (#7903) 2023-06-03 12:41:36 +09:00
Samuel Williams 0b2613f443 rb_io_puts should not write zero length strings. (#7806) 2023-05-15 11:13:51 +09:00
Samuel Williams 648870b5c5 Support IO#pread / IO#pwrite using fiber scheduler. (#7594)
* Skip test if non-blocking file IO is not supported.
2023-03-31 00:48:55 +13:00
Samuel Williams 466aa8010f Fix incorrect usage of rb_fiber_scheduler_io_(p)(read|write). (#7593) 2023-03-25 18:36:27 +13:00
Samuel Williams 7abe47b85a Improve robustness of io_wait implementation. (#7456)
- Restore correct handling of `duration`.
- Don't delete from `@readable` or `@writable` unless it was added.
- A little more documentation.
2023-03-07 19:38:58 +13:00