<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/ext/socket, branch v4.0.4</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Fix: Specifying 0 should cause an immediate timeout (#15641)</title>
<updated>2025-12-19T06:44:35+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2025-12-19T06:44:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=47244b0f306161f175b21f74d801882e950e18be'/>
<id>47244b0f306161f175b21f74d801882e950e18be</id>
<content type='text'>
This change fixes a bug in which specifying 0 for timeout-related options (such as the `timeout` option of `Addrinfo.getaddrinfo`) incorrectly results in an infinite wait.

(This change overwrites https://github.com/ruby/ruby/pull/15626 .)</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This change fixes a bug in which specifying 0 for timeout-related options (such as the `timeout` option of `Addrinfo.getaddrinfo`) incorrectly results in an infinite wait.

(This change overwrites https://github.com/ruby/ruby/pull/15626 .)</pre>
</div>
</content>
</entry>
<entry>
<title>Fix: Do not check open_timeout twice (#15626)</title>
<updated>2025-12-19T03:12:12+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2025-12-19T03:12:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=42d66b894cdfa356ed67af3000f79f7b2e9185fe'/>
<id>42d66b894cdfa356ed67af3000f79f7b2e9185fe</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Add host information to timeout error messages in `TCPSocket.new` and `Socket.tcp` (#15582)</title>
<updated>2025-12-17T07:16:32+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2025-12-17T07:16:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=54d3945ee53fa29186c6aa44f673a3a5ec3b38d9'/>
<id>54d3945ee53fa29186c6aa44f673a3a5ec3b38d9</id>
<content type='text'>
This change adds host information to the error messages shown when a timeout occurs while passing timeout options to `TCPSocket.new` or `Socket.tcp`, for improved usability.
(When the `fast_fallback option` is enabled, there may be multiple possible destinations, so the host name is shown instead of an IP address.)

As part of this change, the error messages in `Addrinfo.getaddrinfo` and `Addrinfo#connect_internal`, both of which are used by `Socket.tcp`, have also been improved in the same way.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This change adds host information to the error messages shown when a timeout occurs while passing timeout options to `TCPSocket.new` or `Socket.tcp`, for improved usability.
(When the `fast_fallback option` is enabled, there may be multiple possible destinations, so the host name is shown instead of an IP address.)

As part of this change, the error messages in `Addrinfo.getaddrinfo` and `Addrinfo#connect_internal`, both of which are used by `Socket.tcp`, have also been improved in the same way.</pre>
</div>
</content>
</entry>
<entry>
<title>`Socket.tcp` and `TCPSocket.new` raises `IO::TiemoutError` with user specified timeout (#15602)</title>
<updated>2025-12-17T06:02:26+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2025-12-17T06:02:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7b5691c3b000c763faa282e1f73db96afa2ecae1'/>
<id>7b5691c3b000c763faa282e1f73db96afa2ecae1</id>
<content type='text'>
* `Socket.tcp` and `TCPSocket.new` raises `IO::TiemoutError` with user specified timeout

In https://github.com/ruby/ruby/pull/11880, `rsock_connect()` was changed to raise `IO::TimeoutError` when a user-specified timeout occurs.
However, when `TCPSocket.new` attempts to connect to multiple destinations, it does not use `rsock_connect()`, and instead raises `Errno::ETIMEDOUT` on timeout.
As a result, the exception class raised on timeout could differ depending on whether there were multiple destinations or not.

To align this behavior with the implementation of `rsock_connect()`, this change makes `TCPSocket.new` raise `IO::TimeoutError` when a user-specified timeout occurs.
Similarly, `Socket.tcp` is updated to raise `IO::TimeoutError` when a timeout occurs within the method.
(Note that the existing behavior of `Addrinfo#connect_internal`, which Socket.tcp depends on internally and which raises `Errno::ETIMEDOUT` on timeout, is not changed.)

* [ruby/net-http] Raise `Net::OpenTimeout` when `TCPSocket.open` raises `IO::TimeoutError`.

With the changes in https://github.com/ruby/ruby/pull/15602, `TCPSocket.open` now raises `IO::TimeoutError` when a user-specified timeout occurs.
This change updates #connect to handle this case accordingly.

https://github.com/ruby/net-http/commit/f64109e1cf</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* `Socket.tcp` and `TCPSocket.new` raises `IO::TiemoutError` with user specified timeout

In https://github.com/ruby/ruby/pull/11880, `rsock_connect()` was changed to raise `IO::TimeoutError` when a user-specified timeout occurs.
However, when `TCPSocket.new` attempts to connect to multiple destinations, it does not use `rsock_connect()`, and instead raises `Errno::ETIMEDOUT` on timeout.
As a result, the exception class raised on timeout could differ depending on whether there were multiple destinations or not.

To align this behavior with the implementation of `rsock_connect()`, this change makes `TCPSocket.new` raise `IO::TimeoutError` when a user-specified timeout occurs.
Similarly, `Socket.tcp` is updated to raise `IO::TimeoutError` when a timeout occurs within the method.
(Note that the existing behavior of `Addrinfo#connect_internal`, which Socket.tcp depends on internally and which raises `Errno::ETIMEDOUT` on timeout, is not changed.)

* [ruby/net-http] Raise `Net::OpenTimeout` when `TCPSocket.open` raises `IO::TimeoutError`.

With the changes in https://github.com/ruby/ruby/pull/15602, `TCPSocket.open` now raises `IO::TimeoutError` when a user-specified timeout occurs.
This change updates #connect to handle this case accordingly.

https://github.com/ruby/net-http/commit/f64109e1cf</pre>
</div>
</content>
</entry>
<entry>
<title>Fix: Recalculate the timeout duration considering `open_timeout` (#15596)</title>
<updated>2025-12-17T02:11:39+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2025-12-17T02:11:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=74a365310cfd150af6b45920d84920d17d6b3946'/>
<id>74a365310cfd150af6b45920d84920d17d6b3946</id>
<content type='text'>
This change updates the behavior so that, when there is only a single destination and `open_timeout` is specified, the remaining `open_timeout` duration is used as the connection timeout.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This change updates the behavior so that, when there is only a single destination and `open_timeout` is specified, the remaining `open_timeout` duration is used as the connection timeout.</pre>
</div>
</content>
</entry>
<entry>
<title>Fix: Do not pass negative timeout to Addrinfo#connect_internal (#15578)</title>
<updated>2025-12-16T10:52:45+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2025-12-16T10:52:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=2b1a9afbfbb5491665bfbdd560486a310ca49755'/>
<id>2b1a9afbfbb5491665bfbdd560486a310ca49755</id>
<content type='text'>
This change fixes a bug where, with `Socket.tcp`’s `fast_fallback option` disabled, specifying `open_timeout` could unintentionally pass a negative value to `Addrinfo#connect_internal`, `causing an ArgumentError`.

```
❯ ruby -rsocket -e 'p Socket.tcp("localhost", 9292, open_timeout: 1, fast_fallback: false)'
/Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:64:in 'IO#wait_writable': time interval must not be negative (ArgumentError)

          sock.wait_writable(timeout) or
                             ^^^^^^^
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:64:in 'Addrinfo#connect_internal'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:141:in 'Addrinfo#connect'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:964:in 'block in Socket.tcp_without_fast_fallback'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:231:in 'Array#each'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:231:in 'Addrinfo.foreach'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:945:in 'Socket.tcp_without_fast_fallback'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:671:in 'Socket.tcp'
	from -e:1:in '&lt;main&gt;'
```</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This change fixes a bug where, with `Socket.tcp`’s `fast_fallback option` disabled, specifying `open_timeout` could unintentionally pass a negative value to `Addrinfo#connect_internal`, `causing an ArgumentError`.

```
❯ ruby -rsocket -e 'p Socket.tcp("localhost", 9292, open_timeout: 1, fast_fallback: false)'
/Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:64:in 'IO#wait_writable': time interval must not be negative (ArgumentError)

          sock.wait_writable(timeout) or
                             ^^^^^^^
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:64:in 'Addrinfo#connect_internal'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:141:in 'Addrinfo#connect'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:964:in 'block in Socket.tcp_without_fast_fallback'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:231:in 'Array#each'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:231:in 'Addrinfo.foreach'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:945:in 'Socket.tcp_without_fast_fallback'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:671:in 'Socket.tcp'
	from -e:1:in '&lt;main&gt;'
```</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Fix Socket.tcp cleanup after Thread#kill (#15131)" (#15565)</title>
<updated>2025-12-15T22:07:15+00:00</updated>
<author>
<name>Luke Gruber</name>
<email>luke.gruber@shopify.com</email>
</author>
<published>2025-12-15T22:07:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=98ab418fed61079f8ef7e229ea1b41957ec5722b'/>
<id>98ab418fed61079f8ef7e229ea1b41957ec5722b</id>
<content type='text'>
This reverts commit 3038286a4bf7832f1c42c8cc9774ee6ff19876fc.

The following CI failure scared me:
https://github.com/ruby/ruby/actions/runs/20241051861/job/58108997049

```
  1) Timeout:
  TestResolvDNS#test_multiple_servers_with_timeout_and_truncated_tcp_fallback
```

Since it could be related, I'm reverting this for now.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 3038286a4bf7832f1c42c8cc9774ee6ff19876fc.

The following CI failure scared me:
https://github.com/ruby/ruby/actions/runs/20241051861/job/58108997049

```
  1) Timeout:
  TestResolvDNS#test_multiple_servers_with_timeout_and_truncated_tcp_fallback
```

Since it could be related, I'm reverting this for now.</pre>
</div>
</content>
</entry>
<entry>
<title>Fix Socket.tcp cleanup after Thread#kill (#15131)</title>
<updated>2025-12-15T16:48:34+00:00</updated>
<author>
<name>Luke Gruber</name>
<email>luke.gruber@shopify.com</email>
</author>
<published>2025-12-15T16:48:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3038286a4bf7832f1c42c8cc9774ee6ff19876fc'/>
<id>3038286a4bf7832f1c42c8cc9774ee6ff19876fc</id>
<content type='text'>
Socket.tcp launches ruby threads to resolve hostnames, and those threads
communicate through a queue implemented with `IO.pipe`. When the thread
that called `Socket.tcp` is killed, the resolver threads still try to
communicate through the pipe even though it may be closed. The method
`Socket.tcp_with_fast_fallback` tries to deal with this by killing the
threads in an ensure block, and then closing the pipe. However, calling
`Thread#kill` is not a blocking operation, it only sets a flag on the
thread telling it to raise during the next interrupt. The thread needs
to be joined to ensure it is terminated. The following script
demonstrates the issue:

```ruby
require "socket"

ts = []
5.times do
  ts &lt;&lt; Thread.new do
    loop do
      1_000.times do |i|
        puts "#{i}"
        t = Thread.new do
          Socket.tcp("ruby-lang.org", 80)
        end
        sleep 0.001
        t.kill
      end
    end
  end
end
ts.each(&amp;:join)
```

output:
```
/Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'IO#write': closed stream (IOError)
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'IO#putc'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'block in Socket::HostnameResolutionResult#add'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1017:in 'Thread::Mutex#synchronize'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1017:in 'Socket::HostnameResolutionResult#add'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:980:in 'Socket.resolve_hostname'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:719:in 'block (2 levels) in Socket.tcp_with_fast_fallback'
/Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'IO#write': closed stream (IOError)
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'IO#putc'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'block in Socket::HostnameResolutionResult#add'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1017:in 'Thread::Mutex#synchronize'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1017:in 'Socket::HostnameResolutionResult#add'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:978:in 'Socket.resolve_hostname'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:719:in 'block (2 levels) in Socket.tcp_with_fast_fallback'
```</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Socket.tcp launches ruby threads to resolve hostnames, and those threads
communicate through a queue implemented with `IO.pipe`. When the thread
that called `Socket.tcp` is killed, the resolver threads still try to
communicate through the pipe even though it may be closed. The method
`Socket.tcp_with_fast_fallback` tries to deal with this by killing the
threads in an ensure block, and then closing the pipe. However, calling
`Thread#kill` is not a blocking operation, it only sets a flag on the
thread telling it to raise during the next interrupt. The thread needs
to be joined to ensure it is terminated. The following script
demonstrates the issue:

```ruby
require "socket"

ts = []
5.times do
  ts &lt;&lt; Thread.new do
    loop do
      1_000.times do |i|
        puts "#{i}"
        t = Thread.new do
          Socket.tcp("ruby-lang.org", 80)
        end
        sleep 0.001
        t.kill
      end
    end
  end
end
ts.each(&amp;:join)
```

output:
```
/Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'IO#write': closed stream (IOError)
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'IO#putc'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'block in Socket::HostnameResolutionResult#add'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1017:in 'Thread::Mutex#synchronize'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1017:in 'Socket::HostnameResolutionResult#add'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:980:in 'Socket.resolve_hostname'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:719:in 'block (2 levels) in Socket.tcp_with_fast_fallback'
/Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'IO#write': closed stream (IOError)
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'IO#putc'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1019:in 'block in Socket::HostnameResolutionResult#add'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1017:in 'Thread::Mutex#synchronize'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:1017:in 'Socket::HostnameResolutionResult#add'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:978:in 'Socket.resolve_hostname'
	from /Users/luke/workspace/ruby-dev/ruby-build-debug/.ext/common/socket.rb:719:in 'block (2 levels) in Socket.tcp_with_fast_fallback'
```</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #21705] Fix segfaults on Windows</title>
<updated>2025-11-23T04:55:15+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2025-11-23T04:55:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=beb85e7eeee4163cd45b69645a60cdb942f72c05'/>
<id>beb85e7eeee4163cd45b69645a60cdb942f72c05</id>
<content type='text'>
It should check the type of the argument and coercion before
converting the encoding.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It should check the type of the argument and coercion before
converting the encoding.
</pre>
</div>
</content>
</entry>
<entry>
<title>Win32: Drop support for older than MSVC 9.0/_MSC_VER 1500</title>
<updated>2025-11-19T02:03:42+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2024-12-09T05:58:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3dd39134cde1a5ecd3c5d3128afcabd3c95e5bea'/>
<id>3dd39134cde1a5ecd3c5d3128afcabd3c95e5bea</id>
<content type='text'>
Visual C++ 2008 (9.0):
- _MSC_VER: 1500
- MSVCRT_VERSION: 90
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Visual C++ 2008 (9.0):
- _MSC_VER: 1500
- MSVCRT_VERSION: 90
</pre>
</div>
</content>
</entry>
</feed>
