Skip to content
Merged
8 changes: 4 additions & 4 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -8423,12 +8423,12 @@ rb_ary_deconstruct(VALUE ary)
*
* [1, 'one', :one, [2, 'two', :two]]
*
* - A {%w or %W string-array Literal}[rdoc-ref:syntax/literals.rdoc@25w+and+-25W-3A+String-Array+Literals]:
* - A {%w or %W string-array Literal}[rdoc-ref:syntax/literals.rdoc@w-and-w-String-Array-Literals]:
*
* %w[foo bar baz] # => ["foo", "bar", "baz"]
* %w[1 % *] # => ["1", "%", "*"]
*
* - A {%i or %I symbol-array Literal}[rdoc-ref:syntax/literals.rdoc@25i+and+-25I-3A+Symbol-Array+Literals]:
* - A {%i or %I symbol-array Literal}[rdoc-ref:syntax/literals.rdoc@i+and-I-Symbol-Array+Literals]:
*
* %i[foo bar baz] # => [:foo, :bar, :baz]
* %i[1 % *] # => [:"1", :%, :*]
Expand Down Expand Up @@ -8690,8 +8690,8 @@ rb_ary_deconstruct(VALUE ary)
*
* First, what's elsewhere. Class \Array:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
* - Inherits from {class Object}[rdoc-ref:Object@Whats-Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@Whats-Here],
* which provides dozens of additional methods.
*
* Here, class \Array provides methods that are useful for:
Expand Down
6 changes: 3 additions & 3 deletions complex.c
Original file line number Diff line number Diff line change
Expand Up @@ -2645,9 +2645,9 @@ float_arg(VALUE self)
* First, what's elsewhere:
*
* - Class \Complex inherits (directly or indirectly)
* from classes {Numeric}[rdoc-ref:Numeric@What-27s+Here]
* and {Object}[rdoc-ref:Object@What-27s+Here].
* - Includes (indirectly) module {Comparable}[rdoc-ref:Comparable@What-27s+Here].
* from classes {Numeric}[rdoc-ref:Numeric@Whats-Here]
* and {Object}[rdoc-ref:Object@Whats-Here].
* - Includes (indirectly) module {Comparable}[rdoc-ref:Comparable@Whats-Here].
*
* Here, class \Complex has methods for:
*
Expand Down
6 changes: 3 additions & 3 deletions dir.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
# A \Dir object is in some ways array-like:
#
# - It has instance methods #children, #each, and #each_child.
# - It includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here].
# - It includes {module Enumerable}[rdoc-ref:Enumerable@Whats+Here].
#
# == \Dir As Stream-Like
#
Expand Down Expand Up @@ -85,8 +85,8 @@
#
# First, what's elsewhere. Class \Dir:
#
# - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
# - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
# - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
# - Includes {module Enumerable}[rdoc-ref:Enumerable@Whats+Here],
# which provides dozens of additional methods.
#
# Here, class \Dir provides methods that are useful for:
Expand Down
6 changes: 3 additions & 3 deletions doc/float.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@
# First, what's elsewhere. Class \Float:
#
# - Inherits from
# {class Numeric}[rdoc-ref:Numeric@What-27s+Here]
# and {class Object}[rdoc-ref:Object@What-27s+Here].
# - Includes {module Comparable}[rdoc-ref:Comparable@What-27s+Here].
# {class Numeric}[rdoc-ref:Numeric@Whats+Here]
# and {class Object}[rdoc-ref:Object@Whats+Here].
# - Includes {module Comparable}[rdoc-ref:Comparable@Whats+Here].
#
# Here, class \Float provides methods for:
#
Expand Down
4 changes: 2 additions & 2 deletions doc/string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@
#
# First, what's elsewhere. Class +String+:
#
# - Inherits from the {Object class}[rdoc-ref:Object@What-27s+Here].
# - Includes the {Comparable module}[rdoc-ref:Comparable@What-27s+Here].
# - Inherits from the {Object class}[rdoc-ref:Object@Whats+Here].
# - Includes the {Comparable module}[rdoc-ref:Comparable@Whats+Here].
#
# Here, class +String+ provides methods that are useful for:
#
Expand Down
27 changes: 17 additions & 10 deletions eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,17 +329,24 @@ ruby_exec_node(void *n)

