#13447: Make libsingular multivariate polynomial rings collectable
----------------------------------------------------------------+-----------
       Reporter:  nbruin                                        |         
Owner:                                 
           Type:  defect                                        |        
Status:  needs_info                     
       Priority:  major                                         |     
Milestone:  sage-5.4                       
      Component:  memleak                                       |    
Resolution:                                 
       Keywords:                                                |   Work 
issues:  Input from a libsingular expert
Report Upstream:  None of the above - read trac for reasoning.  |     
Reviewers:  Simon King                     
        Authors:  Nils Bruin, Simon King                        |     Merged 
in:                                 
   Dependencies:  #11521                                        |      
Stopgaps:                                 
----------------------------------------------------------------+-----------

Comment (by nbruin):

 Replying to [comment:53 SimonKing]:
 > According to the code snipped, the ring is deleted if `r->ref==0`. So,
 apparently `r->ref==0` means that there is ''no'' reference.

 Indeed, but this is tested ''before'' decrement. So for this to work,
 you'd need
 {{{
    R=create_ring_with_appropriate_refcount
    // here R.ref should be 0
    //for the following to cause deletion.
    intrusive_ptr_release(R)
 }}}
 We initialize `R.ref=1` in `singular_ring_new`.

 > If `ref<=0` then no reference is left, hence, the ring is deleted.
 Otherwise, the reference counter is decremented. I really don't understand
 the problem.

 If `ref<=0` BEFORE the reference count is decreased. The difference is
 that `intrusive_ptr_release` happily leaves a ring in memory that AFTER
 the call has R.ref==0. Our `singular_ring_delete` will only abstain from
 calling `rDelete(doomed)` if after the call we have `doomed.ref > 0`.
 {{{
         401         doomed.ref = doomed.ref-1
         402         if doomed.ref > 0:
         403             return
 }}}
 The two behaviours are off-by-one.

 > Singular tests whether `ref<=0`; if it is, then the ring is deleted, but
 if it isn't then the counter is decremented.
 >
 > We first decrement the counter, and then test whether `ref<0`; if it is,
 then the ring is deleted, but if it isn't then no further action is taken.

 We don't. We test whether `ref<=0` (or rather whether `ref>0` to see if we
 should do an early exit).

 As our doctests show, apparently we're never calling
 `singular_ring_delete` on rings we haven't initialized the `ref` field on
 ourselves and that singular expects to to survive after we do, since that
 would probably lead to an error (Singular would try to access a
 deallocated ring).

 A mismatch in the other direction would be milder: Singular takes a
 reference on a ring we initialized the ref field on, we lose our last
 reference via a `singular_ring_delete` (no rDelete gets called because
 Singular correctly increased the refcount). However, Singular will never
 delete the ring because we originally initialized the ref field to 1
 whereas Singular apparently expects it to be initialized to 0.

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/13447#comment:54>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sage-trac?hl=en.

Reply via email to