boost_strand.hpp

Created Diff never expires
146 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
380 lines
248 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
478 lines
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>boost/asio/strand.hpp - 1.67.0</title> <link rel="icon" href="/favicon.ico" type="image/ico" />
<title>boost/asio/io_context_strand.hpp - 1.67.0</title> <link rel="icon" href="/favicon.ico" type="image/ico" />
<link rel="stylesheet" type="text/css" href="/style-v2/section-doc.css" />
<link rel="stylesheet" type="text/css" href="/style-v2/section-doc.css" />
<!--[if IE 7]> <style type="text/css"> body { behavior: url(/style-v2/csshover3.htc); } </style> <![endif]-->
<!--[if IE 7]> <style type="text/css"> body { behavior: url(/style-v2/csshover3.htc); } </style> <![endif]-->


</head>
</head>


<body>
<body>
<div id="heading">
<div id="heading">
<div class="heading-inner">
<div class="heading-inner">
<div class="heading-placard"></div>
<div class="heading-placard"></div>


<h1 class="heading-title">
<h1 class="heading-title">
<a href="/">
<a href="/">
<img src="/gfx/space.png" alt= "Boost C++ Libraries" class="heading-logo" />
<img src="/gfx/space.png" alt= "Boost C++ Libraries" class="heading-logo" />
<span class="heading-boost">Boost</span>
<span class="heading-boost">Boost</span>
<span class="heading-cpplibraries">C++ Libraries</span>
<span class="heading-cpplibraries">C++ Libraries</span>
</a></h1>
</a></h1>


<p class="heading-quote">
<p class="heading-quote">
<q>...one of the most highly
<q>...one of the most highly
regarded and expertly designed C++ library projects in the
regarded and expertly designed C++ library projects in the
world.</q> <span class="heading-attribution">&mdash; <a href=
world.</q> <span class="heading-attribution">&mdash; <a href=
"http://www.gotw.ca/" class="external">Herb Sutter</a> and <a href=
"http://www.gotw.ca/" class="external">Herb Sutter</a> and <a href=
"http://en.wikipedia.org/wiki/Andrei_Alexandrescu" class="external">Andrei
"http://en.wikipedia.org/wiki/Andrei_Alexandrescu" class="external">Andrei
Alexandrescu</a>, <a href=
Alexandrescu</a>, <a href=
"http://safari.awprofessional.com/?XmlId=0321113586" class="external">C++
"http://safari.awprofessional.com/?XmlId=0321113586" class="external">C++
Coding Standards</a></span></p>
Coding Standards</a></span></p>
</div>
</div>
</div>
</div>
<div class="boost-common-header-notice"><a class="boost-common-header-inner" href="/doc/libs/release/boost/asio/strand.hpp">This is the documentation for an old version of Boost.
<div class="boost-common-header-notice"><a class="boost-common-header-inner" href="/doc/libs/release/boost/asio/io_context_strand.hpp">This is the documentation for an old version of Boost.
Click here to view this page for the latest version.</a></div>
Click here to view this page for the latest version.</a></div>


<div id="body">
<div id="body">
<div id="body-inner">
<div id="body-inner">
<div id="content">
<div id="content">
<div class="section" id="docs">
<div class="section" id="docs">
<div class="section-0">
<div class="section-0">
<div class="section-body">
<div class="section-body">
<h3>boost/asio/strand.hpp</h3>
<h3>boost/asio/io_context_strand.hpp</h3>
<pre>
<pre>
//
//
// strand.hpp
// io_context_strand.hpp
// ~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~
//
//
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)
// file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)
//
//


#ifndef BOOST_ASIO_STRAND_HPP
#ifndef BOOST_ASIO_IO_CONTEXT_STRAND_HPP
#define BOOST_ASIO_STRAND_HPP
#define BOOST_ASIO_IO_CONTEXT_STRAND_HPP


#if defined(_MSC_VER) &amp;&amp; (_MSC_VER &gt;= 1200)
#if defined(_MSC_VER) &amp;&amp; (_MSC_VER &gt;= 1200)
# pragma once
# pragma once
#endif // defined(_MSC_VER) &amp;&amp; (_MSC_VER &gt;= 1200)
#endif // defined(_MSC_VER) &amp;&amp; (_MSC_VER &gt;= 1200)