/*
* call-seq:
* Module.nesting -> array
*
* Returns the list of +Modules+ nested at the point of call.
* Module.nesting -> array
*
* Returns nested module as an array of Module objects:
*
* module M0
* def self.speak = Module.nesting
* module M1
* def self.speak = Module.nesting
* module M2
* def self.speak = Module.nesting
* end
* end
* end
* M0.speak # => [M0]
* M0.speak.first.class # => Module
* M0::M1.speak # => [M0::M1, M0]
* M0::M1::M2.speak # => [M0::M1::M2, M0::M1, M0]
*
* module M1
* module M2
* $a = Module.nesting
* end
* end
* $a #=> [M1::M2, M1]
* $a[0].name #=> "M1::M2"
*/

static VALUE
Expand Down
2 changes: 1 addition & 1 deletion file.c
Original file line number Diff line number Diff line change
Expand Up @@ -7507,7 +7507,7 @@ const char ruby_null_device[] =
*
* First, what's elsewhere. Class \File:
*
* - Inherits from {class IO}[rdoc-ref:IO@What-27s+Here],
* - Inherits from {class IO}[rdoc-ref:IO@Whats+Here],
* in particular, methods for creating, reading, and writing files
* - Includes module FileTest,
* which provides dozens of additional methods.
Expand Down
8 changes: 4 additions & 4 deletions hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -7216,8 +7216,8 @@ static const rb_data_type_t env_data_type = {
*
* First, what's elsewhere. Class +Hash+:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
* - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@Whats+Here],
* which provides dozens of additional methods.
*
* Here, class +Hash+ provides methods that are useful for:
Expand Down Expand Up @@ -7528,8 +7528,8 @@ Init_Hash(void)
*
* First, what's elsewhere. Class +ENV+:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Extends {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
* - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
* - Extends {module Enumerable}[rdoc-ref:Enumerable@Whats+Here],
*
* Here, class +ENV+ provides methods that are useful for:
*
Expand Down
4 changes: 2 additions & 2 deletions io.c
Original file line number Diff line number Diff line change
Expand Up @@ -15469,8 +15469,8 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y)
*
* First, what's elsewhere. Class \IO:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
* - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@Whats+Here],
* which provides dozens of additional methods.
*
* Here, class \IO provides methods that are useful for:
Expand Down
4 changes: 2 additions & 2 deletions lib/net/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ class HTTPHeaderSyntaxError < StandardError; end
#
# First, what's elsewhere. Class Net::HTTP:
#
# - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
# - Inherits from {class Object}[rdoc-ref:Object#class-object-whats-here].
#
# This is a categorized summary of methods and attributes.
#
Expand Down Expand Up @@ -1304,7 +1304,7 @@ def response_body_encoding=(value)

# Sets whether to determine the proxy from environment variable
# '<tt>ENV['http_proxy']</tt>';
# see {Proxy Using ENV['http_proxy']}[rdoc-ref:Net::HTTP@Proxy+Using+-27ENV-5B-27http_proxy-27-5D-27].
# see {Proxy Using ENV['http_proxy']}[rdoc-ref:Net::HTTP@Proxy+Using+ENVHTTPProxy].
attr_writer :proxy_from_env

