Skip to content

Commit

Permalink
fix issues with fallback_to. The route cause was that the original fu…
Browse files Browse the repository at this point in the history
…ture was locked after destruction. This was more evident when the future was already ready when future::then was called.
  • Loading branch information
viboes committed Feb 20, 2015
1 parent 63fb28c commit 889c178
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 42 deletions.
51 changes: 25 additions & 26 deletions example/future_fallback_to.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,39 +35,38 @@ int p1()

int main()
{
const int number_of_tests = 100;
const int number_of_tests = 200;
BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;

// {
// for (int i=0; i< number_of_tests; i++)
// try
// {
// BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
// boost::future<int> f1 = boost::async(boost::launch::async, &p1);
// BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
// f1.wait();
// BOOST_ASSERT(f1.get()==1);
// BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
// }
// catch (std::exception& ex)
// {
// std::cout << __FILE__ << "["<< __LINE__<<"] " << "ERRORRRRR "<<ex.what() << "" << std::endl;
// BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
// return 1;
// }
// catch (...)
// {
// std::cout << __FILE__ << "["<< __LINE__<<"] " << " ERRORRRRR exception thrown" << std::endl;
// BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
// return 2;
// }
// }
{
for (int i=0; i< number_of_tests; i++)
try
{
BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
boost::future<int> f1 = boost::async(boost::launch::async, &p1);
BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
f1.wait();
BOOST_ASSERT(f1.get()==1);
BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "["<< __LINE__<<"] " << "ERRORRRRR "<<ex.what() << "" << std::endl;
BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
return 1;
}
catch (...)
{
std::cout << __FILE__ << "["<< __LINE__<<"] " << " ERRORRRRR exception thrown" << std::endl;
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
return 2;
}
}

{
for (int i=0; i< number_of_tests; i++)
try
{
//boost::future<int> f1 = boost::async(boost::launch::async, &p1);
BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
boost::future<int> f1 = boost::async(&p1);
BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
Expand Down
44 changes: 29 additions & 15 deletions include/boost/thread/future.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,24 +93,21 @@ namespace boost
struct relocker
{
boost::unique_lock<boost::mutex>& lock_;
bool unlocked_;

relocker(boost::unique_lock<boost::mutex>& lk):
lock_(lk)
{
lock_.unlock();
unlocked_=true;
}
~relocker()
{
if (unlocked_) {
if (! lock_.owns_lock()) {
lock_.lock();
}
}
void lock() {
if (unlocked_) {
if (! lock_.owns_lock()) {
lock_.lock();
unlocked_=false;
}
}
private:
Expand Down Expand Up @@ -220,10 +217,10 @@ namespace boost
void do_continuation(boost::unique_lock<boost::mutex>& lock)
{
if (! continuations.empty()) {
continuations_type this_continuations = continuations;
continuations_type the_continuations = continuations;
continuations.clear();
relocker rlk(lock);
for (continuations_type::iterator it = this_continuations.begin(); it != this_continuations.end(); ++it) {
for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) {
boost::unique_lock<boost::mutex> cont_lock((*it)->mutex);
(*it)->launch_continuation(cont_lock, *it);
}
Expand Down Expand Up @@ -4026,11 +4023,13 @@ namespace detail
{
F parent;
Fp continuation;
shared_ptr<shared_state_base> centinel;

public:
future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: parent(boost::move(f)),
continuation(boost::move(c)) {
continuation(boost::move(c)),
centinel(parent.future_) {
}


Expand All @@ -4056,11 +4055,13 @@ namespace detail
{
F parent;
Fp continuation;
shared_ptr<shared_state_base> centinel;

public:
future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: parent(boost::move(f)),
continuation(boost::move(c)) {
continuation(boost::move(c)),
centinel(parent.future_) {
}

void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
Expand Down Expand Up @@ -4104,11 +4105,13 @@ namespace detail
Ex* ex;
F parent;
Fp continuation;
shared_ptr<shared_state_base> centinel;

public:
future_executor_continuation_shared_state(Ex& ex, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: ex(&ex), parent(boost::move(f)),
continuation(boost::move(c)) {
continuation(boost::move(c)),
centinel(parent.future_) {
this->set_executor();
}

Expand Down Expand Up @@ -4141,11 +4144,13 @@ namespace detail
Ex* ex;
F parent;
Fp continuation;
shared_ptr<shared_state_base> centinel;

public:
future_executor_continuation_shared_state(Ex& ex, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: ex(&ex), parent(boost::move(f)),
continuation(boost::move(c)) {
continuation(boost::move(c)),
centinel(parent.future_) {
this->set_executor();
}

Expand Down Expand Up @@ -4183,11 +4188,13 @@ namespace detail
{
F parent;
Fp continuation;
shared_ptr<shared_state_base> centinel;

public:
shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
: parent(f),
continuation(boost::move(c)) {
continuation(boost::move(c)),
centinel(parent.future_) {
}

void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
Expand All @@ -4211,11 +4218,13 @@ namespace detail
{
F parent;
Fp continuation;
shared_ptr<shared_state_base> centinel;

public:
shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
: parent(f),
continuation(boost::move(c)) {
continuation(boost::move(c)),
centinel(parent.future_) {
}

void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
Expand Down Expand Up @@ -4246,11 +4255,13 @@ namespace detail
Ex* ex;
F parent;
Fp continuation;
shared_ptr<shared_state_base> centinel;

public:
shared_future_executor_continuation_shared_state(Ex& ex, F f, BOOST_THREAD_FWD_REF(Fp) c)
: ex(&ex), parent(f),
continuation(boost::move(c)) {
continuation(boost::move(c)),
centinel(parent.future_) {
this->set_executor();
}

Expand Down Expand Up @@ -4283,11 +4294,13 @@ namespace detail
Ex* ex;
F parent;
Fp continuation;
shared_ptr<shared_state_base> centinel;

public:
shared_future_executor_continuation_shared_state(Ex& ex, F f, BOOST_THREAD_FWD_REF(Fp) c)
: ex(&ex), parent(f),
continuation(boost::move(c)) {
continuation(boost::move(c)),
centinel(parent.future_) {
}

void launch_continuation(boost::unique_lock<boost::mutex>& lck, shared_ptr<shared_state_base> that) {
Expand Down Expand Up @@ -4532,6 +4545,7 @@ namespace detail
lock.lock();
h->parent.future_->set_continuation_ptr(h, lock);
lock.unlock();

return BOOST_THREAD_FUTURE<Rp>(h);
}
////////////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ rule thread-compile ( sources : reqs * : name )
#[ thread-run ../example/vhh_shared_monitor.cpp ]
#[ thread-run ../example/vhh_shared_mutex.cpp ]
[ thread-run2 ../example/make_future.cpp : ex_make_future ]
#[ thread-run2 ../example/future_then.cpp : ex_future_then ]
[ thread-run2 ../example/future_then.cpp : ex_future_then ]
[ thread-run2 ../example/future_fallback_to.cpp : ex_future_fallback_to ]
[ thread-run2 ../example/future_unwrap.cpp : ex_future_unwrap ]
[ thread-run2-noit ../example/synchronized_value.cpp : ex_synchronized_value ]
Expand Down

0 comments on commit 889c178

Please sign in to comment.