summaryrefslogtreecommitdiff
path: root/ext/socket/rubysocket.h
AgeCommit message (Collapse)Author
2025-07-14merge revision(s) d77e02bd85ab7f841df8d473bac214b9a92a3506: [Backport #21497]Takashi Kokubun
[Bug #21497] [ruby/socket]: add full prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit otherwise, gcc 15 will complain: > init.c:573:19: error: too many arguments to function ‘Rconnect’; expected 0, have 3 > 573 | return (VALUE)Rconnect(arg->fd, arg->sockaddr, arg->len); > | ^~~~~~~~ ~~~~~~~ > In file included from init.c:11: > rubysocket.h:294:5: note: declared here > 294 | int Rconnect(); > | ^~~~~~~~ > sockssocket.c:33:9: error: too many arguments to function ‘SOCKSinit’; expected 0, have 1 > 33 | SOCKSinit("ruby"); > | ^~~~~~~~~ ~~~~~~ > In file included from sockssocket.c:11: > rubysocket.h:293:6: note: declared here > 293 | void SOCKSinit(); > | ^~~~~~~~~ Signed-off-by: Z. Liu <zhixu.liu@gmail.com>
2024-12-18Wrap `do_fast_fallback_getaddrinfo` with `rb_thread_prevent_fork` (#12366)Misaki Shioi
Wrap `do_fast_fallback_getaddrinfo` with `rb_thread_prevent_fork` Referencing PR #10864, wrap `do_fast_fallback_getaddrinfo` with `rb_thread_prevent_fork` to avoid fork safety issues. `do_fast_fallback_getaddrinfo` internally uses getaddrinfo(3), leading to fork safety issues, as described in PR #10864. This change ensures that `do_fast_fallback_getaddrinfo` is guarded by `rb_thread_prevent_fork`, preventing fork during its execution and avoiding related issues. Notes: Merged-By: shioimm <shioi.mm@gmail.com>
2024-12-14Improve APIs for Globally Enabling/Disabling fast_fallback in Socket (#12257)Misaki Shioi
This change includes the following updates: - Added an environment variable `RUBY_TCP_NO_FAST_FALLBACK` to control enabling/disabling fast_fallback - Updated documentation and man pages - Revised the implementation of Socket.tcp_fast_fallback= and Socket.tcp_fast_fallback, which previously performed dynamic name resolution of constants and variables. As a result, the following performance improvements were achieved: (Case of 1000 executions of `TCPSocket.new` to the local host) Rehearsal ----------------------------------------- before 0.031462 0.147946 0.179408 ( 0.249279) after 0.031164 0.146839 0.178003 ( 0.346935) -------------------------------- total: 0.178003sec user system total real before 0.027584 0.138712 0.166296 ( 0.233356) after 0.025953 0.127608 0.153561 ( 0.237971) Notes: Merged-By: shioimm <shioi.mm@gmail.com>
2024-12-11Use `rb_thread_fd_select` instead of select(2) (#12292)Misaki Shioi
* Use `rb_thread_fd_select` instead of select(2) For fixing https://bugs.ruby-lang.org/issues/20932 . `TCPSocket.new`, which internally uses select(2) for HEv2, can cause SEGV if the number of file descriptors exceeds `FD_SETSIZE`. This change avoids that issue by replacing select(2) with `rb_thread_fd_select`, which is provided as part of Ruby's internal API. --- This includes the following changes. * rb_thread_fd_select does not need common pipe Notes: Merged-By: shioimm <shioi.mm@gmail.com>
2024-12-03Fix use of getaddrinfo_shared->lockJohn Hawthorn
In some locations we were using shared->lock and in others &shared->lock, and we were leaking the allocated memory. Notes: Merged: https://github.com/ruby/ruby/pull/12239
2024-11-30Improve the conditions for clearing the Connection Attempt Delay upon ↵Misaki Shioi
connection failure (#12223) * Improve the conditions for clearing the Connection Attempt Delay upon connection failure This change addresses a case that was overlooked in ruby/ruby#12087. In the previous change, the Connection Attempt Delay was cleared at the point of a connection failure only if both of the following conditions were met: - No other sockets were attempting a connection - There were addresses still available to start a new connection In this update, the second condition has been removed. As a result, if name resolution succeeds after a connection failure and new addresses are obtained, it will be able to immediately attempt a connection to one of them. If there are no sockets attempting a connection, no addresses available for connection, and name resolution has completed, an exception will still be raised as before. --- Additionally, the following minor fixes have been made: * Refactor: Remove unnecessary members Notes: Merged-By: shioimm <shioi.mm@gmail.com>
2024-11-29Ensure to close pipes when `TCPSocket.new` finishes processing (#12181)Misaki Shioi
`TCPSocket.new` with HEv2 uses three threads. The last of these threads to exit closed pipes. However, if pipes were open at the end of the main thread, they would leak. This change avoids this by closing pipes at the end of the main thread. Notes: Merged-By: shioimm <shioi.mm@gmail.com>
2024-11-25Prevent memory leakYusuke Endoh
``` for (int i = 0; i < arg->family_size; i++) { arg->getaddrinfo_entries[i] = allocate_fast_fallback_getaddrinfo_entry(); if (!(arg->getaddrinfo_entries[i])) rb_syserr_fail(errno, "calloc(3)"); ``` If the allocation fails in the second interation, the memory allocated in the first iteration would be leaked. This change prevents the memory leak by allocating the memory in advance. (The struct name `fast_fallback_getaddrinfo_shared` might no longer be good.) Notes: Merged: https://github.com/ruby/ruby/pull/12163
2024-11-17Fix stack-use-after-return (#12105)Misaki Shioi
http://ci.rvm.jp/results/trunk_asan@ruby-sp1/5409001 ``` ================================================================= ==3263562==ERROR: AddressSanitizer: stack-use-after-return on address 0x735a8f190da8 at pc 0x735a6f58dabc bp 0x735a639ffd10 sp 0x735a639ffd08 READ of size 4 at 0x735a8f190da8 thread T211 ================================================================= ``` Notes: Merged-By: shioimm <shioi.mm@gmail.com>
2024-11-12[Feature #120782] Introduction of Happy Eyeballs Version 2 (RFC8305) in ↵Misaki Shioi
TCPSocket.new (#11653) * Introduction of Happy Eyeballs Version 2 (RFC8305) in TCPSocket.new This is an implementation of Happy Eyeballs version 2 (RFC 8305) in `TCPSocket.new`. See https://github.com/ruby/ruby/pull/11653 1. Background Prior to this implementation, I implemented Happy Eyeballs Version 2 (HEv2) for `Socket.tcp` in https://github.com/ruby/ruby/pull/9374. HEv2 is an algorithm defined in [RFC 8305](https://datatracker.ietf.org/doc/html/rfc8305), aimed at improving network connectivity. For more details on the specific cases that HEv2 helps, please refer to https://bugs.ruby-lang.org/issues/20108. 2. Proposal & Outcome This proposal implements the same HEv2 algorithm in `TCPSocket.new`. Since `TCPSocket.new` is used more widely than `Socket.tcp`, this change is expected to broaden the impact of HEv2's benefits. Like `Socket.tcp`, I have also added `fast_fallback` keyword argument to `TCPSocket.new`. This option is set to true by default, enabling the HEv2 functionality. However, users can explicitly set it to false to disable HEv2 and use the previous behavior of `TCPSocket.new`. It should be noted that HEv2 is enabled only in environments where pthreads are available. This specification follows the approach taken in https://bugs.ruby-lang.org/issues/19965 , where name resolution can be interrupted. (In environments where pthreads are not available, the `fast_fallback` option is ignored.) 3. Performance Below is the benchmark of 100 requests to `www.ruby-lang.org` with the fast_fallback option set to true and false, respectively. While there is a slight performance degradation when HEv2 is enabled, the degradation is smaller compared to that seen in `Socket.tcp`. ``` ~/s/build ❯❯❯ ../install/bin/ruby ../ruby/test.rb Rehearsal -------------------------------------------------------- fast_fallback: true 0.017588 0.097045 0.114633 ( 1.460664) fast_fallback: false 0.014033 0.078984 0.093017 ( 1.413951) ----------------------------------------------- total: 0.207650sec user system total real fast_fallback: true 0.020891 0.124054 0.144945 ( 1.473816) fast_fallback: false 0.018392 0.110852 0.129244 ( 1.466014) ``` * Update debug prints Co-authored-by: Nobuyoshi Nakada <nobu.nakada@gmail.com> * Remove debug prints * misc * Disable HEv2 in Win * Raise resolution error with hostname resolution * Fix to handle errors * Remove warnings * Errors that do not need to be handled * misc * Improve doc * Fix bug on cancellation * Avoid EAI_ADDRFAMILY for resolving IPv6 * Follow upstream * misc * Refactor connection_attempt_fds management - Introduced allocate_connection_attempt_fds and reallocate_connection_attempt_fds for improved memory allocation of connection_attempt_fds - Added remove_connection_attempt_fd to resize connection_attempt_fds dynamically. - Simplified the in_progress_fds function to only check the size of connection_attempt_fds. * Rename do_pthread_create to raddrinfo_pthread_create to avoid conflicting --------- Co-authored-by: Nobuyoshi Nakada <nobu.nakada@gmail.com> Notes: Merged-By: shioimm <shioi.mm@gmail.com>
2024-10-12Support `IO#timeout` for `rsock_connect`. (#11880)Samuel Williams
Notes: Merged-By: ioquatix <samuel@codeotaku.com>
2024-10-11Update `rsock_connect` to take `VALUE io` argument. (#11847)Samuel Williams
Notes: Merged-By: ioquatix <samuel@codeotaku.com>
2024-02-26Revise 9ec342e07df6aa5e2c2e9003517753a2f1b508fdNobuyoshi Nakada
2024-02-26[Bug #20296] Fix the default assertion messageNobuyoshi Nakada
2024-02-26Introduction of Happy Eyeballs Version 2 (RFC8305) in Socket.tcp (#9374)Misaki Shioi
* Introduction of Happy Eyeballs Version 2 (RFC8305) in Socket.tcp This is an implementation of Happy Eyeballs version 2 (RFC 8305) in Socket.tcp. [Background] Currently, `Socket.tcp` synchronously resolves names and makes connection attempts with `Addrinfo::foreach.` This implementation has the following two problems. 1. In name resolution, the program stops until the DNS server responds to all DNS queries. 2. In a connection attempt, while an IP address is trying to connect to the destination host and is taking time, the program stops, and other resolved IP addresses cannot try to connect. [Proposal] "Happy Eyeballs" ([RFC 8305](https://datatracker.ietf.org/doc/html/rfc8305)) is an algorithm to solve this kind of problem. It avoids delays to the user whenever possible and also uses IPv6 preferentially. I implemented it into `Socket.tcp` by using `Addrinfo.getaddrinfo` in each thread spawned per address family to resolve the hostname asynchronously, and using `Socket::connect_nonblock` to try to connect with multiple addrinfo in parallel. [Outcome] This change eliminates a fatal defect in the following cases. Case 1. One of the A or AAAA DNS queries does not return --- require 'socket' class Addrinfo class << self # Current Socket.tcp depends on foreach def foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, timeout: nil, &block) getaddrinfo(nodename, service, Socket::AF_INET6, socktype, protocol, flags, timeout: timeout) .concat(getaddrinfo(nodename, service, Socket::AF_INET, socktype, protocol, flags, timeout: timeout)) .each(&block) end def getaddrinfo(_, _, family, *_) case family when Socket::AF_INET6 then sleep when Socket::AF_INET then [Addrinfo.tcp("127.0.0.1", 4567)] end end end end Socket.tcp("localhost", 4567) --- Because the current `Socket.tcp` cannot resolve IPv6 names, the program stops in this case. It cannot start to connect with IPv4 address. Though `Socket.tcp` with HEv2 can promptly start a connection attempt with IPv4 address in this case. Case 2. Server does not promptly return ack for syn of either IPv4 / IPv6 address family --- require 'socket' fork do socket = Socket.new(Socket::AF_INET6, :STREAM) socket.setsockopt(:SOCKET, :REUSEADDR, true) socket.bind(Socket.pack_sockaddr_in(4567, '::1')) sleep socket.listen(1) connection, _ = socket.accept connection.close socket.close end fork do socket = Socket.new(Socket::AF_INET, :STREAM) socket.setsockopt(:SOCKET, :REUSEADDR, true) socket.bind(Socket.pack_sockaddr_in(4567, '127.0.0.1')) socket.listen(1) connection, _ = socket.accept connection.close socket.close end Socket.tcp("localhost", 4567) --- The current `Socket.tcp` tries to connect serially, so when its first name resolves an IPv6 address and initiates a connection to an IPv6 server, this server does not return an ACK, and the program stops. Though `Socket.tcp` with HEv2 starts to connect sequentially and in parallel so a connection can be established promptly at the socket that attempted to connect to the IPv4 server. In exchange, the performance of `Socket.tcp` with HEv2 will be degraded. --- 100.times { Socket.tcp("www.ruby-lang.org", 80) } --- This is due to the addition of the creation of IO objects, Thread objects, etc., and calls to `IO::select` in the implementation. * Avoid NameError of Socket::EAI_ADDRFAMILY in MinGW * Support Windows with SO_CONNECT_TIME * Improve performance I have additionally implemented the following patterns: - If the host is single-stack, name resolution is performed in the main thread. This reduces the cost of creating threads. - If an IP address is specified, name resolution is performed in the main thread. This also reduces the cost of creating threads. - If only one IP address is resolved, connect is executed in blocking mode. This reduces the cost of calling IO::select. Also, I have added a fast_fallback option for users who wish not to use HE. Here are the results of each performance test. ```ruby require 'socket' require 'benchmark' HOSTNAME = "www.ruby-lang.org" PORT = 80 ai = Addrinfo.tcp(HOSTNAME, PORT) Benchmark.bmbm do |x| x.report("Domain name") do 30.times { Socket.tcp(HOSTNAME, PORT).close } end x.report("IP Address") do 30.times { Socket.tcp(ai.ip_address, PORT).close } end x.report("fast_fallback: false") do 30.times { Socket.tcp(HOSTNAME, PORT, fast_fallback: false).close } end end ``` ``` user system total real Domain name 0.015567 0.032511 0.048078 ( 0.325284) IP Address 0.004458 0.014219 0.018677 ( 0.284361) fast_fallback: false 0.005869 0.021511 0.027380 ( 0.321891) ```` And this is the measurement result when executed in a single stack environment. ``` user system total real Domain name 0.007062 0.019276 0.026338 ( 1.905775) IP Address 0.004527 0.012176 0.016703 ( 3.051192) fast_fallback: false 0.005546 0.019426 0.024972 ( 1.775798) ``` The following is the result of the run on Ruby 3.3.0. (on Dual stack environment) ``` user system total real Ruby 3.3.0 0.007271 0.027410 0.034681 ( 0.472510) ``` (on Single stack environment) ``` user system total real Ruby 3.3.0 0.005353 0.018898 0.024251 ( 1.774535) ``` * Do not cache `Socket.ip_address_list` As mentioned in the comment at https://github.com/ruby/ruby/pull/9374#discussion_r1482269186, caching Socket.ip_address_list does not follow changes in network configuration. But if we stop caching, it becomes necessary to check every time `Socket.tcp` is called whether it's a single stack or not, which could further degrade performance in the case of a dual stack. From this, I've changed the approach so that when a domain name is passed, it doesn't check whether it's a single stack or not and resolves names in parallel each time. The performance measurement results are as follows. require 'socket' require 'benchmark' HOSTNAME = "www.ruby-lang.org" PORT = 80 ai = Addrinfo.tcp(HOSTNAME, PORT) Benchmark.bmbm do |x| x.report("Domain name") do 30.times { Socket.tcp(HOSTNAME, PORT).close } end x.report("IP Address") do 30.times { Socket.tcp(ai.ip_address, PORT).close } end x.report("fast_fallback: false") do 30.times { Socket.tcp(HOSTNAME, PORT, fast_fallback: false).close } end end user system total real Domain name 0.004085 0.011873 0.015958 ( 0.330097) IP Address 0.000993 0.004400 0.005393 ( 0.257286) fast_fallback: false 0.001348 0.008266 0.009614 ( 0.298626) * Wait forever if fallback addresses are unresolved, unless resolv_timeout Changed from waiting only 3 seconds for name resolution when there is no fallback address available, to waiting as long as there is no resolv_timeout. This is in accordance with the current `Socket.tcp` specification. * Use exact pattern to match IPv6 address format for specify address family
2023-11-30Rename rsock_raise_socket_error to rsock_raise_resolution_errorMisaki Shioi
Again, rsock_raise_socket_error is called only when getaddrinfo and getaddrname fail
2023-11-30Add Socket::ResolutionError & Socket::ResolutionError#error_codeMisaki Shioi
Socket::ResolutionError#error_code returns Socket::EAI_XXX
2023-08-30BasicSocket#recv* return `nil` rather than an empty packetJean Boussier
[Bug #19012] man recvmsg(2) states: > Return Value > These calls return the number of bytes received, or -1 if an error occurred. > The return value will be 0 when the peer has performed an orderly shutdown. Not too sure how one is supposed to make the difference between a packet of size 0 and a closed connection. Notes: Merged: https://github.com/ruby/ruby/pull/6407
2022-11-17Add support for `sockaddr_un` on Windows. (#6513)Samuel Williams
* Windows: Fix warning about undefined if_indextoname() * Windows: Fix UNIXSocket on MINGW and make .pair more reliable * Windows: Use nonblock=true for read tests with scheduler * Windows: Move socket detection from File.socket? to File.stat Add S_IFSOCK to Windows and interpret reparse points accordingly. Enable tests that work now. * Windows: Use wide-char functions to UNIXSocket This fixes behaviour with non-ASCII characters. It also fixes deletion of temporary UNIXSocket.pair files. * Windows: Add UNIXSocket tests for specifics of Windows impl. * Windows: fix VC build due to missing _snwprintf Avoid usage of _snwprintf, since it fails linking ruby.dll like so: linking shared-library x64-vcruntime140-ruby320.dll x64-vcruntime140-ruby320.def : error LNK2001: unresolved external symbol snwprintf x64-vcruntime140-ruby320.def : error LNK2001: unresolved external symbol vsnwprintf_l whereas linking miniruby.exe succeeds. This patch uses snprintf on the UTF-8 string instead. Also remove branch GetWindowsDirectoryW, since it doesn't work. * Windows: Fix dangling symlink test failures Co-authored-by: Lars Kanis <kanis@comcard.de> Notes: Merged-By: ioquatix <samuel@codeotaku.com>
2022-07-21Expand tabs [ci skip]Takashi Kokubun
[Misc #18891] Notes: Merged: https://github.com/ruby/ruby/pull/6094
2021-06-22Deprecate and rework old (fd) centric functions.Samuel Williams
Notes: Merged: https://github.com/ruby/ruby/pull/4592
2021-06-22Direct io for accept, send, sendmsg, recvfrom, and related methods.Samuel Williams
Notes: Merged: https://github.com/ruby/ruby/pull/4477
2021-06-14Add scheduler hook `Addrinfo.getaddrinfo`. (#4375)Samuel Williams
Co-authored-by: Bruno Sutic <code@brunosutic.com> Notes: Merged-By: ioquatix <samuel@codeotaku.com>
2020-12-10Add connect_timeout to TCPSocketMasaki Matsushita
Add connect_timeout to TCPSocket.new in the same way as Socket.tcp. Closes [Feature #17187]
2020-12-07Revert getaddrinfo_a()Masaki Matsushita
getaddrinfo_a() gets stuck after fork(). To avoid this, we need 1 second sleep to wait for internal worker threads of getaddrinfo_a() to be finished, but that is unacceptable. [Bug #17220] [Feature #17134] [Feature #17187]
2020-11-01ext/socket/rubysocket.h: avoid the conflict of T_DATA definition in AIXRei Odaira
2020-09-25Add resolve_timeout to TCPSocket [Feature #17134]Masaki Matsushita
2020-08-27Make Socket.getaddrinfo interruptible (#2827)Kir Shatrov
Before, Socket.getaddrinfo was using a blocking getaddrinfo(3) call. That didn't allow to wrap it into Timeout.timeout or interrupt the thread in any way. Combined with the default 10 sec resolv timeout on many Unix systems, this can have a very noticeable effect on production Ruby apps being not resilient to DNS outages and timing out name resolution, and being unable to fail fast even with Timeout.timeout. Since we already have support for getaddrinfo_a(3), the async version of getaddrinfo, we should be able to make Socket.getaddrinfo leverage that when getaddrinfo_a version is available in the system (hence #ifdef HAVE_GETADDRINFO_A). Related tickets: https://bugs.ruby-lang.org/issues/16476 https://bugs.ruby-lang.org/issues/16381 https://bugs.ruby-lang.org/issues/14997 Notes: Merged-By: mmasaki <glass.saga@gmail.com>
2020-05-14Thread scheduler for light weight concurrency.Samuel Williams
Notes: Merged: https://github.com/ruby/ruby/pull/3032 Merged-By: ioquatix <samuel@codeotaku.com>
2020-04-08Merge pull request #2991 from shyouhei/ruby.h卜部昌平
Split ruby.h Notes: Merged-By: shyouhei <shyouhei@ruby-lang.org>
2019-12-26decouple internal.h headers卜部昌平
Saves comitters' daily life by avoid #include-ing everything from internal.h to make each file do so instead. This would significantly speed up incremental builds. We take the following inclusion order in this changeset: 1. "ruby/config.h", where _GNU_SOURCE is defined (must be the very first thing among everything). 2. RUBY_EXTCONF_H if any. 3. Standard C headers, sorted alphabetically. 4. Other system headers, maybe guarded by #ifdef 5. Everything else, sorted alphabetically. Exceptions are those win32-related headers, which tend not be self- containing (headers have inclusion order dependencies). Notes: Merged: https://github.com/ruby/ruby/pull/2711
2018-11-29disable non-blocking pipes and sockets by defaultnormal
There seems to be a compatibility problems with Rails + Rack::Deflater; so we revert this incompatibility. This effectively reverts r65922; but keeps the bugfixes to better support non-blocking sockets and pipes for future use. [Bug #15356] [Bug #14968] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66093 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-22socket: disable nonblocking-by-default on win32normal
Perhaps this fixes test failures reported by Greg and k0kubun. However, the failure of certain tests to handle non-blocking I/O seems to indicate pre-existing problems on win32 platforms. Somebody knowledgeable about win32 should be able to fix it. [ruby-core:89973] [ruby-core:89976] [ruby-core:89977] [Bug #14968] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65929 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-22io + socket: make pipes and sockets nonblocking by defaultnormal
All normal Ruby IO methods (IO#read, IO#gets, IO#write, ...) are all capable of appearing to be "blocking" when presented with a file description with the O_NONBLOCK flag set; so there is little risk of incompatibility within Ruby-using programs. The biggest compatibility risk is when spawning external programs. As a result, stdin, stdout, and stderr are now always made blocking before exec-family calls. This change will make an event-oriented MJIT usable if it is waiting on pipes on POSIX_like platforms. It is ALSO necessary to take advantage of (proposed lightweight concurrency (aka "auto-Fiber") or any similar proposal for network concurrency: https://bugs.ruby-lang.org/issues/13618 Named-pipe (FIFO) are NOT yet non-blocking by default since they are rarely-used and may introduce compatibility problems and extra syscall overhead for a common path. Please revert this commit if there are problems and if I am afk since I am afk a lot, lately. [ruby-core:89950] [Bug #14968] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65922 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-11Use friendlier terminology in rubysocket.h commentnobu
[Fix GH-2008] From: Juanito Fatas <juanito.fatas@shopify.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65662 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-11Revert "Use friendlier terminology in rubysocket.h comment"nobu
This reverts commit dcd41bbbdb021b5e0e74f8a33c2c58cecf595f29. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65661 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-11Use friendlier terminology in rubysocket.h commentnobu
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65660 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27socket: fix BasicSocket#*_nonblock buffering bugs from r58400normal
IO#read_nonblock and IO#write_nonblock take into account buffered data, so the Linux-only BasicSocket#read_nonblock and BasicSocket#write_nonblock methods must, too. This bug was only introduced in r58400 ("socket: avoid fcntl for read/write_nonblock on Linux") and does not affect any stable release. * ext/socket/basicsocket.c (rsock_init_basicsocket): * ext/socket/init.c (rsock_s_recvfrom_nonblock): * ext/socket/init.c (rsock_init_socket_init): * ext/socket/lib/socket.rb (def read_nonblock): * ext/socket/lib/socket.rb (def write_nonblock): * ext/socket/rubysocket.h (static inline void rsock_maybe_wait_fd): * test/socket/test_basicsocket.rb (def test_read_write_nonblock): [Feature #13362] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60496 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-08-02socket/option.c: inet_ntopnobu
* ext/socket/option.c, ext/socket/rubysocket.h (inet_ntop): share the fallback definition. [ruby-core:76646] [Bug #12645] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55797 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-24Drop support for BeOSnobu
* beos: Drop support for BeOS now that Haiku is stable. [Fix GH-1112] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52731 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-23Haiku now best effort supportnobu
* configure.in: remove obsolete workarounds for Haiku. * dln.c, file.c, io.c: remove obsolete Haiku workarounds. * thread_pthread.c: add stack bounds detection for Haiku. * signal.c: get stack pointer from signal context on Haiku. [ruby-core:67923] [Bug #10811] [Fix GH-1109] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52721 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-17socket: avoid arg parsing in bsock_sendmsg_internalnormal
* ext/socket/ancdata.c (bsock_sendmsg_internal): avoid arg parsing [ruby-core:71439] [Feature #11339] (rsock_bsock_sendmsg): make private, adjust for above (rsock_bsock_sendmsg_nonblock): ditto * ext/socket/rubysocket.h: adjust prototypes (rsock_opt_false_p): remove * ext/socket/basicsocket.c (rsock_init_basicsocket): define private methods * ext/socket/lib/socket.rb (BasicSocket#sendmsg): new wrapper (BasicSocket#sendmsg_nonblock): ditto target 0: a (ruby 2.3.0dev (2015-11-12 trunk 52550) [x86_64-linux]) target 1: b (ruby 2.3.0dev (2015-11-12 avoid-kwarg-capi 52550) [x86_64-linux] ----------------------------------------------------------- sendmsg_nonblock require 'socket' nr = 1_000_000 i = 0 msg = '.' buf = '.' begin r, w = UNIXSocket.pair(:SEQPACKET) while i < nr i += 1 w.sendmsg_nonblock(msg, exception: false) r.recv(1, 0, buf) end ensure r.close w.close end ----------------------------------------------------------- raw data: [["sendmsg_nonblock", [[1.875997293740511, 1.8452614955604076, 1.8449317328631878, 1.8418389447033405, 1.869386937469244], [1.5175109766423702, 1.4987873211503029, 1.4989623799920082, 1.47918451577425, 1.5017359890043736]]]] Elapsed time: 16.775453245 (sec) ----------------------------------------------------------- benchmark results: minimum results in each 5 measurements. Execution time (sec) name a b sendmsg_nonblock 1.842 1.479 Speedup ratio: compare with the result of `a' (greater is better) name b sendmsg_nonblock 1.245 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-17socket (bsock_recvmsg_internal): avoid arg parsingnormal
* ext/socket/ancdata.c (bsock_recvmsg_internal): avoid arg parsing (rsock_bsock_recvmsg): adjust for above change (rsock_bsock_recvmsg_nonblock): ditto [ruby-core:71439] [Feature #11339] * ext/socket/rubysocket.h: adjust prototypes for above * ext/socket/basicsocket.c (rsock_init_basicsocket): adjust private methods * ext/socket/lib/socket.rb (BasicSocket#recvmsg): wrapper method (BasicSocket#recvmsg_nonblock): ditto target 0: a (ruby 2.3.0dev (2015-11-12 trunk 52550) [x86_64-linux]) target 1: b (ruby 2.3.0dev (2015-11-12 avoid-kwarg-capi 52550) [x86_64-linux] ----------------------------------------------------------- recvmsg_nonblock require 'socket' nr = 1_000_000 i = 0 msg = '.' buf = '.' begin r, w = UNIXSocket.pair(:SEQPACKET) while i < nr i += 1 w.sendmsg(msg) r.recvmsg_nonblock(1, exception: false) end ensure r.close w.close end ----------------------------------------------------------- raw data: [["recvmsg_nonblock", [[3.721687912940979, 3.6072621569037437, 3.580637402832508, 3.614185404032469, 3.6029579415917397], [2.4694008752703667, 2.4908322244882584, 2.5051278844475746, 2.5037173740565777, 2.548359278589487]]]] Elapsed time: 30.646087052 (sec) ----------------------------------------------------------- benchmark results: minimum results in each 5 measurements. Execution time (sec) name a b recvmsg_nonblock 3.581 2.469 Speedup ratio: compare with the result of `a' (greater is better) name b recvmsg_nonblock 1.450 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52602 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-16socket: avoid arg parsing in rsock_s_accept_nonblocknormal
* ext/socket/init.c (rsock_s_accept_nonblock): avoid parsing args [ruby-core:71439] [Feature #11339] * ext/socket/rubysocket.h: adjust prototype * ext/socket/socket.c (sock_accept_nonblock): make private * ext/socket/tcpserver.c (tcp_accept_nonblock): ditto * ext/socket/unixserver.c (unix_accept_nonblock): ditto * ext/socket/lib/socket.rb (Socket#accept_nonblock): implement as wrapper, move RDoc (TCPServer#accept_nonblock): ditto (UNIXServer#accept_nonblock): ditto target 0: a (ruby 2.3.0dev (2015-11-12 trunk 52550) [x86_64-linux]) target 1: b (ruby 2.3.0dev (2015-11-12 avoid-kwarg-capi 52550) [x86_64-linux] ----------------------------------------------------------- accept_nonblock require 'tempfile' require 'socket' require 'io/wait' nr = 500000 Tempfile.create(%w(accept_nonblock .sock)) do |tmp| path = tmp.path File.unlink(path) s = UNIXServer.new(path) addr = Socket.sockaddr_un(path).freeze nr.times do s.accept_nonblock(exception: false) c = UNIXSocket.new(path) s.wait_readable s.accept_nonblock(exception: false).close c.close end end ----------------------------------------------------------- raw data: [["accept_nonblock", [[4.807877402752638, 4.930681671947241, 4.738454818725586, 4.69268161803484, 4.684675686061382], [4.253904823213816, 4.255124930292368, 4.295955188572407, 4.248479191213846, 4.213303029537201]]]] Elapsed time: 45.123040065 (sec) ----------------------------------------------------------- benchmark results: minimum results in each 5 measurements. Execution time (sec) name a b accept_nonblock 4.685 4.213 Speedup ratio: compare with the result of `a' (greater is better) name b accept_nonblock 1.112 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52601 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-16socket: avoid arg parsing in rsock_s_recvfrom_nonblocknormal
* ext/socket/init.c (rsock_s_recvfrom_nonblock): avoid arg parsing with C API [ruby-core:71439] [Feature #11339] * ext/socket/basicsocket.c (bsock_recv_nonblock): adjust for above change, make private * ext/socket/socket.c (sock_recvfrom_nonblock): ditto * ext/socket/udpsocket.c (udp_recvfrom_nonblock): ditto * ext/socket/lib/socket.rb (BasicSocket#recv_nonblock): new wrapper for private method, move RDoc (Socket#recvfrom_nonblock): ditto (UDPSocket#recvfrom_nonblock): ditto Note, not adding bm_recv_nonblock.rb to benchmark/ directory since it is non-portable. It is only in this commit message. Benchmark results + code target 0: a (ruby 2.3.0dev (2015-11-12 trunk 52540) [x86_64-linux]) target 1: b (ruby 2.3.0dev (2015-11-12 avoid-kwarg-capi 52540) [x86_64-linux] ----------------------------------------------------------- recv_nonblock require 'socket' nr = 1000000 msg = 'hello world' buf = '' size = msg.bytesize UNIXSocket.pair(:SEQPACKET) do |a, b| nr.times do a.sendmsg(msg) b.recv_nonblock(size, 0, buf, exception: false) end end ----------------------------------------------------------- raw data: [["recv_nonblock", [[1.83511221408844, 1.8703329525887966, 1.8448856547474861, 1.859263762831688, 1.8331583738327026], [1.5637447573244572, 1.4062932096421719, 1.4247371144592762, 1.4108827747404575, 1.4802536629140377]]]] Elapsed time: 16.530452496 (sec) ----------------------------------------------------------- benchmark results: minimum results in each 5 measurements. Execution time (sec) name a b recv_nonblock 1.833 1.406 Speedup ratio: compare with the result of `a' (greater is better) name b recv_nonblock 1.304 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52598 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-10-24* configure.in: fixed build failure of Haiku.hsbt
[fix GH-984] Patch by @kallisti5 * ext/socket/getaddrinfo.c: ditto. * ext/socket/getnameinfo.c: ditto. * ext/socket/rubysocket.h: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52270 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-10-13rsock_addrinfo: specify address familynobu
* ext/socket/rsock_addrinfo (rsock_addrinfo): specify address family. [Fix GH-1052] * ext/socket/udpsocket.c (udp_connect, udp_bind, udp_send): address family by the receiver. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52117 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-02socket: memoize common socket families in fptr->modenormal
This provides a minor speedup by avoiding an extra syscall require 'socket' require 'benchmark' nr = 100000 msg = 'hello world' buf = '' size = msg.bytesize puts(Benchmark.measure do UNIXSocket.pair(:SEQPACKET) do |a, b| nr.times do a.sendmsg_nonblock(msg, 0, exception: false) b.recv(size, 0, buf) end end end) user system total real before: 0.330000 0.340000 0.670000 ( 0.678235) after: 0.290000 0.240000 0.530000 ( 0.534527) * ext/socket/rubysocket.h: flags for common socket families (rsock_getfamily): update signature * include/ruby/io.h: comment socket FMODE flags * ext/socket/init.c (rsock_getfamily): memoize family * ext/socket/basicsocket.c: adjust rsock_getfamily calls * ext/socket/ancdata.c: ditto [ruby-core:69713] [Feature #11298] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51097 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-15socket: allow exception-free nonblocking sendmsg/recvmsgnormal
As documented before, exceptions are expensive and IO::Wait*able are too common in socket applications to be the exceptional case. Datagram sockets deserve the same API which stream sockets are allowed with read_nonblock and write_nonblock. Note: this does not offer a performance advantage under optimal conditions when both ends are equally matched in speed, but it it does make debug output cleaner by avoiding exceptions whenever the receiver slows down. * ext/socket/ancdata.c (bsock_sendmsg_internal, bsock_recvmsg_internal): support "exception: false" kwarg * ext/socket/init.c (rsock_s_recvfrom_nonblock): ditto * ext/socket/init.c (rsock_s_recvfrom_nonblock): use rsock_opt_false_p * ext/socket/socket.c (sock_connect_nonblock): ditto * ext/socket/rubysocket.h (rsock_opt_false_p): new function * ext/socket/basicsocket.c (bsock_recv_nonblock): update rdoc * ext/socket/udpsocket.c (udp_recvfrom_nonblock): ditto * test/socket/test_nonblock.rb: new tests [ruby-core:69542] [Feature #11229] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50910 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-05-29socket: avoid redundant fcntl on Linuxnormal
* ext/socket/ancdata.c (bsock_sendmsg_internal, bsock_recvmsg_internal): avoid redundant fcntl on Linux [ruby-core:69154] [Feature #11145] * ext/socket/init.c (rsock_s_recvfrom_nonblock): ditto * ext/socket/rubysocket.h (MSG_DONTWAIT_RELIABLE): new macro MSG_DONTWAIT is enough to force non-blocking I/O under Linux, so avoid changing the state of a socket. This will allow certain threads to do a non-destructive non-blocking "peek" while others block (without relying on an extra ppoll syscall). We shall be conservative about enabling this feature since some OSes may have incomplete support for MSG_DONTWAIT. I shall defer to a FreeBSD expert to enable that for FreeBSD. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50666 b2dd03c8-39d4-4d8f-98ff-823fe69b080e