Prevent blocking.always from being used with strand<>.
Previously, calling `require(E, blocking.always)` on a strand E compiled but produced incorrect behaviour. Now, `require(E, blocking.always)` will no longer compile. Furthermore, when used with an always-blocking inner executor, the strand will report its blocking property as blocking.possibly.
This commit is contained in:
parent
69f98d2cde
commit
ef0c424b00
@ -18,6 +18,7 @@
|
||||
#include "asio/detail/config.hpp"
|
||||
#include "asio/detail/strand_executor_service.hpp"
|
||||
#include "asio/detail/type_traits.hpp"
|
||||
#include "asio/execution/blocking.hpp"
|
||||
#include "asio/execution/executor.hpp"
|
||||
#include "asio/is_executor.hpp"
|
||||
|
||||
@ -157,7 +158,7 @@ public:
|
||||
/// Forward a query to the underlying executor.
|
||||
/**
|
||||
* Do not call this function directly. It is intended for use with the
|
||||
* execution::execute customisation point.
|
||||
* asio::query customisation point.
|
||||
*
|
||||
* For example:
|
||||
* @code asio::strand<my_executor_type> ex = ...;
|
||||
@ -168,12 +169,17 @@ public:
|
||||
template <typename Property>
|
||||
typename constraint<
|
||||
can_query<const Executor&, Property>::value,
|
||||
typename query_result<const Executor&, Property>::type
|
||||
typename conditional<
|
||||
is_convertible<Property, execution::blocking_t>::value,
|
||||
execution::blocking_t,
|
||||
typename query_result<const Executor&, Property>::type
|
||||
>::type
|
||||
>::type query(const Property& p) const
|
||||
ASIO_NOEXCEPT_IF((
|
||||
is_nothrow_query<const Executor&, Property>::value))
|
||||
{
|
||||
return asio::query(executor_, p);
|
||||
return this->query_helper(
|
||||
is_convertible<Property, execution::blocking_t>(), p);
|
||||
}
|
||||
|
||||
/// Forward a requirement to the underlying executor.
|
||||
@ -188,7 +194,8 @@ public:
|
||||
*/
|
||||
template <typename Property>
|
||||
typename constraint<
|
||||
can_require<const Executor&, Property>::value,
|
||||
can_require<const Executor&, Property>::value
|
||||
&& !is_convertible<Property, execution::blocking_t::always_t>::value,
|
||||
strand<typename decay<
|
||||
typename require_result<const Executor&, Property>::type
|
||||
>::type>
|
||||
@ -213,7 +220,8 @@ public:
|
||||
*/
|
||||
template <typename Property>
|
||||
typename constraint<
|
||||
can_prefer<const Executor&, Property>::value,
|
||||
can_prefer<const Executor&, Property>::value
|
||||
&& !is_convertible<Property, execution::blocking_t::always_t>::value,
|
||||
strand<typename decay<
|
||||
typename prefer_result<const Executor&, Property>::type
|
||||
>::type>
|
||||
@ -406,6 +414,21 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Property>
|
||||
typename query_result<const Executor&, Property>::type query_helper(
|
||||
false_type, const Property& property) const
|
||||
{
|
||||
return asio::query(executor_, property);
|
||||
}
|
||||
|
||||
template <typename Property>
|
||||
execution::blocking_t query_helper(true_type, const Property& property) const
|
||||
{
|
||||
execution::blocking_t result = asio::query(executor_, property);
|
||||
return result == execution::blocking.always
|
||||
? execution::blocking.possibly : result;
|
||||
}
|
||||
|
||||
Executor executor_;
|
||||
implementation_type impl_;
|
||||
};
|
||||
@ -481,7 +504,10 @@ struct query_member<strand<Executor>, Property,
|
||||
ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
|
||||
ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
|
||||
(is_nothrow_query<Executor, Property>::value));
|
||||
typedef typename query_result<Executor, Property>::type result_type;
|
||||
typedef typename conditional<
|
||||
is_convertible<Property, execution::blocking_t>::value,
|
||||
execution::blocking_t, typename query_result<Executor, Property>::type
|
||||
>::type result_type;
|
||||
};
|
||||
|
||||
#endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
|
||||
@ -492,6 +518,7 @@ template <typename Executor, typename Property>
|
||||
struct require_member<strand<Executor>, Property,
|
||||
typename enable_if<
|
||||
can_require<const Executor&, Property>::value
|
||||
&& !is_convertible<Property, execution::blocking_t::always_t>::value
|
||||
>::type>
|
||||
{
|
||||
ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
|
||||
@ -510,6 +537,7 @@ template <typename Executor, typename Property>
|
||||
struct prefer_member<strand<Executor>, Property,
|
||||
typename enable_if<
|
||||
can_prefer<const Executor&, Property>::value
|
||||
&& !is_convertible<Property, execution::blocking_t::always_t>::value
|
||||
>::type>
|
||||
{
|
||||
ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
|
||||
|
Loading…
Reference in New Issue
Block a user