#include &lt;<a href="../../boost/asio/detail/config.hpp">boost/asio/detail/config.hpp</a>&gt;
#include &lt;<a href="../../boost/asio/detail/config.hpp">boost/asio/detail/config.hpp</a>&gt;
#include &lt;<a href="../../boost/asio/detail/strand_executor_service.hpp">boost/asio/detail/strand_executor_service.hpp</a>&gt;

#include &lt;<a href="../../boost/asio/detail/type_traits.hpp">boost/asio/detail/type_traits.hpp</a>&gt;
#if !defined(BOOST_ASIO_NO_EXTENSIONS)

#include &lt;<a href="../../boost/asio/async_result.hpp">boost/asio/async_result.hpp</a>&gt;
#include &lt;<a href="../../boost/asio/detail/handler_type_requirements.hpp">boost/asio/detail/handler_type_requirements.hpp</a>&gt;
#include &lt;<a href="../../boost/asio/detail/strand_service.hpp">boost/asio/detail/strand_service.hpp</a>&gt;
#include &lt;<a href="../../boost/asio/detail/wrapped_handler.hpp">boost/asio/detail/wrapped_handler.hpp</a>&gt;
#include &lt;<a href="../../boost/asio/io_context.hpp">boost/asio/io_context.hpp</a>&gt;


#include &lt;<a href="../../boost/asio/detail/push_options.hpp">boost/asio/detail/push_options.hpp</a>&gt;
#include &lt;<a href="../../boost/asio/detail/push_options.hpp">boost/asio/detail/push_options.hpp</a>&gt;


