===================================================================
@@ -326,29 +326,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Result_base&
wait()
{
- _M_run_deferred();
+ _M_complete_async();
unique_lock<mutex> __lock(_M_mutex);
- if (!_M_ready())
- _M_cond.wait(__lock, std::bind<bool>(&_State_base::_M_ready, this));
+ _M_cond.wait(__lock, [&] { return _M_ready(); });
return *_M_result;
}
template<typename _Rep, typename _Period>
- bool
+ future_status
wait_for(const chrono::duration<_Rep, _Period>& __rel)
{
unique_lock<mutex> __lock(_M_mutex);
- auto __bound = std::bind<bool>(&_State_base::_M_ready, this);
- return _M_ready() || _M_cond.wait_for(__lock, __rel, __bound);
+ if (_M_ready())
+ return future_status::ready;
+ if (_M_has_deferred())
+ return future_status::deferred;
+ if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); }))
+ return future_status::ready;
+ return future_status::timeout;
}
template<typename _Clock, typename _Duration>
- bool
+ future_status
wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
{
unique_lock<mutex> __lock(_M_mutex);
- auto __bound = std::bind<bool>(&_State_base::_M_ready, this);
- return _M_ready() || _M_cond.wait_until(__lock, __abs, __bound);
+ if (_M_ready())
+ return future_status::ready;
+ if (_M_has_deferred())
+ return future_status::deferred;
+ if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); }))
+ return future_status::ready;
+ return future_status::timeout;
}
void
@@ -480,7 +489,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool _M_ready() const noexcept { return static_cast<bool>(_M_result); }
- virtual void _M_run_deferred() { }
+ // Wait for completion of async function.
+ virtual void _M_complete_async() { }
+
+ // Return true if state contains a deferred function.
+ virtual bool _M_has_deferred() { return false; }
};
template<typename _BoundFn, typename = typename _BoundFn::result_type>
@@ -573,7 +586,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _Rep, typename _Period>
- bool
+ future_status
wait_for(const chrono::duration<_Rep, _Period>& __rel) const
{
_State_base::_S_check(_M_state);
@@ -581,7 +594,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _Clock, typename _Duration>
- bool
+ future_status
wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
{
_State_base::_S_check(_M_state);
@@ -1411,11 +1424,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_BoundFn _M_fn;
virtual void
- _M_run_deferred()
+ _M_complete_async()
{
// safe to call multiple times so ignore failure
_M_set_result(_S_task_setter(_M_result, _M_fn), true);
}
+
+ virtual bool _M_has_deferred() { return static_cast<bool>(_M_result); }
};
template<typename _BoundFn, typename _Res>
@@ -1429,18 +1444,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_thread(mem_fn(&_Async_state::_M_do_run), this)
{ }
- ~_Async_state() { _M_thread.join(); }
+ ~_Async_state() { _M_join(); }
private:
- void _M_do_run()
- {
- _M_set_result(_S_task_setter(_M_result, _M_fn));
- }
+ void _M_do_run() { _M_set_result(_S_task_setter(_M_result, _M_fn)); }
+
+ virtual void _M_complete_async() { _M_join(); }
+
+ void
+ _M_join()
+ { std::call_once(_M_once, &thread::join, ref(_M_thread)); }
typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
_Ptr_type _M_result;
_BoundFn _M_fn;
thread _M_thread;
+ once_flag _M_once;
};
template<typename _BoundFn>
===================================================================
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" }
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -36,8 +36,9 @@ void test01()
std::packaged_task<int&(int&)> p1(inc);
std::future<int&> f1 = p1.get_future();
+ std::chrono::milliseconds delay(1);
VERIFY( f1.valid() );
- VERIFY( !f1.wait_for(std::chrono::milliseconds(1)) );
+ VERIFY( f1.wait_for(delay) == std::future_status::timeout );
int i1 = 0;
===================================================================
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" }
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -42,18 +42,18 @@ void test01()
std::shared_future<int> f2(f1);
auto when = make_time(10);
- VERIFY( !f1.wait_until(make_time(10)) );
+ VERIFY( f1.wait_until(make_time(10)) == std::future_status::timeout );
VERIFY( std::chrono::system_clock::now() >= when );
when = make_time(10);
- VERIFY( !f2.wait_until(make_time(10)) );
+ VERIFY( f2.wait_until(make_time(10)) == std::future_status::timeout );
VERIFY( std::chrono::system_clock::now() >= when );
p1.set_value(1);
when = make_time(100);
- VERIFY( f1.wait_until(when) );
- VERIFY( f2.wait_until(when) );
+ VERIFY( f1.wait_until(when) == std::future_status::ready );
+ VERIFY( f2.wait_until(when) == std::future_status::ready );
VERIFY( std::chrono::system_clock::now() < when );
}
===================================================================
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" }
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -38,14 +38,14 @@ void test01()
std::chrono::milliseconds delay(100);
- VERIFY( !f1.wait_for(delay) );
- VERIFY( !f2.wait_for(delay) );
+ VERIFY( f1.wait_for(delay) == std::future_status::timeout );
+ VERIFY( f2.wait_for(delay) == std::future_status::timeout );
p1.set_value(1);
auto before = std::chrono::system_clock::now();
- VERIFY( f1.wait_for(delay) );
- VERIFY( f2.wait_for(delay) );
+ VERIFY( f1.wait_for(delay) == std::future_status::ready );
+ VERIFY( f2.wait_for(delay) == std::future_status::ready );
VERIFY( std::chrono::system_clock::now() < (before + 2*delay) );
}
===================================================================
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" }
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -41,13 +41,13 @@ void test01()
std::future<int> f1(p1.get_future());
auto when = make_time(10);
- VERIFY( !f1.wait_until(when) );
+ VERIFY( f1.wait_until(when) == std::future_status::timeout );
VERIFY( std::chrono::system_clock::now() >= when );
p1.set_value(1);
when = make_time(100);
- VERIFY( f1.wait_until(when) );
+ VERIFY( f1.wait_until(when) == std::future_status::ready );
VERIFY( std::chrono::system_clock::now() < when );
}
===================================================================
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" }
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -37,12 +37,12 @@ void test01()
std::chrono::milliseconds delay(100);
- VERIFY( !f1.wait_for(delay) );
+ VERIFY( f1.wait_for(delay) == std::future_status::timeout );
p1.set_value(1);
auto before = std::chrono::system_clock::now();
- VERIFY( f1.wait_for(delay) );
+ VERIFY( f1.wait_for(delay) == std::future_status::ready );
VERIFY( std::chrono::system_clock::now() < (before + delay) );
}
===================================================================
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" }
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -48,7 +48,8 @@ void test01()
test = true;
}
- VERIFY( f1.wait_for(std::chrono::milliseconds(1)) );
+ std::chrono::milliseconds delay(1);
+ VERIFY( f1.wait_for(delay) == std::future_status::ready );
VERIFY( f1.get() == 1 );
VERIFY( test );
}
@@ -74,7 +75,8 @@ void test02()
test = true;
}
- VERIFY( f1.wait_for(std::chrono::milliseconds(1)) );
+ std::chrono::milliseconds delay(1);
+ VERIFY( f1.wait_for(delay) == std::future_status::ready );
VERIFY( f1.get() == 3 );
VERIFY( test );
}
===================================================================
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" }
-// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -41,24 +41,26 @@ struct tester
std::promise<tester> pglobal;
std::future<tester> fglobal = pglobal.get_future();
+auto delay = std::chrono::milliseconds(1);
+
tester::tester(int)
{
bool test __attribute__((unused)) = true;
- VERIFY (!fglobal.wait_for(std::chrono::milliseconds(1)));
+ VERIFY (fglobal.wait_for(delay) == std::future_status::timeout);
}
tester::tester(const tester&)
{
bool test __attribute__((unused)) = true;
// if this copy happens while a mutex is locked next line could deadlock:
- VERIFY (!fglobal.wait_for(std::chrono::milliseconds(1)));
+ VERIFY (fglobal.wait_for(delay) == std::future_status::timeout);
}
tester& tester::operator=(const tester&)
{
bool test __attribute__((unused)) = true;
// if this copy happens while a mutex is locked next line could deadlock:
- VERIFY (!fglobal.wait_for(std::chrono::milliseconds(1)));
+ VERIFY (fglobal.wait_for(delay) == std::future_status::timeout);
return *this;
}
@@ -68,7 +70,7 @@ void test01()
pglobal.set_value( tester(1) );
- VERIFY( fglobal.wait_for(std::chrono::milliseconds(1)) );
+ VERIFY (fglobal.wait_for(delay) == std::future_status::ready);
}
int main()
===================================================================
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" }
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -35,8 +35,9 @@ void test01()
std::promise<int> p2;
p1.set_value(1);
p1.swap(p2);
- VERIFY( !p1.get_future().wait_for(std::chrono::milliseconds(1)) );
- VERIFY( p2.get_future().wait_for(std::chrono::milliseconds(1)) );
+ auto delay = std::chrono::milliseconds(1);
+ VERIFY( p1.get_future().wait_for(delay) == std::future_status::timeout );
+ VERIFY( p2.get_future().wait_for(delay) == std::future_status::ready );
}
int main()
===================================================================
@@ -39,12 +39,32 @@ void test01()
using namespace std;
int a = 1;
- int b = 10;
- int c = 100;
+ int b = 1;
+ int c = 1;
future<int> f1 = async(launch::deferred, sum(), a, ref(b), cref(c));
+ a = 0;
+ b = 10;
+ c = 100;
+
+ const std::chrono::seconds delay(10);
+ const auto then = std::chrono::system_clock::now() + delay;
VERIFY( f1.valid() );
+ // timed waiting functions should return 'deferred' immediately
+ VERIFY( f1.wait_until(then) == std::future_status::deferred );
+ VERIFY( f1.wait_for(delay) == std::future_status::deferred );
+ VERIFY( std::chrono::system_clock::now() < then );
+
+ f1.wait();
+
+ VERIFY( f1.valid() );
+ // timed waiting functions should return 'ready' immediately
+ VERIFY( f1.wait_until(then) == std::future_status::ready );
+ VERIFY( f1.wait_for(delay) == std::future_status::ready );
+ VERIFY( std::chrono::system_clock::now() < then );
+
VERIFY( f1.get() == 111 );
+ VERIFY( !f1.valid() );
}
int main()