<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/ext/socket/rubysocket.h, branch v3_4_9</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>merge revision(s) d77e02bd85ab7f841df8d473bac214b9a92a3506: [Backport #21497]</title>
<updated>2025-07-14T21:48:27+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2025-07-14T21:48:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=782aef10bbdb63aba6d71e4f5f1876888c70efcb'/>
<id>782aef10bbdb63aba6d71e4f5f1876888c70efcb</id>
<content type='text'>
	[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:

	&gt; init.c:573:19: error: too many arguments to function ‘Rconnect’; expected 0, have 3
	&gt;   573 |     return (VALUE)Rconnect(arg-&gt;fd, arg-&gt;sockaddr, arg-&gt;len);
	&gt;       |                   ^~~~~~~~ ~~~~~~~
	&gt; In file included from init.c:11:
	&gt; rubysocket.h:294:5: note: declared here
	&gt;   294 | int Rconnect();
	&gt;       |     ^~~~~~~~

	&gt; sockssocket.c:33:9: error: too many arguments to function ‘SOCKSinit’; expected 0, have 1
	&gt;    33 |         SOCKSinit("ruby");
	&gt;       |         ^~~~~~~~~ ~~~~~~
	&gt; In file included from sockssocket.c:11:
	&gt; rubysocket.h:293:6: note: declared here
	&gt;   293 | void SOCKSinit();
	&gt;       |      ^~~~~~~~~

	Signed-off-by: Z. Liu &lt;zhixu.liu@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[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:

	&gt; init.c:573:19: error: too many arguments to function ‘Rconnect’; expected 0, have 3
	&gt;   573 |     return (VALUE)Rconnect(arg-&gt;fd, arg-&gt;sockaddr, arg-&gt;len);
	&gt;       |                   ^~~~~~~~ ~~~~~~~
	&gt; In file included from init.c:11:
	&gt; rubysocket.h:294:5: note: declared here
	&gt;   294 | int Rconnect();
	&gt;       |     ^~~~~~~~

	&gt; sockssocket.c:33:9: error: too many arguments to function ‘SOCKSinit’; expected 0, have 1
	&gt;    33 |         SOCKSinit("ruby");
	&gt;       |         ^~~~~~~~~ ~~~~~~
	&gt; In file included from sockssocket.c:11:
	&gt; rubysocket.h:293:6: note: declared here
	&gt;   293 | void SOCKSinit();
	&gt;       |      ^~~~~~~~~

	Signed-off-by: Z. Liu &lt;zhixu.liu@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Wrap `do_fast_fallback_getaddrinfo` with `rb_thread_prevent_fork` (#12366)</title>
<updated>2024-12-18T00:48:26+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-12-18T00:48:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=498d6eb114c52bd16a6821029959e88ed8f87396'/>
<id>498d6eb114c52bd16a6821029959e88ed8f87396</id>
<content type='text'>
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.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.</pre>
</div>
</content>
</entry>
<entry>
<title>Improve APIs for Globally Enabling/Disabling fast_fallback in Socket (#12257)</title>
<updated>2024-12-14T06:51:19+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-12-14T06:51:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=9f924e2f13992241c447190a9eb139bf46dcb8d9'/>
<id>9f924e2f13992241c447190a9eb139bf46dcb8d9</id>
<content type='text'>
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)</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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)</pre>
</div>
</content>
</entry>
<entry>
<title>Use `rb_thread_fd_select` instead of select(2) (#12292)</title>
<updated>2024-12-11T09:57:23+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-12-11T09:57:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f9601903f64e56d95c140074980584c09373b040'/>
<id>f9601903f64e56d95c140074980584c09373b040</id>
<content type='text'>
* 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</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* 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</pre>
</div>
</content>
</entry>
<entry>
<title>Fix use of getaddrinfo_shared-&gt;lock</title>
<updated>2024-12-03T18:03:59+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2024-12-03T03:41:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=e20904d7cff727f14559acd39f5279fed816553d'/>
<id>e20904d7cff727f14559acd39f5279fed816553d</id>
<content type='text'>
In some locations we were using shared-&gt;lock and in others
&amp;shared-&gt;lock, and we were leaking the allocated memory.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In some locations we were using shared-&gt;lock and in others
&amp;shared-&gt;lock, and we were leaking the allocated memory.
</pre>
</div>
</content>
</entry>
<entry>
<title>Improve the conditions for clearing the Connection Attempt Delay upon connection failure (#12223)</title>
<updated>2024-11-30T09:51:53+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-11-30T09:51:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3d07754ee2c707343f79321b0fd358af3154709f'/>
<id>3d07754ee2c707343f79321b0fd358af3154709f</id>
<content type='text'>
* 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</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* 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</pre>
</div>
</content>
</entry>
<entry>
<title>Ensure to close pipes when `TCPSocket.new` finishes processing (#12181)</title>
<updated>2024-11-29T09:49:02+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-11-29T09:49:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=49d2e79fb0dd57caed269c67660ff4cc68b3d729'/>
<id>49d2e79fb0dd57caed269c67660ff4cc68b3d729</id>
<content type='text'>
`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.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`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.</pre>
</div>
</content>
</entry>
<entry>
<title>Prevent memory leak</title>
<updated>2024-11-25T11:18:48+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2024-11-25T09:23:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=92585898fb369c79e7f711465e5934ff4c1879f9'/>
<id>92585898fb369c79e7f711465e5934ff4c1879f9</id>
<content type='text'>
```
for (int i = 0; i &lt; arg-&gt;family_size; i++) {
    arg-&gt;getaddrinfo_entries[i] = allocate_fast_fallback_getaddrinfo_entry();
    if (!(arg-&gt;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.)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
```
for (int i = 0; i &lt; arg-&gt;family_size; i++) {
    arg-&gt;getaddrinfo_entries[i] = allocate_fast_fallback_getaddrinfo_entry();
    if (!(arg-&gt;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.)
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix stack-use-after-return (#12105)</title>
<updated>2024-11-17T01:36:33+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-11-17T01:36:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3c30af77fea37a10b95a3fc322ff20d7086cab5f'/>
<id>3c30af77fea37a10b95a3fc322ff20d7086cab5f</id>
<content type='text'>
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
=================================================================
```</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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
=================================================================
```</pre>
</div>
</content>
</entry>
<entry>
<title>[Feature #120782] Introduction of Happy Eyeballs Version 2 (RFC8305) in TCPSocket.new (#11653)</title>
<updated>2024-11-12T01:06:48+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-11-12T01:06:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4c270200dbc2a3a4511e8b793a033078afd6fb31'/>
<id>4c270200dbc2a3a4511e8b793a033078afd6fb31</id>
<content type='text'>
* 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 &amp; 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 &lt;nobu.nakada@gmail.com&gt;

* 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 &lt;nobu.nakada@gmail.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* 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 &amp; 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 &lt;nobu.nakada@gmail.com&gt;

* 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 &lt;nobu.nakada@gmail.com&gt;</pre>
</div>
</content>
</entry>
</feed>