namespace boost {
namespace boost {
namespace asio {
namespace asio {


/// Provides serialised function invocation for any executor type.
/// Provides serialised handler execution.
template &lt;typename Executor&gt;
/**
class strand
* The io_context::strand class provides the ability to post and dispatch
* handlers with the guarantee that none of those handlers will execute
* concurrently.
*
* @par Order of handler invocation
* Given:
*
* @li a strand object @c s
*
* @li an object @c a meeting completion handler requirements
*
* @li an object @c a1 which is an arbitrary copy of @c a made by the
* implementation
*
* @li an object @c b meeting completion handler requirements
*
* @li an object @c b1 which is an arbitrary copy of @c b made by the
* implementation
*
* if any of the following conditions are true:
*
* @li @c s.post(a) happens-before @c s.post(b)
*
* @li @c s.post(a) happens-before @c s.dispatch(b), where the latter is
* performed outside the strand
*
* @li @c s.dispatch(a) happens-before @c s.post(b), where the former is
* performed outside the strand
*
* @li @c s.dispatch(a) happens-before @c s.dispatch(b), where both are
* performed outside the strand
*
* then @c asio_handler_invoke(a1, &amp;a1) happens-before
* @c asio_handler_invoke(b1, &amp;b1).
*
* Note that in the following case:
* @code async_op_1(..., s.wrap(a));
* async_op_2(..., s.wrap(b)); @endcode
* the completion of the first async operation will perform @c s.dispatch(a),
* and the second will perform @c s.dispatch(b), but the order in which those
* are performed is unspecified. That is, you cannot state whether one
* happens-before the other. Therefore none of the above conditions are met and
* no ordering guarantee is made.
*
* @note The implementation makes no guarantee that handlers posted or
* dispatched through different @c strand objects will be invoked concurrently.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Safe.
*
* @par Concepts:
* Dispatcher.
*/
class io_context::strand
{
{
public:
public:
/// The type of the underlying executor.
/// Constructor.
typedef Executor inner_executor_type;

/// Default constructor.
/**
* This constructor is only valid if the underlying executor type is default
* constructible.
*/
strand()
: executor_(),
impl_(use_service&lt;detail::strand_executor_service&gt;(
executor_.context()).create_implementation())
{
}

/// Construct a strand for the specified executor.
explicit strand(const Executor&amp; e)
: executor_(e),
impl_(use_service&lt;detail::strand_executor_service&gt;(
executor_.context()).create_implementation())
{
}

/// Copy constructor.
strand(const strand&amp; other) BOOST_ASIO_NOEXCEPT
: executor_(other.executor_),
impl_(other.impl_)
{
}

/// Converting constructor.
/**
/**
* This constructor is only valid if the @c OtherExecutor type is convertible
* Constructs the strand.
* to @c Executor.
*
* @param io_context The io_context object that the strand will use to
* dispatch handlers that are ready to be run.
*/
*/
template &lt;class OtherExecutor&gt;
explicit strand(boost::asio::io_context&amp; io_context)
strand(
: service_(boost::asio::use_service&lt;
const strand&lt;OtherExecutor&gt;&amp; other) BOOST_ASIO_NOEXCEPT
boost::asio::detail::strand_service&gt;(io_context))
: executor_(other.executor_),
impl_(other.impl_)
{
}

/// Assignment operator.
strand&amp; operator=(const strand&amp; other) BOOST_ASIO_NOEXCEPT
{
{
executor_ = other.executor_;
service_.construct(impl_);
impl_ = other.impl_;
return *this;
}
}


/// Converting assignment operator.
/// Destructor.
/**
/**
* This assignment operator is only valid if the @c OtherExecutor type is
* Destroys a strand.
* convertible to @c Executor.
*
* Handlers posted through the strand that have not yet been invoked will
* still be dispatched in a way that meets the guarantee of non-concurrency.
*/
*/
template &lt;class OtherExecutor&gt;
~strand()
strand&amp; operator=(
const strand&lt;OtherExecutor&gt;&amp; other) BOOST_ASIO_NOEXCEPT
{
executor_ = other.executor_;
impl_ = other.impl_;
return *this;
}

#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move constructor.
strand(strand&amp;&amp; other) BOOST_ASIO_NOEXCEPT
: executor_(BOOST_ASIO_MOVE_CAST(Executor)(other.executor_)),
impl_(BOOST_ASIO_MOVE_CAST(implementation_type)(other.impl_))
{
{
}
}


/// Converting move constructor.
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use context().) Get the io_context associated with the
/// strand.
/**
/**
* This constructor is only valid if the @c OtherExecutor type is convertible
* This function may be used to obtain the io_context object that the strand
* to @c Executor.
* uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_context object that the strand will use to
* dispatch handlers. Ownership is not transferred to the caller.
*/
*/
template &lt;class OtherExecutor&gt;
boost::asio::io_context&amp; get_io_context()
strand(strand&lt;OtherExecutor&gt;&amp;&amp; other) BOOST_ASIO_NOEXCEPT
: executor_(BOOST_ASIO_MOVE_CAST(OtherExecutor)(other)),
impl_(BOOST_ASIO_MOVE_CAST(implementation_type)(other.impl_))
{
}

/// Move assignment operator.
strand&amp; operator=(strand&amp;&amp; other) BOOST_ASIO_NOEXCEPT
{
{
executor_ = BOOST_ASIO_MOVE_CAST(Executor)(other);
return service_.get_io_context();
impl_ = BOOST_ASIO_MOVE_CAST(implementation_type)(other.impl_);
return *this;
}
}


/// Converting move assignment operator.
/// (Deprecated: Use context().) Get the io_context associated with the
/// strand.
/**
/**
* This assignment operator is only valid if the @c OtherExecutor type is
* This function may be used to obtain the io_context object that the strand
* convertible to @c Executor.
* uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_context object that the strand will use to
* dispatch handlers. Ownership is not transferred to the caller.
*/
*/
template &lt;class OtherExecutor&gt;
boost::asio::io_context&amp; get_io_service()
strand&amp; operator=(
const strand&lt;OtherExecutor&gt;&amp;&amp; other) BOOST_ASIO_NOEXCEPT
{
executor_ = BOOST_ASIO_MOVE_CAST(OtherExecutor)(other);
impl_ = BOOST_ASIO_MOVE_CAST(implementation_type)(other.impl_);
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)

/// Destructor.
~strand()
{
}

/// Obtain the underlying executor.
inner_executor_type get_inner_executor() const BOOST_ASIO_NOEXCEPT
{
{
return executor_;
return service_.get_io_context();
}
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)


/// Obtain the underlying execution context.
/// Obtain the underlying execution context.
execution_context&amp; context() const BOOST_ASIO_NOEXCEPT
boost::asio::io_context&amp; context() const BOOST_ASIO_NOEXCEPT
{
{
return executor_.context();
return service_.get_io_context();
}
}


/// Inform the strand that it has some outstanding work to do.
/// Inform the strand that it has some outstanding work to do.
/**
/**
* The strand delegates this call to its underlying executor.
* The strand delegates this call to its underlying io_context.
*/
*/
void on_work_started() const BOOST_ASIO_NOEXCEPT
void on_work_started() const BOOST_ASIO_NOEXCEPT
{
{
executor_.on_work_started();
context().get_executor().on_work_started();
}
}


/// Inform the strand that some work is no longer outstanding.
/// Inform the strand that some work is no longer outstanding.
/**
/**
* The strand delegates this call to its underlying executor.
* The strand delegates this call to its underlying io_context.
*/
*/
void on_work_finished() const BOOST_ASIO_NOEXCEPT
void on_work_finished() const BOOST_ASIO_NOEXCEPT
{
{
executor_.on_work_finished();
context().get_executor().on_work_finished();
}
}


/// Request the strand to invoke the given function object.
/// Request the strand to invoke the given function object.
/**
/**
* This function is used to ask the strand to execute the given function
* This function is used to ask the strand to execute the given function
* object on its underlying executor. The function object will be executed
* object on its underlying io_context. The function object will be executed
* inside this function if the strand is not otherwise busy and if the
* inside this function if the strand is not otherwise busy and if the
* underlying executor's @c dispatch() function is also able to execute the
* underlying io_context's executor's @c dispatch() function is also able to
* function before returning.
* execute the function before returning.
*
*
* @param f The function object to be called. The executor will make
* @param f The function object to be called. The executor will make
* a copy of the handler object as required. The function signature of the
* a copy of the handler object as required. The function signature of the
* function object must be: @code void function(); @endcode
* function object must be: @code void function(); @endcode
*
*
* @param a An allocator that may be used by the executor to allocate the
* @param a An allocator that may be used by the executor to allocate the
* internal storage needed for function invocation.
* internal storage needed for function invocation.
*/
*/
template &lt;typename Function, typename Allocator&gt;
template &lt;typename Function, typename Allocator&gt;
void dispatch(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator&amp; a) const
void dispatch(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator&amp; a) const
{
{
detail::strand_executor_service::dispatch(impl_,
typename decay&lt;Function&gt;::type tmp(BOOST_ASIO_MOVE_CAST(Function)(f));
executor_, BOOST_ASIO_MOVE_CAST(Function)(f), a);
service_.dispatch(impl_, tmp);
(void)a;
}
}


#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use boost::asio::dispatch().) Request the strand to invoke
/// the given handler.
/**
* This function is used to ask the strand to execute the given handler.
*
* The strand object guarantees that handlers posted or dispatched through
* the strand will not be executed concurrently. The handler may be executed
* inside this function if the guarantee can be met. If this function is
* called from within a handler that was posted or dispatched through the same
* strand, then the new handler will be executed immediately.
*
* The strand's guarantee is in addition to the guarantee provided by the
* underlying io_context. The io_context guarantees that the handler will only
* be called in a thread in which the io_context's run member function is
* currently being invoked.
*
* @param handler The handler to be called. The strand will make a copy of the
* handler object as required. The function signature of the handler must be:
* @code void handler(); @endcode
*/
template &lt;typename LegacyCompletionHandler&gt;
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a LegacyCompletionHandler.
BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;

async_completion&lt;LegacyCompletionHandler, void ()&gt; init(handler);

service_.dispatch(impl_, init.completion_handler);

return init.result.get();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)

/// Request the strand to invoke the given function object.
/// Request the strand to invoke the given function object.
/**
/**
* This function is used to ask the executor to execute the given function
* This function is used to ask the executor to execute the given function
* object. The function object will never be executed inside this function.
* object. The function object will never be executed inside this function.
* Instead, it will be scheduled by the underlying executor's defer function.
* Instead, it will be scheduled to run by the underlying io_context.
*
*
* @param f The function object to be called. The executor will make
* @param f The function object to be called. The executor will make
* a copy of the handler object as required. The function signature of the
* a copy of the handler object as required. The function signature of the
* function object must be: @code void function(); @endcode
* function object must be: @code void function(); @endcode
*
*
* @param a An allocator that may be used by the executor to allocate the
* @param a An allocator that may be used by the executor to allocate the
* internal storage needed for function invocation.
* internal storage needed for function invocation.
*/
*/
template &lt;typename Function, typename Allocator&gt;
template &lt;typename Function, typename Allocator&gt;
void post(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator&amp; a) const
void post(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator&amp; a) const
{
{
detail::strand_executor_service::post(impl_,
typename decay&lt;Function&gt;::type tmp(BOOST_ASIO_MOVE_CAST(Function)(f));
executor_, BOOST_ASIO_MOVE_CAST(Function)(f), a);
service_.post(impl_, tmp);
(void)a;
}
}


#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use boost::asio::post().) Request the strand to invoke the
/// given handler and return immediately.
/**
* This function is used to ask the strand to execute the given handler, but
* without allowing the strand to call the handler from inside this function.
*
* The strand object guarantees that handlers posted or dispatched through
* the strand will not be executed concurrently. The strand's guarantee is in
* addition to the guarantee provided by the underlying io_context. The
* io_context guarantees that the handler will only be called in a thread in
* which the io_context's run member function is currently being invoked.
*
* @param handler The handler to be called. The strand will make a copy of the
* handler object as required. The function signature of the handler must be:
* @code void handler(); @endcode
*/
template &lt;typename LegacyCompletionHandler&gt;
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a LegacyCompletionHandler.
BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;

async_completion&lt;LegacyCompletionHandler, void ()&gt; init(handler);

service_.post(impl_, init.completion_handler);

return init.result.get();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)

/// Request the strand to invoke the given function object.
/// Request the strand to invoke the given function object.
/**
/**
* This function is used to ask the executor to execute the given function
* This function is used to ask the executor to execute the given function
* object. The function object will never be executed inside this function.
* object. The function object will never be executed inside this function.
* Instead, it will be scheduled by the underlying executor's defer function.
* Instead, it will be scheduled to run by the underlying io_context.
*
*
* @param f The function object to be called. The executor will make
* @param f The function object to be called. The executor will make
* a copy of the handler object as required. The function signature of the
* a copy of the handler object as required. The function signature of the
* function object must be: @code void function(); @endcode
* function object must be: @code void function(); @endcode
*
*
* @param a An allocator that may be used by the executor to allocate the
* @param a An allocator that may be used by the executor to allocate the
* internal storage needed for function invocation.
* internal storage needed for function invocation.
*/
*/
template &lt;typename Function, typename Allocator&gt;
template &lt;typename Function, typename Allocator&gt;
void defer(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator&amp; a) const
void defer(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator&amp; a) const
{
{
detail::strand_executor_service::defer(impl_,
typename decay&lt;Function&gt;::type tmp(BOOST_ASIO_MOVE_CAST(Function)(f));
executor_, BOOST_ASIO_MOVE_CAST(Function)(f), a);
service_.post(impl_, tmp);
(void)a;
}
}


#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use boost::asio::bind_executor().) Create a new handler that
/// automatically dispatches the wrapped handler on the strand.
/**
* This function is used to create a new handler function object that, when
* invoked, will automatically pass the wrapped handler to the strand's
* dispatch function.
*
* @param handler The handler to be wrapped. The strand will make a copy of
* the handler object as required. The function signature of the handler must
* be: @code void handler(A1 a1, ... An an); @endcode
*
* @return A function object that, when invoked, passes the wrapped handler to
* the strand's dispatch function. Given a function object with the signature:
* @code R f(A1 a1, ... An an); @endcode
* If this function object is passed to the wrap function like so:
* @code strand.wrap(f); @endcode
* then the return value is a function object with the signature
* @code void g(A1 a1, ... An an); @endcode
* that, when invoked, executes code equivalent to:
* @code strand.dispatch(boost::bind(f, a1, ... an)); @endcode
*/
template &lt;typename Handler&gt;
#if defined(GENERATING_DOCUMENTATION)
unspecified
#else
detail::wrapped_handler&lt;strand, Handler, detail::is_continuation_if_running&gt;
#endif
wrap(Handler handler)
{
return detail::wrapped_handler&lt;io_context::strand, Handler,
detail::is_continuation_if_running&gt;(*this, handler);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)

/// Determine whether the strand is running in the current thread.
/// Determine whether the strand is running in the current thread.
/**
/**
* @return @c true if the current thread is executing a function that was
* @return @c true if the current thread is executing a handler that was
* submitted to the strand using post(), dispatch() or defer(). Otherwise
* submitted to the strand using post(), dispatch() or wrap(). Otherwise
* returns @c false.
* returns @c false.
*/
*/
bool running_in_this_thread() const BOOST_ASIO_NOEXCEPT
bool running_in_this_thread() const BOOST_ASIO_NOEXCEPT
{
{
return detail::strand_executor_service::running_in_this_thread(impl_);
return service_.running_in_this_thread(impl_);
}
}


/// Compare two strands for equality.
/// Compare two strands for equality.
/**
/**
* Two strands are equal if they refer to the same ordered, non-concurrent
* Two strands are equal if they refer to the same ordered, non-concurrent
* state.
* state.
*/
*/
friend bool operator==(const strand&amp; a, const strand&amp; b) BOOST_ASIO_NOEXCEPT
friend bool operator==(const strand&amp; a, const strand&amp; b) BOOST_ASIO_NOEXCEPT
{
{
return a.impl_ == b.impl_;
return a.impl_ == b.impl_;
}
}


/// Compare two strands for inequality.
/// Compare two strands for inequality.
/**
/**
* Two strands are equal if they refer to the same ordered, non-concurrent
* Two strands are equal if they refer to the same ordered, non-concurrent
* state.
* state.
*/
*/
friend bool operator!=(const strand&amp; a, const strand&amp; b) BOOST_ASIO_NOEXCEPT
friend bool operator!=(const strand&amp; a, const strand&amp; b) BOOST_ASIO_NOEXCEPT
{
{
return a.impl_ != b.impl_;
return a.impl_ != b.impl_;
}
}


private:
private:
Executor executor_;
boost::asio::detail::strand_service&amp; service_;
typedef detail::strand_executor_service::implementation_type
mutable boost::asio::detail::strand_service::implementation_type impl_;
implementation_type;
implementation_type impl_;
};
};


} // namespace asio
} // namespace asio
} // namespace boost
} // namespace boost


