diff --git a/doc/string/bytes.rdoc b/doc/string/bytes.rdoc index 6dde0a745d9b84..16fa8e0bb077da 100644 --- a/doc/string/bytes.rdoc +++ b/doc/string/bytes.rdoc @@ -4,4 +4,4 @@ Returns an array of the bytes in +self+: 'こんにちは'.bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/chars.rdoc b/doc/string/chars.rdoc index d4d15bf2ad541d..47fb01b43a66fc 100644 --- a/doc/string/chars.rdoc +++ b/doc/string/chars.rdoc @@ -4,4 +4,4 @@ Returns an array of the characters in +self+: 'こんにちは'.chars # => ["こ", "ん", "に", "ち", "は"] ''.chars # => [] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/codepoints.rdoc b/doc/string/codepoints.rdoc index 22cb22c8890df1..0ad866389e075f 100644 --- a/doc/string/codepoints.rdoc +++ b/doc/string/codepoints.rdoc @@ -5,4 +5,4 @@ each codepoint is the integer value for a character: 'こんにちは'.codepoints # => [12371, 12435, 12395, 12385, 12399] ''.codepoints # => [] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/getbyte.rdoc b/doc/string/getbyte.rdoc index 1d0ed2a5a488ad..974e21c473f96e 100644 --- a/doc/string/getbyte.rdoc +++ b/doc/string/getbyte.rdoc @@ -20,4 +20,4 @@ More examples: s.bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175] s.getbyte(2) # => 147 -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/grapheme_clusters.rdoc b/doc/string/grapheme_clusters.rdoc index 07ea1e318b5573..ee8b45700e46e7 100644 --- a/doc/string/grapheme_clusters.rdoc +++ b/doc/string/grapheme_clusters.rdoc @@ -16,4 +16,4 @@ Details: s.chars # => ["a", "̈"] # Two characters. s.chars.map {|char| char.ord } # => [97, 776] # Their values. -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/inspect.rdoc b/doc/string/inspect.rdoc index 907828c2afc22c..398a5a74c54956 100644 --- a/doc/string/inspect.rdoc +++ b/doc/string/inspect.rdoc @@ -35,4 +35,4 @@ A few, however, have special renderings: 13.chr.inspect # => "\"\\r\"" # CR 27.chr.inspect # => "\"\\e\"" # ESC -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/intern.rdoc b/doc/string/intern.rdoc index eded6ac3d727c9..c82302b906ec5e 100644 --- a/doc/string/intern.rdoc +++ b/doc/string/intern.rdoc @@ -4,5 +4,5 @@ creating it if it did not already exist: 'foo'.intern # => :foo 'こんにちは'.intern # => :こんにちは -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/ord.rdoc b/doc/string/ord.rdoc index 87b469db0205ce..8c460d3ba4a84c 100644 --- a/doc/string/ord.rdoc +++ b/doc/string/ord.rdoc @@ -4,4 +4,4 @@ Returns the integer ordinal of the first character of +self+: 'hello'.ord # => 104 'こんにちは'.ord # => 12371 -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/partition.rdoc b/doc/string/partition.rdoc index 614ad029d49885..b2e620a9fc24e4 100644 --- a/doc/string/partition.rdoc +++ b/doc/string/partition.rdoc @@ -40,4 +40,4 @@ then performs the equivalent of self.index(pattern) 'hello'.partition('x') # => ["hello", "", ""] 'こんにちは'.partition('に') # => ["こん", "に", "ちは"] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/rpartition.rdoc b/doc/string/rpartition.rdoc index eed03949a56e52..add95b1f40d921 100644 --- a/doc/string/rpartition.rdoc +++ b/doc/string/rpartition.rdoc @@ -44,4 +44,4 @@ then searches for the last matching substring 'hello'.rpartition('') # => ["hello", "", ""] 'こんにちは'.rpartition('に') # => ["こん", "に", "ちは"] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/scan.rdoc b/doc/string/scan.rdoc index 04a2b02ff4ec1b..d39b5b6dfa7fb3 100644 --- a/doc/string/scan.rdoc +++ b/doc/string/scan.rdoc @@ -32,4 +32,4 @@ With a block given, calls the block with each result; returns +self+: # => ["w", "o"] # => ["r", "l"] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/split.rdoc b/doc/string/split.rdoc index 1aee1de0a4cca7..8679149003fdd2 100644 --- a/doc/string/split.rdoc +++ b/doc/string/split.rdoc @@ -98,4 +98,4 @@ But the latter: - Has poorer performance because it creates an intermediate array. - Returns an array (instead of +self+). -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 8931d1c30c7d79..ce7872f98af401 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -690,11 +690,11 @@ Reading: [basic reading]: rdoc-ref:StringIO@Basic+Reading [basic writing]: rdoc-ref:StringIO@Basic+Writing -[bom (byte order mark)]: rdoc-ref:StringIO@BOM+-28Byte+Order+Mark-29 +[bom (byte order mark)]: rdoc-ref:StringIO@BOM+Byte+Order+Mark [data mode]: rdoc-ref:StringIO@Data+Mode [encodings]: rdoc-ref:StringIO@Encodings [end-of-stream]: rdoc-ref:StringIO@End-of-Stream [line number]: rdoc-ref:StringIO@Line+Number -[open/closed streams]: rdoc-ref:StringIO@Open-2FClosed+Streams +[open/closed streams]: rdoc-ref:StringIO@OpenClosed+Streams [position]: rdoc-ref:StringIO@Position -[read/write mode]: rdoc-ref:StringIO@Read-2FWrite+Mode +[read/write mode]: rdoc-ref:StringIO@ReadWrite+Mode diff --git a/doc/strscan/link_refs.txt b/doc/strscan/link_refs.txt index 19f6f7ce5c9533..04c441998285bd 100644 --- a/doc/strscan/link_refs.txt +++ b/doc/strscan/link_refs.txt @@ -1,5 +1,5 @@ [1]: rdoc-ref:StringScanner@Stored+String -[2]: rdoc-ref:StringScanner@Byte+Position+-28Position-29 +[2]: rdoc-ref:StringScanner@Byte+Position+Position [3]: rdoc-ref:StringScanner@Target+Substring [4]: rdoc-ref:StringScanner@Setting+the+Target+Substring [5]: rdoc-ref:StringScanner@Traversing+the+Target+Substring diff --git a/gc.c b/gc.c index 53a65d6acb8aab..4e1bb39e21f0b9 100644 --- a/gc.c +++ b/gc.c @@ -3633,9 +3633,11 @@ rb_gc_register_address(VALUE *addr) VALUE obj = *addr; struct global_object_list *tmp = ALLOC(struct global_object_list); - tmp->next = vm->global_object_list; - tmp->varptr = addr; - vm->global_object_list = tmp; + RB_VM_LOCKING() { + tmp->next = vm->global_object_list; + tmp->varptr = addr; + vm->global_object_list = tmp; + } /* * Because some C extensions have assignment-then-register bugs, @@ -3653,22 +3655,25 @@ void rb_gc_unregister_address(VALUE *addr) { rb_vm_t *vm = GET_VM(); - struct global_object_list *tmp = vm->global_object_list; - - if (tmp->varptr == addr) { - vm->global_object_list = tmp->next; - SIZED_FREE(tmp); - return; - } - while (tmp->next) { - if (tmp->next->varptr == addr) { - struct global_object_list *t = tmp->next; + struct global_object_list *tmp; + RB_VM_LOCKING() { + tmp = vm->global_object_list; + if (tmp->varptr == addr) { + vm->global_object_list = tmp->next; + SIZED_FREE(tmp); + } + else { + while (tmp->next) { + if (tmp->next->varptr == addr) { + struct global_object_list *t = tmp->next; - tmp->next = tmp->next->next; - SIZED_FREE(t); - break; + tmp->next = tmp->next->next; + SIZED_FREE(t); + break; + } + tmp = tmp->next; + } } - tmp = tmp->next; } } diff --git a/internal/imemo.h b/internal/imemo.h index 6534cec5d7ca9f..f94f0111fcb951 100644 --- a/internal/imemo.h +++ b/internal/imemo.h @@ -57,7 +57,6 @@ struct vm_svar { /*! THROW_DATA */ struct vm_throw_data { VALUE flags; - VALUE reserved; const VALUE throw_obj; const struct rb_control_frame_struct *catch_frame; int throw_state; diff --git a/lib/error_highlight/base.rb b/lib/error_highlight/base.rb index bc4a62c9d63508..5fffe5ec34e360 100644 --- a/lib/error_highlight/base.rb +++ b/lib/error_highlight/base.rb @@ -28,7 +28,7 @@ module ErrorHighlight # Currently, ErrorHighlight.spot only supports a single-line code fragment. # Therefore, if the return value is not nil, first_lineno and last_lineno will have # the same value. If the relevant code fragment spans multiple lines - # (e.g., Array#[] of +ary[(newline)expr(newline)]+), the method will return nil. + # (e.g., Array#[] of ary[(newline)expr(newline)]), the method will return nil. # This restriction may be removed in the future. def self.spot(obj, **opts) case obj diff --git a/lib/net/http.rb b/lib/net/http.rb index 98639978a2fbf6..53295fe90cfccc 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -37,7 +37,7 @@ class HTTPHeaderSyntaxError < StandardError; end # For information about \HTTP, see: # # - {Hypertext Transfer Protocol}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol]. - # - {Technical overview}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technical_overview]. + # - {Technology}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technology]. # # == About the Examples # @@ -72,7 +72,7 @@ class HTTPHeaderSyntaxError < StandardError; end # # - If performance is important, consider using sessions, which lower request overhead. # This {session}[rdoc-ref:Net::HTTP@Sessions] has multiple requests for - # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods] + # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method] # and {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]: # # Net::HTTP.start(hostname) do |http| @@ -198,7 +198,7 @@ class HTTPHeaderSyntaxError < StandardError; end # In the block, you can use these instance methods, # each of which that sends a single request: # - # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]: + # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method]: # # - #get, #request_get: GET. # - #head, #request_head: HEAD. @@ -447,7 +447,7 @@ class HTTPHeaderSyntaxError < StandardError; end # if the response has header 'Content-Range'. # # Otherwise decompression (or not) depends on the value of header - # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-encoding-response-header]: + # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Content-Encoding_2]: # # - 'deflate', 'gzip', or 'x-gzip': # decompresses the body and deletes the header. diff --git a/lib/prism.rb b/lib/prism.rb index 781bd4bb0115db..4fbe67a717e009 100644 --- a/lib/prism.rb +++ b/lib/prism.rb @@ -56,18 +56,18 @@ def initialize(version) end # :call-seq: - # Prism::lex_compat(source, **options) -> LexCompat::Result + # lex_compat(source, **options) -> LexCompat::Result # # Returns a parse result whose value is an array of tokens that closely - # resembles the return value of Ripper::lex. + # resembles the return value of Ripper.lex. # - # For supported options, see Prism::parse. + # For supported options, see Prism.parse. def self.lex_compat(source, **options) LexCompat.new(source, **options).result # steep:ignore end # :call-seq: - # Prism::load(source, serialized, freeze) -> ParseResult + # load(source, serialized, freeze) -> ParseResult # # Load the serialized AST using the source as a reference into a tree. def self.load(source, serialized, freeze = false) diff --git a/lib/prism/desugar_compiler.rb b/lib/prism/desugar_compiler.rb index 5d7d38d84153ce..7d4201c1c47b50 100644 --- a/lib/prism/desugar_compiler.rb +++ b/lib/prism/desugar_compiler.rb @@ -254,137 +254,137 @@ def desugar # :nodoc: # DesugarCompiler is a compiler that desugars Ruby code into a more primitive # form. This is useful for consumers that want to deal with fewer node types. class DesugarCompiler < MutationCompiler - # @@foo &&= bar + # `@@foo &&= bar` # # becomes # - # @@foo && @@foo = bar + # `@@foo && @@foo = bar` def visit_class_variable_and_write_node(node) node.desugar end - # @@foo ||= bar + # `@@foo ||= bar` # # becomes # - # defined?(@@foo) ? @@foo : @@foo = bar + # `defined?(@@foo) ? @@foo : @@foo = bar` def visit_class_variable_or_write_node(node) node.desugar end - # @@foo += bar + # `@@foo += bar` # # becomes # - # @@foo = @@foo + bar + # `@@foo = @@foo + bar` def visit_class_variable_operator_write_node(node) node.desugar end - # Foo &&= bar + # `Foo &&= bar` # # becomes # - # Foo && Foo = bar + # `Foo && Foo = bar` def visit_constant_and_write_node(node) node.desugar end - # Foo ||= bar + # `Foo ||= bar` # # becomes # - # defined?(Foo) ? Foo : Foo = bar + # `defined?(Foo) ? Foo : Foo = bar` def visit_constant_or_write_node(node) node.desugar end - # Foo += bar + # `Foo += bar` # # becomes # - # Foo = Foo + bar + # `Foo = Foo + bar` def visit_constant_operator_write_node(node) node.desugar end - # $foo &&= bar + # `$foo &&= bar` # # becomes # - # $foo && $foo = bar + # `$foo && $foo = bar` def visit_global_variable_and_write_node(node) node.desugar end - # $foo ||= bar + # `$foo ||= bar` # # becomes # - # defined?($foo) ? $foo : $foo = bar + # `defined?($foo) ? $foo : $foo = bar` def visit_global_variable_or_write_node(node) node.desugar end - # $foo += bar + # `$foo += bar` # # becomes # - # $foo = $foo + bar + # `$foo = $foo + bar` def visit_global_variable_operator_write_node(node) node.desugar end - # @foo &&= bar + # `@foo &&= bar` # # becomes # - # @foo && @foo = bar + # `@foo && @foo = bar` def visit_instance_variable_and_write_node(node) node.desugar end - # @foo ||= bar + # `@foo ||= bar` # # becomes # - # @foo || @foo = bar + # `@foo || @foo = bar` def visit_instance_variable_or_write_node(node) node.desugar end - # @foo += bar + # `@foo += bar` # # becomes # - # @foo = @foo + bar + # `@foo = @foo + bar` def visit_instance_variable_operator_write_node(node) node.desugar end - # foo &&= bar + # `foo &&= bar` # # becomes # - # foo && foo = bar + # `foo && foo = bar` def visit_local_variable_and_write_node(node) node.desugar end - # foo ||= bar + # `foo ||= bar` # # becomes # - # foo || foo = bar + # `foo || foo = bar` def visit_local_variable_or_write_node(node) node.desugar end - # foo += bar + # `foo += bar` # # becomes # - # foo = foo + bar + # `foo = foo + bar` def visit_local_variable_operator_write_node(node) node.desugar end diff --git a/lib/prism/ffi.rb b/lib/prism/ffi.rb index 520c773b43a408..1bcbfc367ccc3f 100644 --- a/lib/prism/ffi.rb +++ b/lib/prism/ffi.rb @@ -12,7 +12,7 @@ # autoloaded from within a non-main Ractor. require "prism/serialize" if defined?(Ractor) -module Prism +module Prism # :nodoc: module LibRubyParser # :nodoc: extend FFI::Library @@ -233,7 +233,7 @@ def self.with_file(filepath) # The version constant is set by reading the result of calling pm_version. VERSION = LibRubyParser.pm_version.read_string.freeze - class << self # :nodoc: + class << self # Mirror the Prism.dump API by using the serialization API. def dump(source, **options) LibRubyParser::PrismString.with_string(source) { |string| dump_common(string, options) } diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index 53ca168c0e81a1..07529c4295cc87 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -519,7 +519,7 @@ def adjoin(string) # This represents a comment that was encountered during parsing. It is the # base class for all comment types. class Comment - # The location of this comment in the source. + # The Location of this comment in the source. attr_reader :location # Create a new comment object with the given location. @@ -556,7 +556,7 @@ def inspect # :nodoc: # EmbDocComment objects correspond to comments that are surrounded by =begin # and =end. class EmbDocComment < Comment - # This can only be true for inline comments. + # Returns false. This can only be true for inline comments. def trailing? false end @@ -670,9 +670,9 @@ def inspect # :nodoc: end end - # This represents the result of a call to ::parse or ::parse_file. It contains - # the requested structure, any comments that were encounters, and any errors - # that were encountered. + # This represents the result of a call to Prism.parse or Prism.parse_file. + # It contains the requested structure, any comments that were encounters, + # and any errors that were encountered. class Result # The list of comments that were encountered during parsing. attr_reader :comments diff --git a/lib/prism/pattern.rb b/lib/prism/pattern.rb index 4a0c5ef54de46a..dde9d3b6f96b06 100644 --- a/lib/prism/pattern.rb +++ b/lib/prism/pattern.rb @@ -41,7 +41,7 @@ class Pattern class CompilationError < StandardError # Create a new CompilationError with the given representation of the node # that caused the error. - def initialize(repr) + def initialize(repr) # :nodoc: super(<<~ERROR) prism was unable to compile the pattern you provided into a usable expression. It failed on to understand the node represented by: diff --git a/prism/api_pack.c b/prism/api_pack.c index 98509ae65ccae0..84dc613de0a03a 100644 --- a/prism/api_pack.c +++ b/prism/api_pack.c @@ -173,7 +173,7 @@ pack_encoding_to_ruby(pm_pack_encoding encoding) { /** * call-seq: - * Pack::parse(version, variant, source) -> Format + * parse(version, variant, source) -> Format * * Parse the given source and return a format object. */ diff --git a/prism/config.yml b/prism/config.yml index 4e1560481e9d9e..f6e99c66b11566 100644 --- a/prism/config.yml +++ b/prism/config.yml @@ -817,7 +817,7 @@ nodes: - name: keyword_loc type: location comment: | - The location of the `alias` keyword. + The Location of the `alias` keyword. alias $foo $bar ^^^^^ @@ -865,7 +865,7 @@ nodes: - name: keyword_loc type: location comment: | - Represents the location of the `alias` keyword. + Represents the Location of the `alias` keyword. alias foo bar ^^^^^ @@ -895,7 +895,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the alternation operator location. + Represents the alternation operator Location. foo => bar | baz ^ @@ -931,7 +931,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `and` keyword or the `&&` operator. + The Location of the `and` keyword or the `&&` operator. left and right ^^^ @@ -966,7 +966,7 @@ nodes: - name: opening_loc type: location? comment: | - Represents the optional source location for the opening token. + Represents the optional source Location for the opening token. [1,2,3] # "[" %w[foo bar baz] # "%w[" @@ -975,7 +975,7 @@ nodes: - name: closing_loc type: location? comment: | - Represents the optional source location for the closing token. + Represents the optional source Location for the closing token. [1,2,3] # "]" %w[foo bar baz] # "]" @@ -1031,14 +1031,14 @@ nodes: - name: opening_loc type: location? comment: | - Represents the opening location of the array pattern. + Represents the opening Location of the array pattern. foo in [1, 2] ^ - name: closing_loc type: location? comment: | - Represents the closing location of the array pattern. + Represents the closing Location of the array pattern. foo in [1, 2] ^ @@ -1089,7 +1089,7 @@ nodes: - name: operator_loc type: location? comment: | - The location of the `=>` operator, if present. + The Location of the `=>` operator, if present. { foo => bar } ^^ @@ -1111,7 +1111,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `**` operator. + The Location of the `**` operator. { **x } ^^ @@ -1140,7 +1140,7 @@ nodes: - name: begin_keyword_loc type: location? comment: | - Represents the location of the `begin` keyword. + Represents the Location of the `begin` keyword. begin x end ^^^^^ @@ -1179,7 +1179,7 @@ nodes: - name: end_keyword_loc type: location? comment: | - Represents the location of the `end` keyword. + Represents the Location of the `end` keyword. begin x end ^^^ @@ -1204,7 +1204,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the location of the `&` operator. + Represents the Location of the `&` operator. foo(&args) ^ @@ -1265,14 +1265,14 @@ nodes: - name: opening_loc type: location comment: | - Represents the location of the opening `{` or `do`. + Represents the Location of the opening `{` or `do`. [1, 2, 3].each { |i| puts x } ^ - name: closing_loc type: location comment: | - Represents the location of the closing `}` or `end`. + Represents the Location of the closing `}` or `end`. [1, 2, 3].each { |i| puts x } ^ @@ -1295,14 +1295,14 @@ nodes: - name: name_loc type: location? comment: | - Represents the location of the block parameter name. + Represents the Location of the block parameter name. def a(&b) ^ - name: operator_loc type: location comment: | - Represents the location of the `&` operator. + Represents the Location of the `&` operator. def a(&b) ^ @@ -1342,7 +1342,7 @@ nodes: - name: opening_loc type: location? comment: | - Represents the opening location of the block parameters. + Represents the opening Location of the block parameters. -> (a, b = 1; local) { } ^ @@ -1353,7 +1353,7 @@ nodes: - name: closing_loc type: location? comment: | - Represents the closing location of the block parameters. + Represents the closing Location of the block parameters. -> (a, b = 1; local) { } ^ @@ -1383,7 +1383,7 @@ nodes: - name: keyword_loc type: location comment: | - The location of the `break` keyword. + The Location of the `break` keyword. break foo ^^^^^ @@ -1406,14 +1406,14 @@ nodes: - name: call_operator_loc type: location? comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar &&= value ^ - name: message_loc type: location? comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar &&= value ^^^ @@ -1434,7 +1434,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the location of the operator. + Represents the Location of the operator. foo.bar &&= value ^^^ @@ -1471,7 +1471,7 @@ nodes: - name: call_operator_loc type: location? comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar ^ @@ -1488,14 +1488,15 @@ nodes: - name: message_loc type: location? comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar ^^^ - name: opening_loc type: location? comment: | - Represents the location of the left parenthesis. + Represents the Location of the left parenthesis. + foo(bar) ^ - name: arguments @@ -1509,14 +1510,14 @@ nodes: - name: closing_loc type: location? comment: | - Represents the location of the right parenthesis. + Represents the Location of the right parenthesis. foo(bar) ^ - name: equal_loc type: location? comment: | - Represents the location of the equal sign, in the case that this is an attribute write. + Represents the Location of the equal sign, in the case that this is an attribute write. foo.bar = value ^ @@ -1567,14 +1568,14 @@ nodes: - name: call_operator_loc type: location? comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar += value ^ - name: message_loc type: location? comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar += value ^^^ @@ -1602,7 +1603,7 @@ nodes: - name: binary_operator_loc type: location comment: | - Represents the location of the binary operator. + Represents the Location of the binary operator. foo.bar += value ^^ @@ -1633,14 +1634,14 @@ nodes: - name: call_operator_loc type: location? comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar ||= value ^ - name: message_loc type: location? comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar ||= value ^^^ @@ -1661,7 +1662,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the location of the operator. + Represents the Location of the operator. foo.bar ||= value ^^^ @@ -1692,7 +1693,7 @@ nodes: - name: call_operator_loc type: location comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar = 1 ^ @@ -1706,7 +1707,7 @@ nodes: - name: message_loc type: location comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar = 1 ^^^ @@ -1744,7 +1745,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the location of the `=>` operator. + Represents the Location of the `=>` operator. foo => bar ^^ @@ -1782,14 +1783,14 @@ nodes: - name: case_keyword_loc type: location comment: | - Represents the location of the `case` keyword. + Represents the Location of the `case` keyword. case true; in false; end ^^^^ - name: end_keyword_loc type: location comment: | - Represents the location of the `end` keyword. + Represents the Location of the `end` keyword. case true; in false; end ^^^ @@ -1829,14 +1830,14 @@ nodes: - name: case_keyword_loc type: location comment: | - Represents the location of the `case` keyword. + Represents the Location of the `case` keyword. case true; when false; end ^^^^ - name: end_keyword_loc type: location comment: | - Represents the location of the `end` keyword. + Represents the Location of the `end` keyword. case true; when false; end ^^^ @@ -1854,7 +1855,7 @@ nodes: - name: class_keyword_loc type: location comment: | - Represents the location of the `class` keyword. + Represents the Location of the `class` keyword. class Foo end ^^^^^ @@ -1867,7 +1868,7 @@ nodes: - name: inheritance_operator_loc type: location? comment: | - Represents the location of the `<` operator. + Represents the Location of the `<` operator. class Foo < Bar ^ @@ -1893,7 +1894,7 @@ nodes: - name: end_keyword_loc type: location comment: | - Represents the location of the `end` keyword. + Represents the Location of the `end` keyword. class Foo end ^^^ @@ -1920,14 +1921,14 @@ nodes: - name: name_loc type: location comment: | - Represents the location of the variable name. + Represents the Location of the variable name. @@target &&= value ^^^^^^^^ - name: operator_loc type: location comment: | - Represents the location of the `&&=` operator. + Represents the Location of the `&&=` operator. @@target &&= value ^^^ @@ -2015,7 +2016,7 @@ nodes: - name: name_loc type: location comment: | - The location of the variable name. + The Location of the variable name. @@foo = :bar ^^^^^ @@ -2033,7 +2034,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. @@foo = :bar ^ @@ -2129,7 +2130,7 @@ nodes: - name: delimiter_loc type: location comment: | - The location of the `::` delimiter. + The Location of the `::` delimiter. ::Foo ^^ @@ -2139,7 +2140,7 @@ nodes: - name: name_loc type: location comment: | - The location of the name of the constant. + The Location of the name of the constant. ::Foo ^^^ @@ -2215,7 +2216,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. ::ABC = 123 ^ @@ -2275,7 +2276,7 @@ nodes: - name: name_loc type: location comment: | - The location of the constant name. + The Location of the constant name. FOO = 1 ^^^ @@ -2293,7 +2294,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. FOO = :bar ^ @@ -2474,7 +2475,7 @@ nodes: - name: opening_loc type: location? comment: | - The location of the opening brace. + The Location of the opening brace. foo in [*bar, baz, *qux] ^ @@ -2484,7 +2485,7 @@ nodes: - name: closing_loc type: location? comment: | - The location of the closing brace. + The Location of the closing brace. foo in [*bar, baz, *qux] ^ @@ -2574,28 +2575,28 @@ nodes: - name: for_keyword_loc type: location comment: | - The location of the `for` keyword. + The Location of the `for` keyword. for i in a end ^^^ - name: in_keyword_loc type: location comment: | - The location of the `in` keyword. + The Location of the `in` keyword. for i in a end ^^ - name: do_keyword_loc type: location? comment: | - The location of the `do` keyword, if present. + The Location of the `do` keyword, if present. for i in a do end ^^ - name: end_keyword_loc type: location comment: | - The location of the `end` keyword. + The Location of the `end` keyword. for i in a end ^^^ @@ -2723,7 +2724,7 @@ nodes: - name: name_loc type: location comment: | - The location of the global variable's name. + The Location of the global variable's name. $foo = :bar ^^^^ @@ -2741,7 +2742,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. $foo = :bar ^ @@ -2755,7 +2756,7 @@ nodes: - name: opening_loc type: location comment: | - The location of the opening brace. + The Location of the opening brace. { a => b } ^ @@ -2775,7 +2776,7 @@ nodes: - name: closing_loc type: location comment: | - The location of the closing brace. + The Location of the closing brace. { a => b } ^ @@ -2826,7 +2827,7 @@ nodes: - name: opening_loc type: location? comment: | - The location of the opening brace. + The Location of the opening brace. foo => { a: 1 } ^ @@ -2836,7 +2837,7 @@ nodes: - name: closing_loc type: location? comment: | - The location of the closing brace. + The Location of the closing brace. foo => { a: 1 } ^ @@ -2862,7 +2863,7 @@ nodes: - name: if_keyword_loc type: location? comment: | - The location of the `if` keyword if present. + The Location of the `if` keyword if present. bar if foo ^^ @@ -2887,7 +2888,7 @@ nodes: - name: then_keyword_loc type: location? comment: | - The location of the `then` keyword (if present) or the `?` in a ternary expression, `nil` otherwise. + The Location of the `then` keyword (if present) or the `?` in a ternary expression, `nil` otherwise. if foo then bar end ^^^^ @@ -2928,7 +2929,7 @@ nodes: - name: end_keyword_loc type: location? comment: | - The location of the `end` keyword if present, `nil` otherwise. + The Location of the `end` keyword if present, `nil` otherwise. if foo bar @@ -3213,7 +3214,7 @@ nodes: - name: name_loc type: location comment: | - The location of the variable name. + The Location of the variable name. @_x = 1 ^^^ @@ -3231,7 +3232,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. @x = y ^ @@ -3538,7 +3539,7 @@ nodes: - name: name_loc type: location comment: | - The location of the variable name. + The Location of the variable name. foo = :bar ^^^ @@ -3560,7 +3561,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. x = :y ^ @@ -3660,7 +3661,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the operator. + The Location of the operator. foo => bar ^^ @@ -3781,14 +3782,14 @@ nodes: - name: lparen_loc type: location? comment: | - The location of the opening parenthesis. + The Location of the opening parenthesis. a, (b, c) = 1, 2, 3 ^ - name: rparen_loc type: location? comment: | - The location of the closing parenthesis. + The Location of the closing parenthesis. a, (b, c) = 1, 2, 3 ^ @@ -3870,21 +3871,21 @@ nodes: - name: lparen_loc type: location? comment: | - The location of the opening parenthesis. + The Location of the opening parenthesis. (a, b, c) = 1, 2, 3 ^ - name: rparen_loc type: location? comment: | - The location of the closing parenthesis. + The Location of the closing parenthesis. (a, b, c) = 1, 2, 3 ^ - name: operator_loc type: location comment: | - The location of the operator. + The Location of the operator. a, b, c = 1, 2, 3 ^ @@ -4018,7 +4019,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `or` keyword or the `||` operator. + The Location of the `or` keyword or the `||` operator. left or right ^^ @@ -4101,21 +4102,21 @@ nodes: - name: operator_loc type: location comment: | - The location of the `^` operator + The Location of the `^` operator foo in ^(bar) ^ - name: lparen_loc type: location comment: | - The location of the opening parenthesis. + The Location of the opening parenthesis. foo in ^(bar) ^ - name: rparen_loc type: location comment: | - The location of the closing parenthesis. + The Location of the closing parenthesis. foo in ^(bar) ^ @@ -4145,7 +4146,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `^` operator + The Location of the `^` operator foo in ^bar ^ @@ -4223,7 +4224,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `..` or `...` operator. + The Location of the `..` or `...` operator. comment: | Represents the use of the `..` or `...` operators. @@ -4449,7 +4450,7 @@ nodes: fields: - name: filepath type: string - comment: Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism::parse*` APIs. + comment: Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism.parse*` APIs. comment: | Represents the use of the `__FILE__` keyword. @@ -4576,7 +4577,7 @@ nodes: - name: keyword_loc type: location comment: | - The location of the `unless` keyword. + The Location of the `unless` keyword. unless cond then bar end ^^^^^^ @@ -4597,7 +4598,7 @@ nodes: - name: then_keyword_loc type: location? comment: | - The location of the `then` keyword, if present. + The Location of the `then` keyword, if present. unless cond then bar end ^^^^ @@ -4621,7 +4622,7 @@ nodes: - name: end_keyword_loc type: location? comment: | - The location of the `end` keyword, if present. + The Location of the `end` keyword, if present. unless cond then bar end ^^^ diff --git a/prism/extension.c b/prism/extension.c index fe3cd6a8f38cb1..c4395b1cbcca4d 100644 --- a/prism/extension.c +++ b/prism/extension.c @@ -390,10 +390,10 @@ dump_input(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::dump(source, **options) -> String + * dump(source, **options) -> String * * Dump the AST corresponding to the given string to a string. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE dump(int argc, VALUE *argv, VALUE self) { @@ -423,10 +423,10 @@ dump(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::dump_file(filepath, **options) -> String + * dump_file(filepath, **options) -> String * * Dump the AST corresponding to the given file to a string. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE dump_file(int argc, VALUE *argv, VALUE self) { @@ -795,10 +795,10 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod /** * call-seq: - * Prism::lex(source, **options) -> LexResult + * lex(source, **options) -> LexResult * * Return a LexResult instance that contains an array of Token instances - * corresponding to the given string. For supported options, see Prism::parse. + * corresponding to the given string. For supported options, see Prism.parse. */ static VALUE lex(int argc, VALUE *argv, VALUE self) { @@ -815,10 +815,10 @@ lex(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::lex_file(filepath, **options) -> LexResult + * lex_file(filepath, **options) -> LexResult * * Return a LexResult instance that contains an array of Token instances - * corresponding to the given file. For supported options, see Prism::parse. + * corresponding to the given file. For supported options, see Prism.parse. */ static VALUE lex_file(int argc, VALUE *argv, VALUE self) { @@ -866,7 +866,7 @@ parse_input(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::parse(source, **options) -> ParseResult + * parse(source, **options) -> ParseResult * * Parse the given string and return a ParseResult instance. The options that * are supported are: @@ -934,10 +934,10 @@ parse(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_file(filepath, **options) -> ParseResult + * parse_file(filepath, **options) -> ParseResult * * Parse the given file and return a ParseResult instance. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE parse_file(int argc, VALUE *argv, VALUE self) { @@ -969,11 +969,11 @@ profile_input(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::profile(source, **options) -> nil + * profile(source, **options) -> nil * * Parse the given string and return nothing. This method is meant to allow * profilers to avoid the overhead of reifying the AST to Ruby. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE profile(int argc, VALUE *argv, VALUE self) { @@ -990,11 +990,11 @@ profile(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::profile_file(filepath, **options) -> nil + * profile_file(filepath, **options) -> nil * * Parse the given file and return nothing. This method is meant to allow * profilers to avoid the overhead of reifying the AST to Ruby. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE profile_file(int argc, VALUE *argv, VALUE self) { @@ -1042,10 +1042,10 @@ parse_stream_fgets(char *string, int size, void *stream) { /** * call-seq: - * Prism::parse_stream(stream, **options) -> ParseResult + * parse_stream(stream, **options) -> ParseResult * * Parse the given object that responds to `gets` and return a ParseResult - * instance. The options that are supported are the same as Prism::parse. + * instance. The options that are supported are the same as Prism.parse. */ static VALUE parse_stream(int argc, VALUE *argv, VALUE self) { @@ -1095,10 +1095,10 @@ parse_input_comments(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::parse_comments(source, **options) -> Array + * parse_comments(source, **options) -> Array * * Parse the given string and return an array of Comment objects. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE parse_comments(int argc, VALUE *argv, VALUE self) { @@ -1115,10 +1115,10 @@ parse_comments(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_file_comments(filepath, **options) -> Array + * parse_file_comments(filepath, **options) -> Array * * Parse the given file and return an array of Comment objects. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE parse_file_comments(int argc, VALUE *argv, VALUE self) { @@ -1137,17 +1137,17 @@ parse_file_comments(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_lex(source, **options) -> ParseLexResult + * parse_lex(source, **options) -> ParseLexResult * * Parse the given string and return a ParseLexResult instance that contains a * 2-element array, where the first element is the AST and the second element is * an array of Token instances. * * This API is only meant to be used in the case where you need both the AST and - * the tokens. If you only need one or the other, use either Prism::parse or - * Prism::lex. + * the tokens. If you only need one or the other, use either Prism.parse or + * Prism.lex. * - * For supported options, see Prism::parse. + * For supported options, see Prism.parse. */ static VALUE parse_lex(int argc, VALUE *argv, VALUE self) { @@ -1164,17 +1164,17 @@ parse_lex(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_lex_file(filepath, **options) -> ParseLexResult + * parse_lex_file(filepath, **options) -> ParseLexResult * * Parse the given file and return a ParseLexResult instance that contains a * 2-element array, where the first element is the AST and the second element is * an array of Token instances. * * This API is only meant to be used in the case where you need both the AST and - * the tokens. If you only need one or the other, use either Prism::parse_file - * or Prism::lex_file. + * the tokens. If you only need one or the other, use either Prism.parse_file + * or Prism.lex_file. * - * For supported options, see Prism::parse. + * For supported options, see Prism.parse. */ static VALUE parse_lex_file(int argc, VALUE *argv, VALUE self) { @@ -1210,10 +1210,10 @@ parse_input_success_p(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::parse_success?(source, **options) -> bool + * parse_success?(source, **options) -> bool * * Parse the given string and return true if it parses without errors. For - * supported options, see Prism::parse. + * supported options, see Prism.parse. */ static VALUE parse_success_p(int argc, VALUE *argv, VALUE self) { @@ -1230,10 +1230,10 @@ parse_success_p(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_failure?(source, **options) -> bool + * parse_failure?(source, **options) -> bool * * Parse the given string and return true if it parses with errors. For - * supported options, see Prism::parse. + * supported options, see Prism.parse. */ static VALUE parse_failure_p(int argc, VALUE *argv, VALUE self) { @@ -1242,10 +1242,10 @@ parse_failure_p(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_file_success?(filepath, **options) -> bool + * parse_file_success?(filepath, **options) -> bool * * Parse the given file and return true if it parses without errors. For - * supported options, see Prism::parse. + * supported options, see Prism.parse. */ static VALUE parse_file_success_p(int argc, VALUE *argv, VALUE self) { @@ -1264,10 +1264,10 @@ parse_file_success_p(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_file_failure?(filepath, **options) -> bool + * parse_file_failure?(filepath, **options) -> bool * * Parse the given file and return true if it parses with errors. For - * supported options, see Prism::parse. + * supported options, see Prism.parse. */ static VALUE parse_file_failure_p(int argc, VALUE *argv, VALUE self) { @@ -1298,7 +1298,7 @@ string_query(pm_string_query_t result) { /** * call-seq: - * Prism::StringQuery::local?(string) -> bool + * local?(string) -> bool * * Returns true if the string constitutes a valid local variable name. Note that * this means the names that can be set through Binding#local_variable_set, not @@ -1312,7 +1312,7 @@ string_query_local_p(VALUE self, VALUE string) { /** * call-seq: - * Prism::StringQuery::constant?(string) -> bool + * constant?(string) -> bool * * Returns true if the string constitutes a valid constant name. Note that this * means the names that can be set through Module#const_set, not necessarily the @@ -1326,7 +1326,7 @@ string_query_constant_p(VALUE self, VALUE string) { /** * call-seq: - * Prism::StringQuery::method_name?(string) -> bool + * method_name?(string) -> bool * * Returns true if the string constitutes a valid method name. */ diff --git a/prism/templates/lib/prism/dispatcher.rb.erb b/prism/templates/lib/prism/dispatcher.rb.erb index 16ce421cc5d093..e4ca84db2421d2 100644 --- a/prism/templates/lib/prism/dispatcher.rb.erb +++ b/prism/templates/lib/prism/dispatcher.rb.erb @@ -41,16 +41,12 @@ module Prism end # Register a listener for one or more events. - # - # def register: (Listener, *Symbol) -> void def register(listener, *events) register_events(listener, events) end # Register all public methods of a listener that match the pattern # `on__(enter|leave)`. - # - # def register_public_methods: (Listener) -> void def register_public_methods(listener) register_events(listener, listener.public_methods(false).grep(/\Aon_.+_(?:enter|leave)\z/)) end @@ -61,13 +57,9 @@ module Prism end # Walks `root` dispatching events to all registered listeners. - # - # def dispatch: (Node) -> void alias dispatch visit # Dispatches a single event for `node` to all registered listeners. - # - # def dispatch_once: (Node) -> void def dispatch_once(node) node.accept(DispatchOnce.new(listeners)) end diff --git a/string.c b/string.c index c99362b74d8d52..417e9893cef882 100644 --- a/string.c +++ b/string.c @@ -7060,7 +7060,7 @@ rb_str_include(VALUE str, VALUE arg) * 'abcdef'.to_i # => 0 * '2'.to_i(2) # => 0 * - * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE @@ -7092,7 +7092,7 @@ rb_str_to_i(int argc, VALUE *argv, VALUE str) * * 'abcdef'.to_f # => 0.0 * - * See {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * See {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE @@ -9619,7 +9619,7 @@ rb_str_each_line(int argc, VALUE *argv, VALUE str) * "This is line four.", * "This is line five."] * - * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE @@ -10762,7 +10762,7 @@ rb_str_scan(VALUE str, VALUE pat) * '0o777'.hex # => 0 * '0d999'.hex # => 55705 * - * Related: See {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * Related: See {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE @@ -10848,7 +10848,7 @@ rb_str_hex(VALUE str) * 'foo'.oct # => 0 * ''.oct # => 0 * - * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE diff --git a/test/ruby/test_ractor.rb b/test/ruby/test_ractor.rb index 6ae511217aca09..d449f9f8143c06 100644 --- a/test/ruby/test_ractor.rb +++ b/test/ruby/test_ractor.rb @@ -201,6 +201,45 @@ def test_max_cpu_1 RUBY end + def test_timer_thread_create_snt_for_dedicated_task + omit "timer thread works differently" if windows? + omit "test relies on this as a best-effort safety mechanism" unless defined?(Process::WNOHANG) + assert_separately([{ "RUBY_MAX_CPU" => "2" }], <<~'RUBY', timeout: 30) + $VERBOSE = nil + CHILD_PID = 0 + + rs = [] + 2.times do |i| + rs << Ractor.new(i) do |j| + if j == 0 + pid = spawn("sleep 60", close_others: true) + Object.const_set(:CHILD_PID, pid) + Process.waitpid(pid) # block forever (dedicated task) + else + while CHILD_PID == 0 + sleep 1 # make sure first ractor blocks forever first (this is what we're testing) + end + 1_000.times do + [nil] * 100 + end + end + end + end + + rs.last.join + begin + result = Process.waitpid(CHILD_PID, Process::WNOHANG) + rescue Errno::ECHILD, Errno::ESRCH + # If it's somehow not a child (not running?), don't send it a signal + else + if result.nil? + Process.kill('KILL', CHILD_PID) rescue nil + end + end + rs.first.join # reap + RUBY + end + def test_symbol_proc_is_shareable pr = :symbol.to_proc assert_make_shareable(pr) diff --git a/thread_pthread.c b/thread_pthread.c index 5b461efec877d6..f455ac828ea937 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -90,6 +90,11 @@ static const void *const condattr_monotonic = NULL; #endif #endif +#ifndef MINIMUM_SNT +// make at least MINIMUM_SNT snts for debug. +#define MINIMUM_SNT 0 +#endif + #ifdef HAVE_SCHED_YIELD #define native_thread_yield() (void)sched_yield() #else @@ -554,6 +559,20 @@ ractor_sched_timeslice_threads_contain_p(rb_vm_t *vm, rb_thread_t *th) static void ractor_sched_barrier_join_signal_locked(rb_vm_t *vm); +static bool +need_more_shared_native_threads_p(rb_vm_t *vm) +{ + ASSERT_ractor_sched_locked(vm, NULL); + + unsigned int schedulable_ractor_cnt = vm->ractor.cnt; + unsigned int snt_cnt = vm->ractor.sched.snt_cnt; + RUBY_ASSERT(schedulable_ractor_cnt >= 1); + if (!vm->ractor.main_ractor->threads.sched.enable_mn_threads) { + schedulable_ractor_cnt--; // do not need snt for main ractor + } + return snt_cnt < MINIMUM_SNT || (snt_cnt < schedulable_ractor_cnt && snt_cnt < vm->ractor.sched.max_cpu); +} + // setup timeslice signals by the timer thread. static void thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *cr, rb_vm_t *vm, @@ -564,6 +583,7 @@ thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *c #endif rb_thread_t *del_timeslice_th; + bool wakeup_timer_thread = false; if (del_th && sched->is_running_timeslice) { del_timeslice_th = del_th; @@ -592,6 +612,12 @@ thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *c ractor_sched_barrier_join_signal_locked(vm); } sched->is_running = false; + + // If we need more SNTs, the timer thread should be awake and monitoring the situation so it can correct it. + if (!del_th->has_dedicated_nt && del_th->nt->dedicated > 0 && (sched->running != NULL || vm->ractor.sched.grq_cnt > 0) && + need_more_shared_native_threads_p(vm)) { + wakeup_timer_thread = true; + } } if (add_th) { @@ -616,7 +642,7 @@ thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *c ccan_list_add(&vm->ractor.sched.timeslice_threads, &add_timeslice_th->sched.node.timeslice_threads); sched->is_running_timeslice = true; if (was_empty) { - timer_thread_wakeup_locked(vm); + wakeup_timer_thread = true; } } @@ -625,6 +651,10 @@ thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *c ccan_list_del_init(&del_timeslice_th->sched.node.timeslice_threads); } + if (wakeup_timer_thread) { + timer_thread_wakeup_locked(vm); + } + VM_ASSERT(ractor_sched_running_threads_size(vm) == vm->ractor.sched.running_cnt); VM_ASSERT(ractor_sched_timeslice_threads_size(vm) <= vm->ractor.sched.running_cnt); } @@ -1264,11 +1294,6 @@ ractor_sched_enq(rb_vm_t *vm, rb_ractor_t *r) #define SNT_KEEP_SECONDS 0 #endif -#ifndef MINIMUM_SNT -// make at least MINIMUM_SNT snts for debug. -#define MINIMUM_SNT 0 -#endif - static rb_ractor_t * ractor_sched_deq(rb_vm_t *vm, rb_ractor_t *cr) { diff --git a/thread_pthread_mn.c b/thread_pthread_mn.c index 69e81e5fbcf00f..d6602cea77d25a 100644 --- a/thread_pthread_mn.c +++ b/thread_pthread_mn.c @@ -394,25 +394,14 @@ nt_free_stack(void *mstack) rb_native_mutex_unlock(&nt_machine_stack_lock); } - static int native_thread_check_and_create_shared(rb_vm_t *vm) { bool need_to_make = false; - rb_native_mutex_lock(&vm->ractor.sched.lock); + ractor_sched_lock(vm, NULL); { - unsigned int schedulable_ractor_cnt = vm->ractor.cnt; - RUBY_ASSERT(schedulable_ractor_cnt >= 1); - - if (!vm->ractor.main_ractor->threads.sched.enable_mn_threads) - schedulable_ractor_cnt--; // do not need snt for main ractor - - unsigned int snt_cnt = vm->ractor.sched.snt_cnt; - if (((int)snt_cnt < MINIMUM_SNT) || - (snt_cnt < schedulable_ractor_cnt && - snt_cnt < vm->ractor.sched.max_cpu)) { - + if (need_more_shared_native_threads_p(vm)) { RUBY_DEBUG_LOG("added snt:%u dnt:%u ractor_cnt:%u grq_cnt:%u", vm->ractor.sched.snt_cnt, vm->ractor.sched.dnt_cnt, @@ -426,7 +415,7 @@ native_thread_check_and_create_shared(rb_vm_t *vm) RUBY_DEBUG_LOG("snt:%d ractor_cnt:%d", (int)vm->ractor.sched.snt_cnt, (int)vm->ractor.cnt); } } - rb_native_mutex_unlock(&vm->ractor.sched.lock); + ractor_sched_unlock(vm, NULL); if (need_to_make) { struct rb_native_thread *nt = native_thread_alloc(); diff --git a/time.c b/time.c index b2eed2daf3b85c..acc20d2c9757b4 100644 --- a/time.c +++ b/time.c @@ -3821,8 +3821,7 @@ time_to_i(VALUE time) * {Epoch seconds}[rdoc-ref:Time@Epoch+Seconds]; * subseconds are included. * - * The stored value of +self+ is a - * {Rational}[rdoc-ref:Rational@#method-i-to_f], + * The stored value of +self+ is a Rational, * which means that the returned value may be approximate: * * Time.utc(1970, 1, 1, 0, 0, 0).to_f # => 0.0