
"ioquatix (Samuel Williams) via ruby-core" <ruby-core@ml.ruby-lang.org> wrote:
Issue #19057 has been updated by ioquatix (Samuel Williams).
Why don't you reconsider the "nested public interface" approach?
My assessment of this approach is that it would require a rewrite of all internal code that accesses `rb_io_t` internals. Rewriting code isn't a problem, but it takes a lot of time and effort that I don't have in abundance right now. Additionally, it's still only a partial solution. One of the issues is accessing the file descriptor directly and the handling of `IO#close` from a different thread/fiber. Using the file descriptor directly can be problematic.
Again, why not the container_of solution I proposed? It shouldn't be that much for you since the relevant core internals could be divorced from extensions and significantly less work for stressed out and overworked downstream maintainers. Cross-thread IO#close or close(2) is a PITA to deal with portably if another thread is using that FD in any way. This applies to pure C projects, too, not just Ruby ones. Either: 1) ensure only one thread operates on a given FD and closes it; this is typical for stream FDs. 2) get all threads to abandon the FD before closing it. I do this for thread-shared packetized FDs which are analogous to Queue (O_DIRECT pipe, SOCK_SEQPACKET, listen sockets, kqueue/epoll FDs, etc...). Atomics + out-of-band (pthread_kill) signaling work for both cases. I've also used sentinel values in-band for packetized FDs (analogous to pushing `:stop' messages into a thread-shared Queue, like forcing a connect() in one thread to get blocking accept() to wake up; or adding an (eventfd||pipe) into a (kqueue||epoll) from another thread (it's 100% safe to EPOLL_CTL_ADD||EV_ADD from different threads and I've been abusing this safety for well over a decade)
Ruby lost numerous users due to a never-ending stream of incompatibilities introduced every year.
Compatibility and progress are always something to balance out. I think on the whole, Ruby does a pretty decent job at it. Lack of forward progress also causes users to look elsewhere as the language stagnates. So this isn't just. a matter of "preserve compatibility at all costs", as those costs will be the same. The hard part is finding the middle ground of compatibility and progress. Both compatibility at any cost, and progress at any cost, are naive statements.
git and Linux kernel do a pretty good job at maintaining compatibility while adding new features. OTOH some of the incompatibility proposals for Perl 5 have made me look into writing more C...