From 928a06723d1ede495b7c3b42f3ca48e370ccec77 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Sat, 19 Dec 2020 02:45:47 +0900 Subject: [PATCH] [bigdecimal] Make bigdecimal Ractor safe https://github.com/ruby/bigdecimal/commit/93fc392640 https://github.com/ruby/bigdecimal/commit/a90d13c4d0 --- ext/bigdecimal/bigdecimal.c | 13 ++++++++++++- test/bigdecimal/test_ractor.rb | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/bigdecimal/test_ractor.rb diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 9952193e13..039a4d7338 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -189,11 +189,16 @@ BigDecimal_memsize(const void *ptr) return (sizeof(*pv) + pv->MaxPrec * sizeof(BDIGIT)); } +#ifndef HAVE_RB_EXT_RACTOR_SAFE +# undef RUBY_TYPED_FROZEN_SHAREABLE +# define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + static const rb_data_type_t BigDecimal_data_type = { "BigDecimal", { 0, BigDecimal_delete, BigDecimal_memsize, }, #ifdef RUBY_TYPED_FREE_IMMEDIATELY - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE #endif }; @@ -3351,6 +3356,9 @@ get_vp_value: void Init_bigdecimal(void) { +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif VALUE arg; id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode"); @@ -3617,6 +3625,9 @@ static void VpFormatSt(char *psz, size_t fFmt); static int VpRdup(Real *m, size_t ind_m); #ifdef BIGDECIMAL_DEBUG +# ifdef HAVE_RB_EXT_RACTOR_SAFE +# error Need to make rewiting gnAlloc atomic +# endif static int gnAlloc = 0; /* Memory allocation counter */ #endif /* BIGDECIMAL_DEBUG */ diff --git a/test/bigdecimal/test_ractor.rb b/test/bigdecimal/test_ractor.rb new file mode 100644 index 0000000000..3ccd7c8073 --- /dev/null +++ b/test/bigdecimal/test_ractor.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +require_relative "testbase" + +class TestBigDecimalRactor < Test::Unit::TestCase + include TestBigDecimalBase + + def setup + super + skip unless defined? Ractor + end + + def test_ractor_shareable + assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + $VERBOSE = nil + require "bigdecimal" + r = Ractor.new BigDecimal(Math::PI, Float::DIG+1) do |pi| + BigDecimal('2.0')*pi + end + assert_equal(2*Math::PI, r.take) + end; + end +end