Re: [Boost-bugs] [Boost C++ Libraries] #12542: multi_index constraint violation if rollback callable is passed, but doesn't correct the issue

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #12542: multi_index constraint violation if rollback callable is passed, but doesn't correct the issue
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-10-23 18:30:39


#12542: multi_index constraint violation if rollback callable is passed, but
doesn't correct the issue
-----------------------------------+-------------------------
  Reporter: Jon Kalb <jonkalb@…> | Owner: joaquin
      Type: Bugs | Status: new
 Milestone: To Be Determined | Component: multi_index
   Version: Boost 1.61.0 | Severity: Problem
Resolution: | Keywords:
-----------------------------------+-------------------------

Comment (by anonymous):

 Hi Jon,

 OK, I think I'm buying your point. My thought process has been somewhat
 convoluted, though, let me explain:

 Re-reading the specs for non-rollback `modify` I noticed this (italics
 mine):

 "'''Exception safety:''' Basic. If an exception is thrown by some user-
 provided operation ''(except possibly `mod`)'', then the element pointed
 to by `position` is erased."

 So I was like, am I really allowing the user to throw inside `mod` without
 the lib checking the consistency of the element? In fact I am:

 {{{
 template<typename Modifier>
 bool modify_(Modifier& mod,node_type* x)
 {
   mod(const_cast<value_type&>(x->value()));

   BOOST_TRY{
     ...
 }}}

 and this opens up a real case of consistency breach:

 {{{
 struct element
 {
   std::string x,y;
 };
 ...
 i.modify(it,[](element& e){
   e.x="whatever"; // dynamic allocation, can throw
   e.y="and ever"; // idem
 });
 }}}

 This example can throw in between assigments to `x` and `y`, making
 `modify` return without checking for consistency (uniqueness,
 rearranging). So, this is a design flaw in `modify` (both with and without
 rollback) and I have to correct it. We have two options when `mod` throws:
 delete the element or go ahead with rearranging; as throwing is an
 indication of failure, I think the natural thing to do is delete, and
 moreover going ahead in the rollback version is problematic, since the
 element was left in mid-modification and `rollback` could expect something
 else (your opinion on this point most welcome). The current situation is
 then

 * `mod` is not guarded against throws but is guarded against inconsistency
 (rollback or element deletion if no rollback provided)
 * `rollback` is guarded against throws (element deletion) but is not
 guarded against inconsistency

 and after I correct the problem with `mod` we'll have

 * `mod` is guarded against throws (element deletion) and inconsistency
 (rollback or element deletion if no rollback provided)
 * `rollback` is guarded against throws (element deletion) but not guarded
 against inconsistency

 and now I'm leaning more towards your position out of considerations of
 symmetry:

 * `mod` is guarded against throws (element deletion) and inconsistency
 (rollback or element deletion if no rollback provided)
 * `rollback` is guarded against throws and inconsistency (element
 deletion)

 So, I'l put myself to clean this up. The changes required are not entirely
 trivial, though, and require extra care to get them right (as I guess
 you'll guess after this conversation), so it's going to take me some weeks
 before I find the time --I'm also in the process of finishing something up
 for Boost submission, so my current C++ slot is occupied.

 Thanks for the interesting discussion,

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/12542#comment:5>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC