Subject: [boost] [thread] Questions about broken_promise
From: Klaim - Joël Lamotte (mjklaim_at_[hidden])
Date: 2013-07-28 17:24:23


I have a few questions concerning broken promises (exception):

1. is the broken_promise exception a standard, or future standard behaviour?
So far I assumed it wasn't because
http://en.cppreference.com/w/cpp/thread/promise/~promise
don't say anything about this and I only read about broken_promise
exceptions on Boost.Thread
documentation.
I would like to know if I should expect the future standard library to have
the same concept.
I see no configuration macro to deactivate these exceptions. I don't want
to actually, but
if I'm correct that it's not standard or future standard, then it's
surprising that I can't setup
a standard-like setup.

2. I have a case that could be summarized like this:

/////////////////////////////////////////////

Updated by thread A:

struct X { /*... */ };

struct K
{
    future<shared_ptr<X,U>> m_ft_x;
    shared_ptr<X,U> m_x;

    K( Foo& foo )
        : m_ft_x( foo.create<X>() )
    {}

    void update() // this is always called by a loop in the thread A
    {
        if( !m_x )
        {
             if( m_ft_x.has_value() )
                 m_x = m_ft_x.get();
        }
        else
           work();
    }

    void work(); // uses m_x

};

Updated by thread B:

// special deleter which will just push a task in Foo work queue for
deleting the object
// in sync with thread B
struct U { /* ... */ };

struct Foo
{
     template< class T >
     future<shared_ptr<T,U>> create() // will push a creation task in a
work queue updated in update()

     void update(); // called by a loop in the thread B, will execute all
the work pushed in the work queue.

};

/////////////////////////////////////////////

(this is an exageratedly simplified version of what I'm doing)
It works nicely (even if I think it could be improved with future.then and
other tools)
but there is a minor problem appearing when an instance of
K is constructed then almost immediately destructed,
 before the instance of Foo executed the creation of the X instance.
In this case, visual studio (which is configured to detect all throw calls)
detect a broken_promise exception thrown from the
destructor of the promise which was in the code generated by Foo::create()
and pushed in a work queue.

I look at the destructor and I see:

if(!future_->done && !future_->is_constructed)
                {

future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()),
lock);
                }

Here is the full copy_exception code:

template <class T>
    inline
    exception_ptr
    copy_exception( T const & e )
        {
        try
            {
            throw enable_current_exception(e);
            }
        catch(
        ... )
            {
            return current_exception();
            }
        }

This code triggers actually two "first-chance" exceptions this is the first
one)
 which are catch immediately intentionally.

My question is: why is copy_exception necessary and why does it have to do
it this way?
It's a very minor problem as just re-setting my visual studio debugging
settings to default
makes the exception transparent -only visible in the console log.
However each time I activate debug breaking on all c++ exception so that I
can debug
some potential issues, I can have a breakpoint which is actually "noise" as
it is only used
to implement a copy of exception.
Is it possible to eliminate this noise? Or, as I'm guessing, is there a
language or compiler limitation
which forces this code to be written this way?

Thanks for your time.

Joel Lamotte