summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-26 07:00:04 +0000
committerkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-26 07:00:04 +0000
commitcb0a4c0f6231639dab11d50b21614cbea019e5d4 (patch)
treef624d00849c92461652879b065649a0693bc575d
parent6f3ad9bd3d1c0fd53539d55743b445d67360e911 (diff)
* bignum.c (bigdivrem): restart calculation when bigdivrem1 was
interrupted by signal. Otherwise, ruby script may see a garbage value. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37850 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--bignum.c15
2 files changed, 19 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 48d5e9cbf7..9a4e41f39f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Mon Nov 26 15:50:29 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+
+ * bignum.c (bigdivrem): restart calculation when bigdivrem1 was
+ interrupted by signal. Otherwise, ruby script may see a garbage
+ value.
+
Mon Nov 26 15:33:02 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* bignum.c (big_div_struct): added volatile to 'stop' member.
diff --git a/bignum.c b/bignum.c
index 8939282ebf..798571deba 100644
--- a/bignum.c
+++ b/bignum.c
@@ -2713,16 +2713,22 @@ rb_big_stop(void *ptr)
}
static VALUE
-bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
+bigdivrem(VALUE x, VALUE y_, volatile VALUE *divp, volatile VALUE *modp)
{
+ VALUE y;
struct big_div_struct bds;
- long nx = RBIGNUM_LEN(x), ny = RBIGNUM_LEN(y);
+ long nx, ny;
long i, j;
VALUE z, yy, zz;
BDIGIT *xds, *yds, *zds, *tds;
BDIGIT_DBL t2;
BDIGIT dd, q;
+ retry:
+ y = y_;
+ nx = RBIGNUM_LEN(x);
+ ny = RBIGNUM_LEN(y);
+
if (BIGZEROP(y)) rb_num_zerodiv();
xds = BDIGITS(x);
yds = BDIGITS(y);
@@ -2795,6 +2801,11 @@ bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
bds.stop = Qfalse;
if (nx > 10000 || ny > 10000) {
rb_thread_call_without_gvl(bigdivrem1, &bds, rb_big_stop, &bds);
+
+ if (bds.stop == Qtrue) {
+ /* execute trap handler, but exception was not raised. */
+ goto retry;
+ }
}
else {
bigdivrem1(&bds);