summaryrefslogtreecommitdiff
path: root/test/fiber/scheduler.rb
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-12-18 18:19:30 +1300
committerGitHub <noreply@github.com>2021-12-18 18:19:30 +1300
commit42d32311541e58503b885b09b469948922650c66 (patch)
tree235c0405be8a02e2fb2612b5daf9694d01ebd2fe /test/fiber/scheduler.rb
parent922a81a99418c992f4039b27a8341f2ee96d2d0c (diff)
Introduce io_result wrapper for passing `[-errno, size]` in VALUE.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5287 Merged-By: ioquatix <samuel@codeotaku.com>
Diffstat (limited to 'test/fiber/scheduler.rb')
-rw-r--r--test/fiber/scheduler.rb82
1 files changed, 82 insertions, 0 deletions
diff --git a/test/fiber/scheduler.rb b/test/fiber/scheduler.rb
index a6e1325259..0e352a1cc9 100644
--- a/test/fiber/scheduler.rb
+++ b/test/fiber/scheduler.rb
@@ -192,6 +192,9 @@ class Scheduler
end
Fiber.yield
+ ensure
+ @readable.delete(io)
+ @writable.delete(io)
end
# Used for Kernel#sleep and Thread::Mutex#sleep
@@ -257,6 +260,85 @@ class Scheduler
end
end
+class IOBufferScheduler < Scheduler
+ EAGAIN = Errno::EAGAIN::Errno
+
+ def io_read(io, buffer, length)
+ offset = 0
+
+ while true
+ maximum_size = buffer.size - offset
+ result = blocking{io.read_nonblock(maximum_size, exception: false)}
+
+ # blocking{pp read: maximum_size, result: result, length: length}
+
+ case result
+ when :wait_readable
+ if length > 0
+ self.io_wait(io, IO::READABLE, nil)
+ else
+ return -EAGAIN
+ end
+ when :wait_writable
+ if length > 0
+ self.io_wait(io, IO::WRITABLE, nil)
+ else
+ return -EAGAIN
+ end
+ else
+ break unless result
+
+ buffer.copy(result, offset)
+
+ size = result.bytesize
+ offset += size
+ break if size >= length
+ length -= size
+ end
+ end
+
+ return offset
+ end
+
+ def io_write(io, buffer, length)
+ offset = 0
+
+ while true
+ maximum_size = buffer.size - offset
+
+ chunk = buffer.to_str(offset, maximum_size)
+ result = blocking{io.write_nonblock(chunk, exception: false)}
+
+ # blocking{pp write: maximum_size, result: result, length: length}
+
+ case result
+ when :wait_readable
+ if length > 0
+ self.io_wait(io, IO::READABLE, nil)
+ else
+ return -EAGAIN
+ end
+ when :wait_writable
+ if length > 0
+ self.io_wait(io, IO::WRITABLE, nil)
+ else
+ return -EAGAIN
+ end
+ else
+ offset += result
+ break if result >= length
+ length -= result
+ end
+ end
+
+ return offset
+ end
+
+ def blocking(&block)
+ Fiber.new(blocking: true, &block).resume
+ end
+end
+
class BrokenUnblockScheduler < Scheduler
def unblock(blocker, fiber)
super