# Sets the proxy address;
Expand Down
5 changes: 5 additions & 0 deletions lib/resolv.rb
Original file line number Diff line number Diff line change
Expand Up @@ -487,13 +487,18 @@ def each_name(address)
# * Resolv::DNS::Resource::IN::A
# * Resolv::DNS::Resource::IN::AAAA
# * Resolv::DNS::Resource::IN::ANY
# * Resolv::DNS::Resource::IN::CAA
# * Resolv::DNS::Resource::IN::CNAME
# * Resolv::DNS::Resource::IN::HINFO
# * Resolv::DNS::Resource::IN::HTTPS
# * Resolv::DNS::Resource::IN::LOC
# * Resolv::DNS::Resource::IN::MINFO
# * Resolv::DNS::Resource::IN::MX
# * Resolv::DNS::Resource::IN::NS
# * Resolv::DNS::Resource::IN::PTR
# * Resolv::DNS::Resource::IN::SOA
# * Resolv::DNS::Resource::IN::SRV
# * Resolv::DNS::Resource::IN::SVCB
# * Resolv::DNS::Resource::IN::TXT
# * Resolv::DNS::Resource::IN::WKS
#
Expand Down
10 changes: 5 additions & 5 deletions numeric.c
Original file line number Diff line number Diff line change
Expand Up @@ -3680,9 +3680,9 @@ rb_int128_to_numeric(rb_int128_t n)
* First, what's elsewhere. Class \Integer:
*
* - Inherits from
* {class Numeric}[rdoc-ref:Numeric@What-27s+Here]
* and {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Comparable}[rdoc-ref:Comparable@What-27s+Here].
* {class Numeric}[rdoc-ref:Numeric@Whats+Here]
* and {class Object}[rdoc-ref:Object@Whats+Here].
* - Includes {module Comparable}[rdoc-ref:Comparable@Whats+Here].
*
* Here, class \Integer provides methods for:
*
Expand Down Expand Up @@ -6365,8 +6365,8 @@ int_s_try_convert(VALUE self, VALUE num)
*
* First, what's elsewhere. Class \Numeric:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Comparable}[rdoc-ref:Comparable@What-27s+Here].
* - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
* - Includes {module Comparable}[rdoc-ref:Comparable@Whats+Here].
*
* Here, class \Numeric provides methods for:
*
Expand Down
4 changes: 2 additions & 2 deletions object.c
Original file line number Diff line number Diff line change
Expand Up @@ -4357,8 +4357,8 @@ rb_f_loop_size(VALUE self, VALUE args, VALUE eobj)
*
* First, what's elsewhere. Class \Object:
*
* - Inherits from {class BasicObject}[rdoc-ref:BasicObject@What-27s+Here].
* - Includes {module Kernel}[rdoc-ref:Kernel@What-27s+Here].
* - Inherits from {class BasicObject}[rdoc-ref:BasicObject@Whats+Here].
* - Includes {module Kernel}[rdoc-ref:Kernel@Whats+Here].
*
* Here, class \Object provides methods for:
*
Expand Down
4 changes: 2 additions & 2 deletions range.c
Original file line number Diff line number Diff line change
Expand Up @@ -2768,8 +2768,8 @@ range_overlap(VALUE range, VALUE other)
*
* First, what's elsewhere. Class \Range:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
* - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@Whats+Here],
* which provides dozens of additional methods.
*
* Here, class \Range provides methods that are useful for:
Expand Down
4 changes: 2 additions & 2 deletions set.c
Original file line number Diff line number Diff line change
Expand Up @@ -2051,8 +2051,8 @@ rb_set_size(VALUE set)
*
* First, what's elsewhere. \Class \Set:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
* - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@Whats+Here],
* which provides dozens of additional methods.
*
* In particular, class \Set does not have many methods of its own
Expand Down
4 changes: 2 additions & 2 deletions string.c
Original file line number Diff line number Diff line change
Expand Up @@ -12174,8 +12174,8 @@ rb_str_unicode_normalized_p(int argc, VALUE *argv, VALUE str)
*
* First, what's elsewhere. Class +Symbol+:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Comparable}[rdoc-ref:Comparable@What-27s+Here].
* - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
* - Includes {module Comparable}[rdoc-ref:Comparable@Whats+Here].
*
* Here, class +Symbol+ provides methods that are useful for:
*
Expand Down
4 changes: 2 additions & 2 deletions struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -2134,8 +2134,8 @@ rb_data_inspect(VALUE s)
*
* First, what's elsewhere. Class \Struct:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
* - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@Whats+Here],
* which provides dozens of additional methods.
*
* See also Data, which is a somewhat similar, but stricter concept for defining immutable
Expand Down
33 changes: 33 additions & 0 deletions test/ruby/test_thread.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1664,4 +1664,37 @@ def test_mn_threads_sub_millisecond_sleep
assert_operator elapsed, :>=, 0.1, "sub-millisecond sleeps should not return immediately"
end;
end

