Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions bootstraptest/test_ractor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2444,35 +2444,45 @@ def call_test(obj)
# When creating bmethods in Ractors, they should only be usable from their
# defining ractor, even if it is GC'd
assert_equal 'ok', <<~'RUBY'
CLASSES = 1000.times.map { Class.new }.freeze

# This would be better to run in parallel, but there's a bug with lambda
# creation and YJIT causing crashes in dev mode
ractors = CLASSES.map do |klass|
Ractor.new(klass) do |klass|
Ractor.receive
klass.define_method(:foo) {}
begin
CLASSES = 1000.times.map { Class.new }.freeze

# This would be better to run in parallel, but there's a bug with lambda
# creation and YJIT causing crashes in dev mode
ractors = CLASSES.map do |klass|
Ractor.new(klass) do |klass|
Ractor.receive
klass.define_method(:foo) {}
end
end
end

ractors.each do |ractor|
ractor << nil
ractor.join
end
ractors.each do |ractor|
ractor << nil
ractor.join
end

ractors.clear
GC.start
ractors.clear
GC.start

any = 1000.times.map do
Ractor.new do
CLASSES.any? do |klass|
begin
klass.new.foo
true
rescue RuntimeError
false
any = 1000.times.map do
Ractor.new do
CLASSES.any? do |klass|
begin
klass.new.foo
true
rescue RuntimeError
false
end
end
end
end.map(&:value).none? && :ok
rescue ThreadError => e
# ignore limited memory machine
if /can\'t create Thread/ =~ e.message
:ok
else
raise
end
end.map(&:value).none? && :ok
end
RUBY
59 changes: 33 additions & 26 deletions ext/win32/resolv/resolv.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ w32error_make_error(DWORD e)
FORMAT_MESSAGE_IGNORE_INSERTS, &source, e,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
buffer, sizeof(buffer), NULL)) {
snprintf(buffer, sizeof(buffer), "Unknown Error %u", (unsigned long)e);
snprintf(buffer, sizeof(buffer), "Unknown Error %lu", (unsigned long)e);
}
p = buffer;
while ((p = strpbrk(p, "\r\n")) != NULL) {
Expand Down Expand Up @@ -149,7 +149,6 @@ reg_each_key(VALUE self)
{
WCHAR wname[256];
HKEY hkey = DATA_PTR(self);
rb_encoding *utf8 = rb_utf8_encoding();
VALUE k = TypedData_Wrap_Struct(CLASS_OF(self), &hkey_type, NULL);
DWORD i, e, n;
for (i = 0; n = numberof(wname), (e = RegEnumKeyExW(hkey, i, wname, &n, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS; i++) {
Expand Down Expand Up @@ -183,50 +182,58 @@ reg_value(VALUE self, VALUE name)
e = RegGetValueW(hkey, NULL, wname, RRF_RT_ANY, &type, NULL, &size);
if (e == ERROR_FILE_NOT_FOUND) return Qnil;
w32error_check(e);
# define get_value_2nd(data, dsize) do { \
DWORD type2 = type; \
w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_ANY, &type2, data, dsize)); \
if (type != type2) { \
rb_raise(rb_eRuntimeError, "registry value type changed %lu -> %lu", \
(unsigned long)type, (unsigned long)type2); \
} \
} while (0)

switch (type) {
case REG_DWORD: case REG_DWORD_BIG_ENDIAN:
{
DWORD d;
if (size != sizeof(d)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", size);
if (size != sizeof(d)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", (unsigned long)size);
w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_REG_DWORD, &type, &d, &size));
if (type == REG_DWORD_BIG_ENDIAN) d = swap_dw(d);
return ULONG2NUM(d);
}
case REG_QWORD:
{
QWORD q;
if (size != sizeof(q)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", size);
if (size != sizeof(q)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", (unsigned long)size);
w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_REG_QWORD, &type, &q, &size));
return ULL2NUM(q);
}
case REG_SZ: case REG_MULTI_SZ: case REG_EXPAND_SZ:
if (size % sizeof(WCHAR)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", size);
if (size % sizeof(WCHAR)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", (unsigned long)size);
buffer = ALLOCV_N(char, value_buffer, size);
get_value_2nd(buffer, &size);
if (type == REG_MULTI_SZ) {
const WCHAR *w = (WCHAR *)buffer;
result = rb_ary_new();
size /= sizeof(WCHAR);
size -= 1;
for (size_t i = 0; i < size; ++i) {
int n = lstrlenW(w+i);
rb_ary_push(result, wchar_to_utf8(w+i, n));
i += n;
}
}
else {
result = wchar_to_utf8((WCHAR *)buffer, lstrlenW((WCHAR *)buffer));
}
ALLOCV_END(value_buffer);
break;
default:
result = rb_str_new(0, size);
buffer = RSTRING_PTR(result);
}
w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_ANY, &type, buffer, &size));
switch (type) {
case REG_MULTI_SZ: {
const WCHAR *w = (WCHAR *)buffer;
rb_encoding *utf8 = rb_utf8_encoding();
result = rb_ary_new();
size /= sizeof(WCHAR);
size -= 1;
for (size_t i = 0; i < size; ++i) {
int n = lstrlenW(w+i);
rb_ary_push(result, wchar_to_utf8(w+i, n));
i += n;
}
return result;
}
case REG_SZ: case REG_EXPAND_SZ:
return wchar_to_utf8((WCHAR *)buffer, lstrlenW((WCHAR *)buffer));
default:
return result;
get_value_2nd(RSTRING_PTR(result), &size);
rb_str_set_len(result, size);
break;
}
return result;
}

void
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/templates/newgem/lib/newgem.rb.tt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require_relative "<%= File.basename(config[:namespaced_path]) %>/version"
<%- if config[:ext] -%>
require_relative "<%= File.basename(config[:namespaced_path]) %>/<%= config[:underscored_name] %>"
require "<%= File.basename(config[:namespaced_path]) %>/<%= config[:underscored_name] %>"
<%- end -%>

<%- config[:constant_array].each_with_index do |c, i| -%>
Expand Down
7 changes: 7 additions & 0 deletions spec/bundler/commands/newgem_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,13 @@ def create_temporary_dir(dir)
expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.c")).to exist
end

it "generates native extension loading code" do
expect(bundled_app("#{gem_name}/lib/#{gem_name}.rb").read).to include(<<~RUBY)
require_relative "test_gem/version"
require "#{gem_name}/#{gem_name}"
RUBY
end

it "includes rake-compiler, but no Rust related changes" do
expect(bundled_app("#{gem_name}/Gemfile").read).to include('gem "rake-compiler"')

Expand Down
4 changes: 3 additions & 1 deletion thread_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,8 @@ mutex_sleep_begin(VALUE _arguments)
VALUE
rb_mutex_sleep(VALUE self, VALUE timeout)
{
rb_execution_context_t *ec = GET_EC();

if (!NIL_P(timeout)) {
// Validate the argument:
rb_time_interval(timeout);
Expand All @@ -614,7 +616,7 @@ rb_mutex_sleep(VALUE self, VALUE timeout)

VALUE woken = rb_ensure(mutex_sleep_begin, (VALUE)&arguments, mutex_lock_uninterruptible, self);

RUBY_VM_CHECK_INTS_BLOCKING(GET_EC());
RUBY_VM_CHECK_INTS_BLOCKING(ec);
if (!woken) return Qnil;
time_t end = time(0) - beg;
return TIMET2NUM(end);
Expand Down