#include &lt;<a href="../../boost/asio/detail/pop_options.hpp">boost/asio/detail/pop_options.hpp</a>&gt;
#include &lt;<a href="../../boost/asio/detail/pop_options.hpp">boost/asio/detail/pop_options.hpp</a>&gt;


// If both io_context.hpp and strand.hpp have been included, automatically
// include the header file needed for the io_context::strand class.
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
# if defined(BOOST_ASIO_IO_CONTEXT_HPP)
# include &lt;<a href="../../boost/asio/io_context_strand.hpp">boost/asio/io_context_strand.hpp</a>&gt;
# endif // defined(BOOST_ASIO_IO_CONTEXT_HPP)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)


#endif // BOOST_ASIO_STRAND_HPP
#endif // BOOST_ASIO_IO_CONTEXT_STRAND_HPP
</pre>
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>


<div class="clear"></div>
<div class="clear"></div>
</div>
</div>
</div>
</div>


<div id="footer">
<div id="footer">
<div id="footer-left">
<div id="footer-left">
<div id="revised">
<div id="revised">
<p>Revised $Date$</p>
<p>Revised $Date$</p>
</div>
</div>


<div id="copyright">
<div id="copyright">
<p>Copyright Beman Dawes, David Abrahams, 1998-2005.</p>
<p>Copyright Beman Dawes, David Abrahams, 1998-2005.</p>


<p>Copyright Rene Rivera 2004-2008.</p>
<p>Copyright Rene Rivera 2004-2008.</p>
</div> <div id="license">
</div> <div id="license">
<p>Distributed under the <a href="/LICENSE_1_0.txt" class=
<p>Distributed under the <a href="/LICENSE_1_0.txt" class=
"internal">Boost Software License, Version 1.0</a>.</p>
"internal">Boost Software License, Version 1.0</a>.</p>
</div>
</div>
</div>
</div>


<div id="footer-right">
<div id="footer-right">
<div id="banners">
<div id="banners">
<p id="banner-xhtml"><a href="https://validator.w3.org/check?uri=referer"
<p id="banner-xhtml"><a href="https://validator.w3.org/check?uri=referer"
class="external">XHTML 1.0</a></p>
class="external">XHTML 1.0</a></p>


<p id="banner-css"><a href=
<p id="banner-css"><a href=
"https://jigsaw.w3.org/css-validator/check/referer" class=
"https://jigsaw.w3.org/css-validator/check/referer" class=
"external">CSS</a></p>
"external">CSS</a></p>


<p id="banner-osi"><a href=
<p id="banner-osi"><a href=
"https://opensource.org/docs/definition.php" class="external">OSI
"https://opensource.org/docs/definition.php" class="external">OSI
Certified</a></p>
Certified</a></p>
</div>
</div>
</div>
</div>


<div class="clear"></div>
<div class="clear"></div>
</div>
</div>
</body>
</body>
</html>
</html>