summaryrefslogtreecommitdiff
path: root/ext
AgeCommit message (Collapse)Author
2024-02-26Fix compilation for platforms without pthreadPierrick Bouvier
Found when compiling ruby for windows-arm64 using msys2 Missing return type for function Init_lock_native_thread lock_native_thread.c:45:1: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int] 45 | Init_lock_native_thread(void) | ^ | int
2024-02-26[ruby/strscan] Add a method for peeking and reading bytes asAaron Patterson
integers (https://github.com/ruby/strscan/pull/89) This commit adds `scan_byte` and `peek_byte`. `scan_byte` will scan the current byte, return it as an integer, and advance the cursor. `peek_byte` will return the current byte as an integer without advancing the cursor. Currently `StringScanner#get_byte` returns a string, but I want to get the current byte without allocating a string. I think this will help with writing high performance lexers. --------- https://github.com/ruby/strscan/commit/873aba2e5d Co-authored-by: Sutou Kouhei <kou@clear-code.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
2024-02-23Stop using rb_str_locktmp_ensure publiclyPeter Zhu
rb_str_locktmp_ensure is a private API.
2024-02-23Stop using rb_fstring publiclyPeter Zhu
rb_fstring is a private API, so we should use rb_str_to_interned_str instead, which is a public API.
2024-02-23Add option for mtu discovery flagMarek Küthe
Signed-off-by: Marek Küthe <m.k@mk16.de>
2024-02-23Fixes [Bug #20258]Marek Küthe
Signed-off-by: Marek Küthe <m.k@mk16.de>
2024-02-23Use rb_hash_foreach in objspace.cPeter Zhu
Using RHASH_TBL_RAW is a private API, so we should use rb_hash_foreach rather than RHASH_TBL_RAW with st_foreach.
2024-02-23Use rb_hash_foreach in coveragePeter Zhu
Using RHASH_TBL_RAW is a private API, so we should use rb_hash_foreach rather than RHASH_TBL_RAW with st_foreach.
2024-02-22[ruby/zlib] In Zlib::GzipReader#eof? check if we're actually at eofMartin Emde
Only consider it eof if we read ahead and something fills the buf. If not, we may only have empty blocks and the footer. Fixes https://github.com/ruby/zlib/pull/56 https://github.com/ruby/zlib/commit/437bea8003
2024-02-21[ruby/date] Remove the unintentional ability to parse `Symbol`Nobuyoshi Nakada
It's been 2 years since ruby/date#49, so it's okay. https://github.com/ruby/date/commit/435dfec6c8
2024-02-21`rb_thread_lock_native_thread()`Koichi Sasada
Introduce `rb_thread_lock_native_thread()` to allocate dedicated native thread to the current Ruby thread for M:N threads. This C API is similar to Go's `runtime.LockOSThread()`. Accepted at https://github.com/ruby/dev-meeting-log/blob/master/2023/DevMeeting-2023-08-24.md (and missed to implement on Ruby 3.3.0)
2024-02-20Move ripper_validate_object to ripper_init.c.tmplyui-knk
2024-02-20[Feature #20257] Rearchitect Ripperyui-knk
Introduce another semantic value stack for Ripper so that Ripper can manage both Node and Ruby Object separately. This rearchitectutre of Ripper solves these issues. Therefore adding test cases for them. * [Bug 10436] https://bugs.ruby-lang.org/issues/10436 * [Bug 18988] https://bugs.ruby-lang.org/issues/18988 * [Bug 20055] https://bugs.ruby-lang.org/issues/20055 Checked the differences of `Ripper.sexp` for files under `/test/ruby` are only on test_pattern_matching.rb. The differences comes from the differences between `new_hash_pattern_tail` functions between parser and Ripper. Ripper `new_hash_pattern_tail` didn’t call `assignable` then `kw_rest_arg` wasn’t marked as local variable. This is also fixed by this commit. ``` --- a/./tmp/before/test_pattern_matching.rb +++ b/./tmp/after/test_pattern_matching.rb @@ -3607,7 +3607,7 @@ [:in, [:hshptn, nil, [], [:var_field, [:@ident, “a”, [984, 13]]]], [[:binary, - [:vcall, [:@ident, “a”, [985, 10]]], + [:var_ref, [:@ident, “a”, [985, 10]]], :==, [:hash, nil]]], nil]]], @@ -3662,7 +3662,7 @@ [:in, [:hshptn, nil, [], [:var_field, [:@ident, “a”, [993, 13]]]], [[:binary, - [:vcall, [:@ident, “a”, [994, 10]]], + [:var_ref, [:@ident, “a”, [994, 10]]], :==, [:hash, [:assoclist_from_args, @@ -3813,7 +3813,7 @@ [:command, [:@ident, “raise”, [1022, 10]], [:args_add_block, - [[:vcall, [:@ident, “b”, [1022, 16]]]], + [[:var_ref, [:@ident, “b”, [1022, 16]]]], false]]], [:else, [[:var_ref, [:@kw, “true”, [1024, 10]]]]]]]], nil, @@ -3876,7 +3876,7 @@ [:@int, “0”, [1033, 15]]], :“&&“, [:binary, - [:vcall, [:@ident, “b”, [1033, 20]]], + [:var_ref, [:@ident, “b”, [1033, 20]]], :==, [:hash, nil]]]], nil]]], @@ -3946,7 +3946,7 @@ [:@int, “0”, [1042, 15]]], :“&&“, [:binary, - [:vcall, [:@ident, “b”, [1042, 20]]], + [:var_ref, [:@ident, “b”, [1042, 20]]], :==, [:hash, [:assoclist_from_args, @@ -5206,7 +5206,7 @@ [[:assoc_new, [:@label, “c:“, [1352, 22]], [:@int, “0”, [1352, 25]]]]]], - [:vcall, [:@ident, “r”, [1352, 29]]]], + [:var_ref, [:@ident, “r”, [1352, 29]]]], false]]], [:binary, [:call, @@ -5299,7 +5299,7 @@ [:assoc_new, [:@label, “c:“, [1367, 34]], [:@int, “0”, [1367, 37]]]]]], - [:vcall, [:@ident, “r”, [1367, 41]]]], + [:var_ref, [:@ident, “r”, [1367, 41]]]], false]]], [:binary, [:call, @@ -5931,7 +5931,7 @@ [:in, [:hshptn, nil, [], [:var_field, [:@ident, “r”, [1533, 11]]]], [[:binary, - [:vcall, [:@ident, “r”, [1534, 8]]], + [:var_ref, [:@ident, “r”, [1534, 8]]], :==, [:hash, [:assoclist_from_args, ```
2024-02-15Do not include a backtick in error messages and backtracesYusuke Endoh
[Feature #16495]
2024-02-08[ruby/strscan] Bump versionSutou Kouhei
https://github.com/ruby/strscan/commit/ba338b882c
2024-02-08[ruby/strscan] Bump versionSutou Kouhei
https://github.com/ruby/strscan/commit/842845af1f
2024-02-08[ruby/fiddle] Set changelog_uri gem metadataMasato Nakamura
(https://github.com/ruby/fiddle/pull/138) See https://guides.rubygems.org/specification-reference/#metadata for changelog_uri metadata. https://github.com/ruby/fiddle/commit/0bd8e96adc
2024-02-04Alias init functionsNobuyoshi Nakada
The extension library has each initialization function named "Init_" + basename. If multiple extensions have the same base name (such as cgi/escape and erb/escape), the same function will be registered for both names. To fix this conflict, rename the initialization functions under sub directories using using parent names, when statically linking.
2024-02-04Allow glob patterns in ext/SetupNobuyoshi Nakada
2024-02-04Glob with base optionNobuyoshi Nakada
When ripping the base directory off the result names.
2024-02-01Revert "Set AI_ADDRCONFIG when making getaddrinfo(3) calls for outgoing conns"KJ Tsanaktsidis
This reverts commit 673ed41c81cf5a6951bcb2c3dec82d7bd6ea7440.
2024-01-31[flori/json] Make OpenStruct support as optionalHiroshi SHIBATA
https://github.com/flori/json/commit/202ffe2335
2024-01-30[DOC] Fix Ripper DSL input exampleyui-knk
'!' suffix is needed for event dispatch.
2024-01-28[ruby/win32ole] [DOC] Remove spaces inside parenthesesNobuyoshi Nakada
https://github.com/ruby/win32ole/commit/57e4a38465
2024-01-28[ruby/win32ole] Move toplevel constant for olegen under `WIN32OLE`Nobuyoshi Nakada
https://github.com/ruby/win32ole/commit/78ff137c0f
2024-01-28[ruby/win32ole] [DOC] Move sample to toplevelNobuyoshi Nakada
https://github.com/ruby/win32ole/commit/70ea60c4d2
2024-01-28[ruby/win32ole] Use `end_with?` and fix indentNobuyoshi Nakada
https://github.com/ruby/win32ole/commit/7648ee7e56
2024-01-28[ruby/win32ole] Move `WIN32OLE` prefixed error classes under `WIN32OLE`Nobuyoshi Nakada
https://github.com/ruby/win32ole/commit/1c95816168
2024-01-28[ruby/win32ole] Use the scoped names in `inspect` and error messagesNobuyoshi Nakada
https://github.com/ruby/win32ole/commit/2f51493bd1
2024-01-28[ruby/win32ole] [DOC] Update class names using the scoped namesNobuyoshi Nakada
https://github.com/ruby/win32ole/commit/2c5d193da7
2024-01-28[ruby/win32ole] Rename `WIN32OLE::Typelib` as `WIN32OLE::TypeLib`Nobuyoshi Nakada
https://github.com/ruby/win32ole/commit/5feede2cc5
2024-01-28[ruby/win32ole] Rename `WIN32OLE::VARIANT` as `WIN32OLE::VariantType`Nobuyoshi Nakada
Prevent name clash with `WIN32OLE::Variant`, of generated document files on case-insensitive filesystems, such as Windows. https://github.com/ruby/win32ole/commit/049e5f0a6e
2024-01-28[ruby/digest] [DOC] Expand `Digest::SHA2` definitions for RDocNobuyoshi Nakada
Since RDoc searches `var = rb_define_class_under(...)` statements literally, they cannot be built by macros. https://github.com/ruby/digest/commit/d39b684f91
2024-01-28[ruby/digest] Prefer `rb_const_get` over `rb_path2class` for direct constantsNobuyoshi Nakada
https://github.com/ruby/digest/commit/e5d30394b3
2024-01-28[ruby/digest] [DOC] Add .documentNobuyoshi Nakada
https://github.com/ruby/digest/commit/6db96aa99a
2024-01-24Initialize errno variables and fix maybe-uninitialized warningsNobuyoshi Nakada
2024-01-23Make lastline and nextline to be rb_parser_stringyui-knk
This commit changes `struct parser_params` lastline and nextline from `VALUE` (String object) to `rb_parser_string_t *` so that dependency on Ruby Object is reduced. `parser_string_buffer_t string_buffer` is added to `struct parser_params` to manage `rb_parser_string_t` pointers of each line. All allocated line strings are freed in `rb_ruby_parser_free`.
2024-01-22Extract syslogHiroshi SHIBATA
2024-01-22Extract nkfHiroshi SHIBATA
2024-01-22Make sure the correct error is raised for EAI_SYSTEM resolver failKJ Tsanaktsidis
In case of EAI_SYSTEM, getaddrinfo is supposed to set more detail in errno; however, because we call getaddrinfo on a thread now, and errno is threadlocal, that information is being lost. Instead, we just raise whatever errno happens to be on the calling thread (which can be something very confusing, like `ECHILD`). Fix it by explicitly propagating errno back to the calling thread through the getaddrinfo_arg structure. [Bug #20198]
2024-01-22[ruby/nkf] Bump up version to 0.2.0Hiroshi SHIBATA
https://github.com/ruby/nkf/commit/65506fecfd
2024-01-22[ruby/nkf] Drop GPL and add licenses to gemspecCharles Oliver Nutter
https://github.com/ruby/nkf/commit/19df7138f7
2024-01-22[ruby/nkf] Add JRuby extension to the gemCharles Oliver Nutter
This pulls in the nkf extension implementation from JRuby. The build and load logic has been updated along the same lines as ruby/digest and the gem appears to build correctly for the -java platform. Fixes https://github.com/ruby/nkf/pull/13 https://github.com/ruby/nkf/commit/18f57f36ed
2024-01-19Remove null checks for xfreePeter Zhu
xfree can handle null values, so we don't need to check it.
2024-01-19[ruby/strscan] Bump versionSutou Kouhei
https://github.com/ruby/strscan/commit/d6f97ec102
2024-01-19Mark asan fake stacks during machine stack markingKJ Tsanaktsidis
ASAN leaves a pointer to the fake frame on the stack; we can use the __asan_addr_is_in_fake_stack API to work out the extent of the fake stack and thus mark any VALUEs contained therein. [Bug #20001]
2024-01-18[ruby/psych] Add :stringify_names option to convert symbol keys to string ↵Robert Schulze
for dumping https://github.com/ruby/psych/commit/3d051d89aa