# [Bug #21840]
def test_mutex_owner_doesnt_starve_waiters
assert_ruby_status([], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
m = Mutex.new
fib = lambda { |n|
return n if n <= 1
fib(n - 1) + fib(n - 2)
}
t1_running = false
t1 = Thread.new do
t1_running = true
loop do
fib(20)
m.synchronize do
File.open(__FILE__) { } # reset timeslice due to blocking operation
end
end
end
loop until t1_running
3.times.map do
Thread.new do
m.synchronize do
end
end
end.each(&:join)
end;
end
end
24 changes: 22 additions & 2 deletions thread_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ typedef struct rb_mutex_struct {
rb_thread_t *th; // even if the fiber is collected, we might need access to the thread in mutex_free
struct rb_mutex_struct *next_mutex;
struct ccan_list_head waitq; /* protected by GVL */
uint32_t saved_running_time_us;
bool wait_waking; // Is there a thread waiting to be woken up by this mutex? Reset during every wakeup.
} rb_mutex_t;

/* sync_waiter is always on-stack */
Expand Down Expand Up @@ -212,8 +214,15 @@ mutex_locked(rb_mutex_t *mutex, rb_thread_t *th, rb_serial_t ec_serial)
static inline bool
do_mutex_trylock(rb_mutex_t *mutex, rb_thread_t *th, rb_serial_t ec_serial)
{
// NOTE: we can successfully lock a mutex even if there are other threads waiting on it. First one to it wins.
if (mutex->ec_serial == 0) {
RUBY_DEBUG_LOG("%p ok", mutex);
if (mutex->wait_waking) {
// If we acquired `mutex` without contention and before the thread that was popped off the waitq, we're going
// to set our running_time back to what it was here during mutex unlock if it got reset during our critical
// section. This is to prevent starvation of other threads waiting on the mutex.
mutex->saved_running_time_us = th->running_time_us;
}

mutex_locked(mutex, th, ec_serial);
return true;
Expand Down Expand Up @@ -350,7 +359,8 @@ do_mutex_lock(struct mutex_args *args, int interruptible_p)
}
ccan_list_del(&sync_waiter.node);

// unlocked by another thread while sleeping
// If mutex->ec_serial != 0, the mutex was locked by another thread before we had the chance to acquire it.
// We'll put ourselves on the waitq and sleep again.
if (!mutex->ec_serial) {
mutex_set_owner(mutex, th, ec_serial);
}
Expand Down Expand Up @@ -391,6 +401,7 @@ do_mutex_lock(struct mutex_args *args, int interruptible_p)

if (saved_ints) th->ec->interrupt_flag = saved_ints;
if (mutex->ec_serial == ec_serial) mutex_locked(mutex, th, ec_serial);
mutex->wait_waking = false;
}

RUBY_DEBUG_LOG("%p locked", mutex);
Expand Down Expand Up @@ -454,6 +465,15 @@ rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t *th, rb_serial_t ec_serial)

struct sync_waiter *cur = 0, *next;


if (mutex->wait_waking) {
uint32_t saved = mutex->saved_running_time_us;
if (th->running_time_us < saved) {
th->running_time_us = saved;
}
}

mutex->saved_running_time_us = 0;
mutex->ec_serial = 0;
thread_mutex_remove(th, mutex);

Expand All @@ -469,6 +489,7 @@ rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t *th, rb_serial_t ec_serial)
case THREAD_RUNNABLE: /* from someone else calling Thread#run */
case THREAD_STOPPED_FOREVER: /* likely (rb_mutex_lock) */
RUBY_DEBUG_LOG("wakeup th:%u", rb_th_serial(cur->th));
mutex->wait_waking = true;
rb_threadptr_interrupt(cur->th);
return NULL;
case THREAD_STOPPED: /* probably impossible */
Expand All @@ -480,7 +501,6 @@ rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t *th, rb_serial_t ec_serial)
}
}
}

// We did not find any threads to wake up, so we can just return with no error:
return NULL;
}
Expand Down
4 changes: 2 additions & 2 deletions timev.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@
#
# First, what's elsewhere. Class +Time+:
#
# - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
# - Includes {module Comparable}[rdoc-ref:Comparable@What-27s+Here].
# - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
# - Includes {module Comparable}[rdoc-ref:Comparable@Whats+Here].
#
# Here, class +Time+ provides methods that are useful for:
#
Expand Down
Loading