Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 521bac9

Browse files
committed
Throw away mpz_t after an interrupt happened
1 parent 6d4bb9f commit 521bac9

File tree

2 files changed

+29
-21
lines changed

2 files changed

+29
-21
lines changed

src/sage/rings/integer.pyx

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,10 @@ cimport cython
144144
from libc.math cimport (ldexp, sqrt as sqrt_double, log as log_c,
145145
ceil as ceil_c, isnan)
146146
from libc.string cimport memcpy
147-
cdef extern from "<limits.h>":
148-
const long LONG_MAX # Work around https://github.com/cython/cython/pull/2016
147+
from libc.limits cimport LONG_MAX
149148

150149
from cysignals.memory cimport check_allocarray, check_malloc, sig_free
151-
from cysignals.signals cimport sig_on, sig_off, sig_check
150+
from cysignals.signals cimport sig_on, sig_off, sig_check, sig_occurred
152151

153152
import operator
154153
import sys
@@ -7296,39 +7295,41 @@ cdef PyObject* fast_tp_new(type t, args, kwds) except NULL:
72967295

72977296
return new
72987297

7299-
cdef void fast_tp_dealloc(PyObject* o):
73007298

7299+
cdef void fast_tp_dealloc(PyObject* o):
73017300
# If there is room in the pool for a used integer object,
73027301
# then put it in rather than deallocating it.
7303-
73047302
global integer_pool, integer_pool_count
73057303

73067304
cdef mpz_ptr o_mpz = <mpz_ptr>((<Integer>o).value)
73077305

7308-
if integer_pool_count < integer_pool_size:
7306+
# If we are recovering from an interrupt, throw the mpz_t away
7307+
# without recycling or freeing it because it might be in an
7308+
# inconsistent state (see Trac #24986).
7309+
if sig_occurred() is NULL:
7310+
if integer_pool_count < integer_pool_size:
7311+
# Here we free any extra memory used by the mpz_t by
7312+
# setting it to a single limb.
7313+
if o_mpz._mp_alloc > 10:
7314+
_mpz_realloc(o_mpz, 1)
73097315

7310-
# Here we free any extra memory used by the mpz_t by
7311-
# setting it to a single limb.
7312-
if o_mpz._mp_alloc > 10:
7313-
_mpz_realloc(o_mpz, 1)
7316+
# It's cheap to zero out an integer, so do it here.
7317+
o_mpz._mp_size = 0
73147318

7315-
# It's cheap to zero out an integer, so do it here.
7316-
o_mpz._mp_size = 0
7319+
# And add it to the pool.
7320+
integer_pool[integer_pool_count] = o
7321+
integer_pool_count += 1
7322+
return
73177323

7318-
# And add it to the pool.
7319-
integer_pool[integer_pool_count] = o
7320-
integer_pool_count += 1
7321-
return
7322-
7323-
# Again, we move to the mpz_t and clear it. As in fast_tp_new,
7324-
# we free the memory directly.
7325-
sig_free(o_mpz._mp_d)
7324+
# No space in the pool, so just free the mpz_t.
7325+
sig_free(o_mpz._mp_d)
73267326

73277327
# Free the object. This assumes that Py_TPFLAGS_HAVE_GC is not
73287328
# set. If it was set another free function would need to be
73297329
# called.
73307330
PyObject_Free(o)
73317331

7332+
73327333
from sage.misc.allocator cimport hook_tp_functions
73337334
cdef hook_fast_tp_functions():
73347335
"""

src/sage/structure/coerce_actions.pyx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,10 +735,17 @@ cdef class IntegerMulAction(IntegerAction):
735735
736736
Check that large multiplications can be interrupted::
737737
738-
sage: alarm(0.5); (2^(10^7)) * P # not tested; see trac:#24986
738+
sage: alarm(0.5); (2^(10^6)) * P
739739
Traceback (most recent call last):
740740
...
741741
AlarmInterrupt
742+
743+
Verify that cysignals correctly detects that the above
744+
exception has been handled::
745+
746+
sage: from cysignals.tests import print_sig_occurred
747+
sage: print_sig_occurred()
748+
No current exception
742749
"""
743750
cdef int err = 0
744751
cdef long n_long

0 commit comments

Comments
 (0)