1// Copyright (C) 2013 Vicente Botet
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6// futtest.cpp
7#include <iostream>
8#define BOOST_THREAD_VERSION 4
9
10#include <boost/thread/future.hpp>
11#include <boost/thread/thread.hpp>
12#include <boost/bind.hpp>
13#include <boost/chrono.hpp>
14#include <boost/shared_ptr.hpp>
15#include <boost/scoped_ptr.hpp>
16
17typedef boost::shared_ptr< boost::promise<int> > IntPromise;
18
19void foo(IntPromise p)
20{
21 std::cout << "foo" << std::endl;
22 p->set_value(123); // This line locks the future's mutex, then calls the continuation with the mutex already locked.
23}
24
25void bar(boost::future<int> fooResult)
26{
27 try {
28 std::cout << "bar" << std::endl;
29 int i = fooResult.get(); // Code hangs on this line (Due to future already being locked by the set_value call)
30 std::cout << "i: " << i << std::endl;
31 } catch(...) {
32 std::cout << __FILE__ << ":" << __LINE__ << std::endl;
33 }
34}
35
36int main()
37{
38 std::cout << __FILE__ << ":" << __LINE__ << std::endl;
39 try {
40 IntPromise p(new boost::promise<int>());
41 boost::thread t(boost::bind(f: foo, a1: p));
42 boost::future<int> f1 = p->get_future();
43 f1.then(policy: boost::launch::deferred, func: &bar);
44 t.join();
45 } catch(...) {
46 return 1;
47 }
48 std::cout << __FILE__ << ":" << __LINE__ << std::endl;
49 try {
50 IntPromise p(new boost::promise<int>());
51 boost::thread t(boost::bind(f: foo, a1: p));
52 boost::future<int> f1 = p->get_future();
53 f1.then(policy: boost::launch::async, func: &bar);
54 t.join();
55 } catch(...) {
56 return 2;
57 }
58 std::cout << __FILE__ << ":" << __LINE__ << std::endl;
59}
60
61

source code of boost/libs/thread/test/test_9319.cpp