From: samuel@... Date: 2021-06-15T23:46:38+00:00 Subject: [ruby-core:104293] [Ruby master Bug#17664] Behavior of sockets changed in Ruby 3.0 to non-blocking Issue #17664 has been updated by ioquatix (Samuel Williams). This change was originally proposed and implemented by @normalperson. The outward interface does not change, but you are right it can impact io_uring implementation. I know this is a problem and ran into the same issue. I don't know how we should solve the io_uring issue correctly. There are several options: - Change Ruby default IO back to blocking. But it can cause issues for fiber scheduler since non-blocking hooks will never be invoked. - In the uring backend, for read/write operations, set the IO to blocking and then revert it afterwards. - Propose that uring takes a flag/option to do this per SQE, i.e. even if the I/O is set to non-blocking mode, e.g. `OP_READV` should always behave like blocking operation. Personally, I like the last option best, since I think it's more predictable. We cannot determine the state of the FD just because of Ruby's default. i.e. if a user makes an IO blocking or non-blocking, we prefer if uring read/write behaves predictably. There is a precedent for this with sendmsg/recvmsg too. I welcome discussion on this point, but for certain, I believe Ruby being non-blocking by default makes sense and that approach was proposed by Eric, and I agreed with it and finally enabled it in Ruby 3. Since there is no outwardly visible change to behaviour, I didn't think it's a big problem, but I also noticed that Eric forced Unicorn IO back to blocking by default, so it might be nice to have is input too. ---------------------------------------- Bug #17664: Behavior of sockets changed in Ruby 3.0 to non-blocking https://bugs.ruby-lang.org/issues/17664#change-92514 * Author: ciconia (Sharon Rosner) * Status: Assigned * Priority: Normal * Assignee: ioquatix (Samuel Williams) * ruby -v: 3.0.0 * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN ---------------------------------------- I'm not sure this is a bug, but apparently a change was introduced in Ruby 3.0 that makes sockets non-blocking by default. This change was apparently introduced as part of the work on the [FiberScheduler interface](https://github.com/ruby/ruby/blame/78f188524f551c97b1a7a44ae13514729f1a21c7/ext/socket/init.c#L411-L434). This change of behaviour is not discussed in the Ruby 3.0.0 release notes. This change complicates the implementation of an io_uring-based fiber scheduler, since io_uring SQE's on fd's with `O_NONBLOCK` can return `EAGAIN` just like normal syscalls. Using io_uring with non-blocking fd's defeats the whole purpose of using io_uring in the first place. A workaround I have put in place in the Polyphony [io_uring backend](https://github.com/digital-fabric/polyphony/blob/d3c9cf3ddc1f414387948fa40e5f6a24f68bf045/ext/polyphony/backend_io_uring.c#L28-L47) is to make sure `O_NONBLOCK` is not set before attempting I/O operations on any fd. -- https://bugs.ruby-lang.org/ Unsubscribe: