Initial implementation of move support for posix descriptors.
This commit is contained in:
parent
f52dddfd5c
commit
d5b1a7308f
@ -16,17 +16,39 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/io_service.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
#if defined(ASIO_HAS_MOVE)
|
||||
namespace detail
|
||||
{
|
||||
// Type trait used to determine whether a service supports move.
|
||||
template <typename IoObjectService>
|
||||
class service_has_move
|
||||
{
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(service_has_move::eval(static_cast<IoObjectService*>(0))) == 1;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static auto eval(T*) -> decltype(&T::move_construct, char(0));
|
||||
static char (&eval(...))[2];
|
||||
};
|
||||
}
|
||||
#endif // defined(ASIO_HAS_MOVE)
|
||||
|
||||
/// Base class for all I/O objects.
|
||||
#if !defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
template <typename IoObjectService>
|
||||
#else
|
||||
template <typename IoObjectService,
|
||||
bool Movable = detail::service_has_move<IoObjectService>::value>
|
||||
#endif
|
||||
class basic_io_object
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
/// The type of the service that will be used to provide I/O operations.
|
||||
@ -52,7 +74,7 @@ protected:
|
||||
/// Construct a basic_io_object.
|
||||
/**
|
||||
* Performs:
|
||||
* @code service.construct(implementation); @endcode
|
||||
* @code get_service().construct(get_implementation()); @endcode
|
||||
*/
|
||||
explicit basic_io_object(asio::io_service& io_service)
|
||||
: service(asio::use_service<IoObjectService>(io_service))
|
||||
@ -60,23 +82,154 @@ protected:
|
||||
service.construct(implementation);
|
||||
}
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a basic_io_object.
|
||||
/**
|
||||
* Performs:
|
||||
* @code get_service().move_construct(
|
||||
* get_implementation(), other.get_implementation()); @endcode
|
||||
*
|
||||
* @note Available only for services that support movability,
|
||||
*/
|
||||
basic_io_object(basic_io_object&& other);
|
||||
|
||||
/// Move-assign a basic_io_object.
|
||||
/**
|
||||
* Performs:
|
||||
* @code get_service().move_assign(get_implementation(),
|
||||
* other.get_service(), other.get_implementation()); @endcode
|
||||
*
|
||||
* @note Available only for services that support movability,
|
||||
*/
|
||||
basic_io_object& operator=(basic_io_object&& other);
|
||||
|
||||
/// Copy construction is not supported.
|
||||
basic_io_object(const basic_io_object&) = delete;
|
||||
|
||||
/// Copy assignment is not supported.
|
||||
basic_io_object& operator=(const basic_io_object&) = delete;
|
||||
#endif // defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Protected destructor to prevent deletion through this type.
|
||||
/**
|
||||
* Performs:
|
||||
* @code service.destroy(implementation); @endcode
|
||||
* @code get_service().destroy(get_implementation()); @endcode
|
||||
*/
|
||||
~basic_io_object()
|
||||
{
|
||||
service.destroy(implementation);
|
||||
}
|
||||
|
||||
/// The service associated with the I/O object.
|
||||
/// Get the service associated with the I/O object.
|
||||
service_type& get_service()
|
||||
{
|
||||
return service;
|
||||
}
|
||||
|
||||
/// Get the service associated with the I/O object.
|
||||
const service_type& get_service() const
|
||||
{
|
||||
return service;
|
||||
}
|
||||
|
||||
/// (Deprecated: Use get_service().) The service associated with the I/O
|
||||
/// object.
|
||||
/**
|
||||
* @note Available only for services that do not support movability.
|
||||
*/
|
||||
service_type& service;
|
||||
|
||||
/// The underlying implementation of the I/O object.
|
||||
/// Get the underlying implementation of the I/O object.
|
||||
implementation_type& get_implementation()
|
||||
{
|
||||
return implementation;
|
||||
}
|
||||
|
||||
/// Get the underlying implementation of the I/O object.
|
||||
const implementation_type& get_implementation() const
|
||||
{
|
||||
return implementation;
|
||||
}
|
||||
|
||||
/// (Deprecated: Use get_implementation().) The underlying implementation of
|
||||
/// the I/O object.
|
||||
implementation_type implementation;
|
||||
|
||||
private:
|
||||
basic_io_object(const basic_io_object&);
|
||||
basic_io_object& operator=(const basic_io_object&);
|
||||
};
|
||||
|
||||
#if defined(ASIO_HAS_MOVE)
|
||||
// Specialisation for movable objects.
|
||||
template <typename IoObjectService>
|
||||
class basic_io_object<IoObjectService, true>
|
||||
{
|
||||
public:
|
||||
typedef IoObjectService service_type;
|
||||
typedef typename service_type::implementation_type implementation_type;
|
||||
|
||||
asio::io_service& get_io_service()
|
||||
{
|
||||
return service_->get_io_service();
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit basic_io_object(asio::io_service& io_service)
|
||||
: service_(&asio::use_service<IoObjectService>(io_service))
|
||||
{
|
||||
service_->construct(implementation);
|
||||
}
|
||||
|
||||
basic_io_object(basic_io_object&& other)
|
||||
: service_(&other.get_service())
|
||||
{
|
||||
service_->move_construct(implementation, other.implementation);
|
||||
}
|
||||
|
||||
~basic_io_object()
|
||||
{
|
||||
service_->destroy(implementation);
|
||||
}
|
||||
|
||||
basic_io_object& operator=(basic_io_object&& other)
|
||||
{
|
||||
service_->move_assign(implementation,
|
||||
*other.service_, other.implementation);
|
||||
service_ = other.service_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
service_type& get_service()
|
||||
{
|
||||
return *service_;
|
||||
}
|
||||
|
||||
const service_type& get_service() const
|
||||
{
|
||||
return *service_;
|
||||
}
|
||||
|
||||
implementation_type& get_implementation()
|
||||
{
|
||||
return implementation;
|
||||
}
|
||||
|
||||
const implementation_type& get_implementation() const
|
||||
{
|
||||
return implementation;
|
||||
}
|
||||
|
||||
implementation_type implementation;
|
||||
|
||||
private:
|
||||
basic_io_object(const basic_io_object&);
|
||||
void operator=(const basic_io_object&);
|
||||
|
||||
IoObjectService* service_;
|
||||
};
|
||||
#endif // defined(ASIO_HAS_MOVE)
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
@ -46,7 +46,7 @@
|
||||
# define ASIO_DECL
|
||||
#endif // !defined(ASIO_DECL)
|
||||
|
||||
// Support move construction on compilers known to allow it.
|
||||
// Support move construction as an optimisation on compilers known to allow it.
|
||||
#if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
@ -65,6 +65,22 @@
|
||||
# define ASIO_MOVE_CAST(type) static_cast<const type&>
|
||||
#endif // !defined_ASIO_MOVE_CAST
|
||||
|
||||
// Move construction and assignment in the API.
|
||||
#if !defined(ASIO_DISABLE_MOVE)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define ASIO_HAS_MOVE
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_MSVC)
|
||||
# if (_MSC_VER >= 1600)
|
||||
# define ASIO_HAS_MOVE
|
||||
# endif // (_MSC_VER >= 1600)
|
||||
# endif // defined(BOOST_MSVC)
|
||||
#endif // !defined(ASIO_DISABLE_MOVE)
|
||||
|
||||
// Standard library support for system errors.
|
||||
#if !defined(ASIO_DISABLE_STD_SYSTEM_ERROR)
|
||||
# if defined(__GNUC__)
|
||||
|
@ -88,6 +88,11 @@ public:
|
||||
int op_type, socket_type descriptor,
|
||||
per_descriptor_data& descriptor_data, reactor_op* op);
|
||||
|
||||
// Move descriptor registration from one descriptor_data object to another.
|
||||
ASIO_DECL void move_descriptor(socket_type descriptor,
|
||||
per_descriptor_data& target_descriptor_data,
|
||||
per_descriptor_data& source_descriptor_data);
|
||||
|
||||
// Post a reactor operation for immediate completion.
|
||||
void post_immediate_completion(reactor_op* op)
|
||||
{
|
||||
|
@ -186,6 +186,14 @@ int epoll_reactor::register_internal_descriptor(
|
||||
return 0;
|
||||
}
|
||||
|
||||
void epoll_reactor::move_descriptor(socket_type,
|
||||
epoll_reactor::per_descriptor_data& target_descriptor_data,
|
||||
epoll_reactor::per_descriptor_data& source_descriptor_data)
|
||||
{
|
||||
target_descriptor_data = source_descriptor_data;
|
||||
source_descriptor_data = 0;
|
||||
}
|
||||
|
||||
void epoll_reactor::start_op(int op_type, socket_type descriptor,
|
||||
epoll_reactor::per_descriptor_data& descriptor_data,
|
||||
reactor_op* op, bool allow_speculative)
|
||||
|
@ -45,6 +45,37 @@ void reactive_descriptor_service::construct(
|
||||
impl.state_ = 0;
|
||||
}
|
||||
|
||||
void reactive_descriptor_service::move_construct(
|
||||
reactive_descriptor_service::implementation_type& impl,
|
||||
reactive_descriptor_service::implementation_type& other_impl)
|
||||
{
|
||||
impl.descriptor_ = other_impl.descriptor_;
|
||||
other_impl.descriptor_ = -1;
|
||||
|
||||
impl.state_ = other_impl.state_;
|
||||
other_impl.state_ = 0;
|
||||
|
||||
reactor_.move_descriptor(impl.descriptor_,
|
||||
impl.reactor_data_, other_impl.reactor_data_);
|
||||
}
|
||||
|
||||
void reactive_descriptor_service::move_assign(
|
||||
reactive_descriptor_service::implementation_type& impl,
|
||||
reactive_descriptor_service& other_service,
|
||||
reactive_descriptor_service::implementation_type& other_impl)
|
||||
{
|
||||
destroy(impl);
|
||||
|
||||
impl.descriptor_ = other_impl.descriptor_;
|
||||
other_impl.descriptor_ = -1;
|
||||
|
||||
impl.state_ = other_impl.state_;
|
||||
other_impl.state_ = 0;
|
||||
|
||||
other_service.reactor_.move_descriptor(impl.descriptor_,
|
||||
impl.reactor_data_, other_impl.reactor_data_);
|
||||
}
|
||||
|
||||
void reactive_descriptor_service::destroy(
|
||||
reactive_descriptor_service::implementation_type& impl)
|
||||
{
|
||||
|
@ -79,6 +79,15 @@ public:
|
||||
// Construct a new descriptor implementation.
|
||||
ASIO_DECL void construct(implementation_type& impl);
|
||||
|
||||
// Move-construct a new descriptor implementation.
|
||||
ASIO_DECL void move_construct(implementation_type& impl,
|
||||
implementation_type& other_impl);
|
||||
|
||||
// Move-assign from another descriptor implementation.
|
||||
ASIO_DECL void move_assign(implementation_type& impl,
|
||||
reactive_descriptor_service& other_service,
|
||||
implementation_type& other_impl);
|
||||
|
||||
// Destroy a descriptor implementation.
|
||||
ASIO_DECL void destroy(implementation_type& impl);
|
||||
|
||||
|
@ -86,10 +86,48 @@ public:
|
||||
: basic_io_object<DescriptorService>(io_service)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.assign(this->implementation, native_descriptor, ec);
|
||||
this->get_service().assign(this->get_implementation(),
|
||||
native_descriptor, ec);
|
||||
asio::detail::throw_error(ec, "assign");
|
||||
}
|
||||
|
||||
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a basic_descriptor from another.
|
||||
/**
|
||||
* This constructor moves a stream descriptor from one object to another.
|
||||
*
|
||||
* @param other The other basic_descriptor object from which the move will
|
||||
* occur.
|
||||
*
|
||||
* @note Following the move, the valid operations for the other object are:
|
||||
* @li Using it as the target of a move assignment.
|
||||
* @li Destruction.
|
||||
*/
|
||||
basic_descriptor(basic_descriptor&& other)
|
||||
: basic_io_object<DescriptorService>(
|
||||
ASIO_MOVE_CAST(basic_descriptor)(other))
|
||||
{
|
||||
}
|
||||
|
||||
/// Move-assign a basic_descriptor from another.
|
||||
/**
|
||||
* This constructor moves a descriptor from one object to another.
|
||||
*
|
||||
* @param other The other basic_descriptor object from which the move will
|
||||
* occur.
|
||||
*
|
||||
* @note Following the move, the valid operations for the other object are:
|
||||
* @li Using it as the target of a move assignment.
|
||||
* @li Destruction.
|
||||
*/
|
||||
basic_descriptor& operator=(basic_descriptor&& other)
|
||||
{
|
||||
basic_io_object<DescriptorService>::operator=(
|
||||
ASIO_MOVE_CAST(basic_descriptor)(other));
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Get a reference to the lowest layer.
|
||||
/**
|
||||
* This function returns a reference to the lowest layer in a stack of
|
||||
@ -129,7 +167,8 @@ public:
|
||||
void assign(const native_handle_type& native_descriptor)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.assign(this->implementation, native_descriptor, ec);
|
||||
this->get_service().assign(this->get_implementation(),
|
||||
native_descriptor, ec);
|
||||
asio::detail::throw_error(ec, "assign");
|
||||
}
|
||||
|
||||
@ -144,13 +183,14 @@ public:
|
||||
asio::error_code assign(const native_handle_type& native_descriptor,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.assign(this->implementation, native_descriptor, ec);
|
||||
return this->get_service().assign(
|
||||
this->get_implementation(), native_descriptor, ec);
|
||||
}
|
||||
|
||||
/// Determine whether the descriptor is open.
|
||||
bool is_open() const
|
||||
{
|
||||
return this->service.is_open(this->implementation);
|
||||
return this->get_service().is_open(this->implementation);
|
||||
}
|
||||
|
||||
/// Close the descriptor.
|
||||
@ -165,7 +205,7 @@ public:
|
||||
void close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.close(this->implementation, ec);
|
||||
this->get_service().close(this->get_implementation(), ec);
|
||||
asio::detail::throw_error(ec, "close");
|
||||
}
|
||||
|
||||
@ -180,7 +220,7 @@ public:
|
||||
*/
|
||||
asio::error_code close(asio::error_code& ec)
|
||||
{
|
||||
return this->service.close(this->implementation, ec);
|
||||
return this->get_service().close(this->get_implementation(), ec);
|
||||
}
|
||||
|
||||
/// (Deprecated: Use native_handle().) Get the native descriptor
|
||||
@ -192,7 +232,7 @@ public:
|
||||
*/
|
||||
native_type native()
|
||||
{
|
||||
return this->service.native_handle(this->implementation);
|
||||
return this->get_service().native_handle(this->implementation);
|
||||
}
|
||||
|
||||
/// Get the native descriptor representation.
|
||||
@ -203,7 +243,7 @@ public:
|
||||
*/
|
||||
native_handle_type native_handle()
|
||||
{
|
||||
return this->service.native_handle(this->implementation);
|
||||
return this->get_service().native_handle(this->implementation);
|
||||
}
|
||||
|
||||
/// Release ownership of the native descriptor implementation.
|
||||
@ -218,7 +258,7 @@ public:
|
||||
*/
|
||||
native_handle_type release()
|
||||
{
|
||||
return this->service.release(this->implementation);
|
||||
return this->get_service().release(this->implementation);
|
||||
}
|
||||
|
||||
/// Cancel all asynchronous operations associated with the descriptor.
|
||||
@ -232,7 +272,7 @@ public:
|
||||
void cancel()
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.cancel(this->implementation, ec);
|
||||
this->get_service().cancel(this->get_implementation(), ec);
|
||||
asio::detail::throw_error(ec, "cancel");
|
||||
}
|
||||
|
||||
@ -246,7 +286,7 @@ public:
|
||||
*/
|
||||
asio::error_code cancel(asio::error_code& ec)
|
||||
{
|
||||
return this->service.cancel(this->implementation, ec);
|
||||
return this->get_service().cancel(this->get_implementation(), ec);
|
||||
}
|
||||
|
||||
/// Perform an IO control command on the descriptor.
|
||||
@ -275,7 +315,7 @@ public:
|
||||
void io_control(IoControlCommand& command)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.io_control(this->implementation, command, ec);
|
||||
this->get_service().io_control(this->get_implementation(), command, ec);
|
||||
asio::detail::throw_error(ec, "io_control");
|
||||
}
|
||||
|
||||
@ -310,7 +350,8 @@ public:
|
||||
asio::error_code io_control(IoControlCommand& command,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.io_control(this->implementation, command, ec);
|
||||
return this->get_service().io_control(
|
||||
this->get_implementation(), command, ec);
|
||||
}
|
||||
|
||||
/// Gets the non-blocking mode of the descriptor.
|
||||
@ -326,7 +367,7 @@ public:
|
||||
*/
|
||||
bool non_blocking() const
|
||||
{
|
||||
return this->service.non_blocking(this->implementation);
|
||||
return this->get_service().non_blocking(this->implementation);
|
||||
}
|
||||
|
||||
/// Sets the non-blocking mode of the descriptor.
|
||||
@ -345,7 +386,7 @@ public:
|
||||
void non_blocking(bool mode)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.non_blocking(this->implementation, mode, ec);
|
||||
this->get_service().non_blocking(this->get_implementation(), mode, ec);
|
||||
asio::detail::throw_error(ec, "non_blocking");
|
||||
}
|
||||
|
||||
@ -365,7 +406,8 @@ public:
|
||||
asio::error_code non_blocking(
|
||||
bool mode, asio::error_code& ec)
|
||||
{
|
||||
return this->service.non_blocking(this->implementation, mode, ec);
|
||||
return this->get_service().non_blocking(
|
||||
this->get_implementation(), mode, ec);
|
||||
}
|
||||
|
||||
/// Gets the non-blocking mode of the native descriptor implementation.
|
||||
@ -384,7 +426,7 @@ public:
|
||||
*/
|
||||
bool native_non_blocking() const
|
||||
{
|
||||
return this->service.native_non_blocking(this->implementation);
|
||||
return this->get_service().native_non_blocking(this->implementation);
|
||||
}
|
||||
|
||||
/// Sets the non-blocking mode of the native descriptor implementation.
|
||||
@ -405,7 +447,8 @@ public:
|
||||
void native_non_blocking(bool mode)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.native_non_blocking(this->implementation, mode, ec);
|
||||
this->get_service().native_non_blocking(
|
||||
this->get_implementation(), mode, ec);
|
||||
asio::detail::throw_error(ec, "native_non_blocking");
|
||||
}
|
||||
|
||||
@ -427,7 +470,8 @@ public:
|
||||
asio::error_code native_non_blocking(
|
||||
bool mode, asio::error_code& ec)
|
||||
{
|
||||
return this->service.native_non_blocking(this->implementation, mode, ec);
|
||||
return this->get_service().native_non_blocking(
|
||||
this->get_implementation(), mode, ec);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -91,6 +91,43 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a basic_stream_descriptor from another.
|
||||
/**
|
||||
* This constructor moves a stream descriptor from one object to another.
|
||||
*
|
||||
* @param other The other basic_stream_descriptor object from which the move
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the valid operations for the other object are:
|
||||
* @li Using it as the target of a move assignment.
|
||||
* @li Destruction.
|
||||
*/
|
||||
basic_stream_descriptor(basic_stream_descriptor&& other)
|
||||
: basic_descriptor<StreamDescriptorService>(
|
||||
ASIO_MOVE_CAST(basic_stream_descriptor)(other))
|
||||
{
|
||||
}
|
||||
|
||||
/// Move-assign a basic_descriptor from another.
|
||||
/**
|
||||
* This constructor moves a stream descriptor from one object to another.
|
||||
*
|
||||
* @param other The other basic_stream_descriptor object from which the move
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the valid operations for the other object are:
|
||||
* @li Using it as the target of a move assignment.
|
||||
* @li Destruction.
|
||||
*/
|
||||
basic_stream_descriptor& operator=(basic_stream_descriptor&& other)
|
||||
{
|
||||
basic_descriptor<StreamDescriptorService>::operator=(
|
||||
ASIO_MOVE_CAST(basic_stream_descriptor)(other));
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Write some data to the descriptor.
|
||||
/**
|
||||
* This function is used to write data to the stream descriptor. The function
|
||||
@ -122,7 +159,8 @@ public:
|
||||
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.write_some(this->implementation, buffers, ec);
|
||||
std::size_t s = this->get_service().write_some(
|
||||
this->get_implementation(), buffers, ec);
|
||||
asio::detail::throw_error(ec, "write_some");
|
||||
return s;
|
||||
}
|
||||
@ -147,7 +185,8 @@ public:
|
||||
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.write_some(this->implementation, buffers, ec);
|
||||
return this->get_service().write_some(
|
||||
this->get_implementation(), buffers, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous write.
|
||||
@ -193,8 +232,8 @@ public:
|
||||
// not meet the documented type requirements for a WriteHandler.
|
||||
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
|
||||
|
||||
this->service.async_write_some(this->implementation, buffers,
|
||||
ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
this->get_service().async_write_some(this->get_implementation(),
|
||||
buffers, ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
}
|
||||
|
||||
/// Read some data from the descriptor.
|
||||
@ -229,7 +268,8 @@ public:
|
||||
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.read_some(this->implementation, buffers, ec);
|
||||
std::size_t s = this->get_service().read_some(
|
||||
this->get_implementation(), buffers, ec);
|
||||
asio::detail::throw_error(ec, "read_some");
|
||||
return s;
|
||||
}
|
||||
@ -255,7 +295,8 @@ public:
|
||||
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.read_some(this->implementation, buffers, ec);
|
||||
return this->get_service().read_some(
|
||||
this->get_implementation(), buffers, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous read.
|
||||
@ -302,8 +343,8 @@ public:
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
this->service.async_read_some(this->implementation, buffers,
|
||||
ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
this->get_service().async_read_some(this->get_implementation(),
|
||||
buffers, ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -83,6 +83,23 @@ public:
|
||||
service_impl_.construct(impl);
|
||||
}
|
||||
|
||||
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a new stream descriptor implementation.
|
||||
void move_construct(implementation_type& impl,
|
||||
implementation_type& other_impl)
|
||||
{
|
||||
service_impl_.move_construct(impl, other_impl);
|
||||
}
|
||||
|
||||
/// Move-assign from another stream descriptor implementation.
|
||||
void move_assign(implementation_type& impl,
|
||||
stream_descriptor_service& other_service,
|
||||
implementation_type& other_impl)
|
||||
{
|
||||
service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
|
||||
}
|
||||
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destroy a stream descriptor implementation.
|
||||
void destroy(implementation_type& impl)
|
||||
{
|
||||
|
@ -57,6 +57,18 @@ void test()
|
||||
int native_descriptor1 = -1;
|
||||
posix::stream_descriptor descriptor2(ios, native_descriptor1);
|
||||
|
||||
#if defined(ASIO_HAS_MOVE)
|
||||
posix::stream_descriptor descriptor3(posix_stream_descriptor(ios));
|
||||
posix::stream_descriptor descriptor4(std::move(descriptor3));
|
||||
#endif // defined(ASIO_HAS_MOVE)
|
||||
|
||||
// basic_stream_descriptor operators.
|
||||
|
||||
#if defined(ASIO_HAS_MOVE)
|
||||
descriptor3 = posix_stream_descriptor(ios);
|
||||
descriptor4 = std::move(descriptor3);
|
||||
#endif // defined(ASIO_HAS_MOVE)
|
||||
|
||||
// basic_io_object functions.
|
||||
|
||||
io_service& ios_ref = descriptor1.get_io_service();
|
||||
|
Loading…
Reference in New Issue
Block a user