upgrade to libtorrent 0.12 ...yay!
This commit is contained in:
parent
c9d4c59249
commit
38e241c379
@ -41,14 +41,24 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
struct TORRENT_EXPORT tracker_alert: alert
|
struct TORRENT_EXPORT torrent_alert: alert
|
||||||
|
{
|
||||||
|
torrent_alert(torrent_handle const& h, alert::severity_t s
|
||||||
|
, std::string const& msg)
|
||||||
|
: alert(s, msg)
|
||||||
|
, handle(h)
|
||||||
|
{}
|
||||||
|
|
||||||
|
torrent_handle handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TORRENT_EXPORT tracker_alert: torrent_alert
|
||||||
{
|
{
|
||||||
tracker_alert(torrent_handle const& h
|
tracker_alert(torrent_handle const& h
|
||||||
, int times
|
, int times
|
||||||
, int status
|
, int status
|
||||||
, std::string const& msg)
|
, std::string const& msg)
|
||||||
: alert(alert::warning, msg)
|
: torrent_alert(h, alert::warning, msg)
|
||||||
, handle(h)
|
|
||||||
, times_in_row(times)
|
, times_in_row(times)
|
||||||
, status_code(status)
|
, status_code(status)
|
||||||
{}
|
{}
|
||||||
@ -56,85 +66,75 @@ namespace libtorrent
|
|||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new tracker_alert(*this)); }
|
{ return std::auto_ptr<alert>(new tracker_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
int times_in_row;
|
int times_in_row;
|
||||||
int status_code;
|
int status_code;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT tracker_warning_alert: alert
|
struct TORRENT_EXPORT tracker_warning_alert: torrent_alert
|
||||||
{
|
{
|
||||||
tracker_warning_alert(torrent_handle const& h
|
tracker_warning_alert(torrent_handle const& h
|
||||||
, std::string const& msg)
|
, std::string const& msg)
|
||||||
: alert(alert::warning, msg)
|
: torrent_alert(h, alert::warning, msg)
|
||||||
, handle(h)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new tracker_warning_alert(*this)); }
|
{ return std::auto_ptr<alert>(new tracker_warning_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct TORRENT_EXPORT tracker_reply_alert: alert
|
struct TORRENT_EXPORT tracker_reply_alert: torrent_alert
|
||||||
{
|
{
|
||||||
tracker_reply_alert(torrent_handle const& h
|
tracker_reply_alert(torrent_handle const& h
|
||||||
|
, int np
|
||||||
, std::string const& msg)
|
, std::string const& msg)
|
||||||
: alert(alert::info, msg)
|
: torrent_alert(h, alert::info, msg)
|
||||||
, handle(h)
|
, num_peers(np)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
int num_peers;
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new tracker_reply_alert(*this)); }
|
{ return std::auto_ptr<alert>(new tracker_reply_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT tracker_announce_alert: alert
|
struct TORRENT_EXPORT tracker_announce_alert: torrent_alert
|
||||||
{
|
{
|
||||||
tracker_announce_alert(torrent_handle const& h, std::string const& msg)
|
tracker_announce_alert(torrent_handle const& h, std::string const& msg)
|
||||||
: alert(alert::info, msg)
|
: torrent_alert(h, alert::info, msg)
|
||||||
, handle(h)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new tracker_announce_alert(*this)); }
|
{ return std::auto_ptr<alert>(new tracker_announce_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT hash_failed_alert: alert
|
struct TORRENT_EXPORT hash_failed_alert: torrent_alert
|
||||||
{
|
{
|
||||||
hash_failed_alert(
|
hash_failed_alert(
|
||||||
torrent_handle const& h
|
torrent_handle const& h
|
||||||
, int index
|
, int index
|
||||||
, std::string const& msg)
|
, std::string const& msg)
|
||||||
: alert(alert::info, msg)
|
: torrent_alert(h, alert::info, msg)
|
||||||
, handle(h)
|
|
||||||
, piece_index(index)
|
, piece_index(index)
|
||||||
{ assert(index >= 0);}
|
{ assert(index >= 0);}
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new hash_failed_alert(*this)); }
|
{ return std::auto_ptr<alert>(new hash_failed_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
int piece_index;
|
int piece_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT peer_ban_alert: alert
|
struct TORRENT_EXPORT peer_ban_alert: torrent_alert
|
||||||
{
|
{
|
||||||
peer_ban_alert(tcp::endpoint const& pip, torrent_handle h, std::string const& msg)
|
peer_ban_alert(tcp::endpoint const& pip, torrent_handle h, std::string const& msg)
|
||||||
: alert(alert::info, msg)
|
: torrent_alert(h, alert::info, msg)
|
||||||
, ip(pip)
|
, ip(pip)
|
||||||
, handle(h)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new peer_ban_alert(*this)); }
|
{ return std::auto_ptr<alert>(new peer_ban_alert(*this)); }
|
||||||
|
|
||||||
tcp::endpoint ip;
|
tcp::endpoint ip;
|
||||||
torrent_handle handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT peer_error_alert: alert
|
struct TORRENT_EXPORT peer_error_alert: alert
|
||||||
@ -152,25 +152,7 @@ namespace libtorrent
|
|||||||
peer_id pid;
|
peer_id pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT chat_message_alert: alert
|
struct TORRENT_EXPORT invalid_request_alert: torrent_alert
|
||||||
{
|
|
||||||
chat_message_alert(
|
|
||||||
const torrent_handle& h
|
|
||||||
, const tcp::endpoint& sender
|
|
||||||
, const std::string& msg)
|
|
||||||
: alert(alert::critical, msg)
|
|
||||||
, handle(h)
|
|
||||||
, ip(sender)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
|
||||||
{ return std::auto_ptr<alert>(new chat_message_alert(*this)); }
|
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
tcp::endpoint ip;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TORRENT_EXPORT invalid_request_alert: alert
|
|
||||||
{
|
{
|
||||||
invalid_request_alert(
|
invalid_request_alert(
|
||||||
peer_request const& r
|
peer_request const& r
|
||||||
@ -178,8 +160,7 @@ namespace libtorrent
|
|||||||
, tcp::endpoint const& sender
|
, tcp::endpoint const& sender
|
||||||
, peer_id const& pid_
|
, peer_id const& pid_
|
||||||
, std::string const& msg)
|
, std::string const& msg)
|
||||||
: alert(alert::debug, msg)
|
: torrent_alert(h, alert::debug, msg)
|
||||||
, handle(h)
|
|
||||||
, ip(sender)
|
, ip(sender)
|
||||||
, request(r)
|
, request(r)
|
||||||
, pid(pid_)
|
, pid(pid_)
|
||||||
@ -188,33 +169,30 @@ namespace libtorrent
|
|||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new invalid_request_alert(*this)); }
|
{ return std::auto_ptr<alert>(new invalid_request_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
tcp::endpoint ip;
|
tcp::endpoint ip;
|
||||||
peer_request request;
|
peer_request request;
|
||||||
peer_id pid;
|
peer_id pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT torrent_finished_alert: alert
|
struct TORRENT_EXPORT torrent_finished_alert: torrent_alert
|
||||||
{
|
{
|
||||||
torrent_finished_alert(
|
torrent_finished_alert(
|
||||||
const torrent_handle& h
|
const torrent_handle& h
|
||||||
, const std::string& msg)
|
, const std::string& msg)
|
||||||
: alert(alert::warning, msg)
|
: torrent_alert(h, alert::warning, msg)
|
||||||
, handle(h)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new torrent_finished_alert(*this)); }
|
{ return std::auto_ptr<alert>(new torrent_finished_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT url_seed_alert: alert
|
struct TORRENT_EXPORT url_seed_alert: torrent_alert
|
||||||
{
|
{
|
||||||
url_seed_alert(
|
url_seed_alert(
|
||||||
const std::string& url_
|
torrent_handle const& h
|
||||||
|
, const std::string& url_
|
||||||
, const std::string& msg)
|
, const std::string& msg)
|
||||||
: alert(alert::warning, msg)
|
: torrent_alert(h, alert::warning, msg)
|
||||||
, url(url_)
|
, url(url_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -224,49 +202,40 @@ namespace libtorrent
|
|||||||
std::string url;
|
std::string url;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT file_error_alert: alert
|
struct TORRENT_EXPORT file_error_alert: torrent_alert
|
||||||
{
|
{
|
||||||
file_error_alert(
|
file_error_alert(
|
||||||
const torrent_handle& h
|
const torrent_handle& h
|
||||||
, const std::string& msg)
|
, const std::string& msg)
|
||||||
: alert(alert::fatal, msg)
|
: torrent_alert(h, alert::fatal, msg)
|
||||||
, handle(h)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new file_error_alert(*this)); }
|
{ return std::auto_ptr<alert>(new file_error_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT metadata_failed_alert: alert
|
struct TORRENT_EXPORT metadata_failed_alert: torrent_alert
|
||||||
{
|
{
|
||||||
metadata_failed_alert(
|
metadata_failed_alert(
|
||||||
const torrent_handle& h
|
const torrent_handle& h
|
||||||
, const std::string& msg)
|
, const std::string& msg)
|
||||||
: alert(alert::info, msg)
|
: torrent_alert(h, alert::info, msg)
|
||||||
, handle(h)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new metadata_failed_alert(*this)); }
|
{ return std::auto_ptr<alert>(new metadata_failed_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT metadata_received_alert: alert
|
struct TORRENT_EXPORT metadata_received_alert: torrent_alert
|
||||||
{
|
{
|
||||||
metadata_received_alert(
|
metadata_received_alert(
|
||||||
const torrent_handle& h
|
const torrent_handle& h
|
||||||
, const std::string& msg)
|
, const std::string& msg)
|
||||||
: alert(alert::info, msg)
|
: torrent_alert(h, alert::info, msg)
|
||||||
, handle(h)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new metadata_received_alert(*this)); }
|
{ return std::auto_ptr<alert>(new metadata_received_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT listen_failed_alert: alert
|
struct TORRENT_EXPORT listen_failed_alert: alert
|
||||||
@ -280,18 +249,15 @@ namespace libtorrent
|
|||||||
{ return std::auto_ptr<alert>(new listen_failed_alert(*this)); }
|
{ return std::auto_ptr<alert>(new listen_failed_alert(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT fastresume_rejected_alert: alert
|
struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert
|
||||||
{
|
{
|
||||||
fastresume_rejected_alert(torrent_handle const& h
|
fastresume_rejected_alert(torrent_handle const& h
|
||||||
, std::string const& msg)
|
, std::string const& msg)
|
||||||
: alert(alert::warning, msg)
|
: torrent_alert(h, alert::warning, msg)
|
||||||
, handle(h)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new fastresume_rejected_alert(*this)); }
|
{ return std::auto_ptr<alert>(new fastresume_rejected_alert(*this)); }
|
||||||
|
|
||||||
torrent_handle handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libtorrent/resource_request.hpp"
|
#include "libtorrent/resource_request.hpp"
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
|
#include "libtorrent/session.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
@ -66,6 +67,11 @@ namespace libtorrent
|
|||||||
, std::map<tcp::endpoint, peer_connection*>& connections
|
, std::map<tcp::endpoint, peer_connection*>& connections
|
||||||
, resource_request peer_connection::* res);
|
, resource_request peer_connection::* res);
|
||||||
|
|
||||||
|
// Used for global limits.
|
||||||
|
void allocate_resources(
|
||||||
|
int resources
|
||||||
|
, std::vector<session*>& _sessions
|
||||||
|
, resource_request session::* res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// asio.hpp
|
// asio.hpp
|
||||||
// ~~~~~~~~
|
// ~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -18,7 +18,6 @@
|
|||||||
#include "asio/basic_datagram_socket.hpp"
|
#include "asio/basic_datagram_socket.hpp"
|
||||||
#include "asio/basic_deadline_timer.hpp"
|
#include "asio/basic_deadline_timer.hpp"
|
||||||
#include "asio/basic_io_object.hpp"
|
#include "asio/basic_io_object.hpp"
|
||||||
#include "asio/basic_resolver.hpp"
|
|
||||||
#include "asio/basic_socket_acceptor.hpp"
|
#include "asio/basic_socket_acceptor.hpp"
|
||||||
#include "asio/basic_socket_iostream.hpp"
|
#include "asio/basic_socket_iostream.hpp"
|
||||||
#include "asio/basic_socket_streambuf.hpp"
|
#include "asio/basic_socket_streambuf.hpp"
|
||||||
@ -35,8 +34,8 @@
|
|||||||
#include "asio/datagram_socket_service.hpp"
|
#include "asio/datagram_socket_service.hpp"
|
||||||
#include "asio/deadline_timer_service.hpp"
|
#include "asio/deadline_timer_service.hpp"
|
||||||
#include "asio/deadline_timer.hpp"
|
#include "asio/deadline_timer.hpp"
|
||||||
#include "asio/error_handler.hpp"
|
|
||||||
#include "asio/error.hpp"
|
#include "asio/error.hpp"
|
||||||
|
#include "asio/error_code.hpp"
|
||||||
#include "asio/handler_alloc_hook.hpp"
|
#include "asio/handler_alloc_hook.hpp"
|
||||||
#include "asio/handler_invoke_hook.hpp"
|
#include "asio/handler_invoke_hook.hpp"
|
||||||
#include "asio/io_service.hpp"
|
#include "asio/io_service.hpp"
|
||||||
@ -44,26 +43,29 @@
|
|||||||
#include "asio/ip/address_v4.hpp"
|
#include "asio/ip/address_v4.hpp"
|
||||||
#include "asio/ip/address_v6.hpp"
|
#include "asio/ip/address_v6.hpp"
|
||||||
#include "asio/ip/basic_endpoint.hpp"
|
#include "asio/ip/basic_endpoint.hpp"
|
||||||
|
#include "asio/ip/basic_resolver.hpp"
|
||||||
#include "asio/ip/basic_resolver_entry.hpp"
|
#include "asio/ip/basic_resolver_entry.hpp"
|
||||||
#include "asio/ip/basic_resolver_iterator.hpp"
|
#include "asio/ip/basic_resolver_iterator.hpp"
|
||||||
#include "asio/ip/basic_resolver_query.hpp"
|
#include "asio/ip/basic_resolver_query.hpp"
|
||||||
#include "asio/ip/host_name.hpp"
|
#include "asio/ip/host_name.hpp"
|
||||||
#include "asio/ip/multicast.hpp"
|
#include "asio/ip/multicast.hpp"
|
||||||
#include "asio/ip/resolver_query_base.hpp"
|
#include "asio/ip/resolver_query_base.hpp"
|
||||||
|
#include "asio/ip/resolver_service.hpp"
|
||||||
#include "asio/ip/tcp.hpp"
|
#include "asio/ip/tcp.hpp"
|
||||||
#include "asio/ip/udp.hpp"
|
#include "asio/ip/udp.hpp"
|
||||||
|
#include "asio/ip/unicast.hpp"
|
||||||
|
#include "asio/ip/v6_only.hpp"
|
||||||
#include "asio/is_read_buffered.hpp"
|
#include "asio/is_read_buffered.hpp"
|
||||||
#include "asio/is_write_buffered.hpp"
|
#include "asio/is_write_buffered.hpp"
|
||||||
#include "asio/placeholders.hpp"
|
#include "asio/placeholders.hpp"
|
||||||
#include "asio/read.hpp"
|
#include "asio/read.hpp"
|
||||||
#include "asio/read_until.hpp"
|
#include "asio/read_until.hpp"
|
||||||
#include "asio/resolver_service.hpp"
|
|
||||||
#include "asio/socket_acceptor_service.hpp"
|
#include "asio/socket_acceptor_service.hpp"
|
||||||
#include "asio/socket_base.hpp"
|
#include "asio/socket_base.hpp"
|
||||||
#include "asio/strand.hpp"
|
#include "asio/strand.hpp"
|
||||||
#include "asio/stream_socket_service.hpp"
|
#include "asio/stream_socket_service.hpp"
|
||||||
#include "asio/streambuf.hpp"
|
#include "asio/streambuf.hpp"
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/thread.hpp"
|
#include "asio/thread.hpp"
|
||||||
#include "asio/time_traits.hpp"
|
#include "asio/time_traits.hpp"
|
||||||
#include "asio/write.hpp"
|
#include "asio/write.hpp"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// basic_datagram_socket.hpp
|
// basic_datagram_socket.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -24,7 +24,8 @@
|
|||||||
|
|
||||||
#include "asio/basic_socket.hpp"
|
#include "asio/basic_socket.hpp"
|
||||||
#include "asio/datagram_socket_service.hpp"
|
#include "asio/datagram_socket_service.hpp"
|
||||||
#include "asio/error_handler.hpp"
|
#include "asio/error.hpp"
|
||||||
|
#include "asio/detail/throw_error.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
@ -33,21 +34,18 @@ namespace asio {
|
|||||||
* The basic_datagram_socket class template provides asynchronous and blocking
|
* The basic_datagram_socket class template provides asynchronous and blocking
|
||||||
* datagram-oriented socket functionality.
|
* datagram-oriented socket functionality.
|
||||||
*
|
*
|
||||||
* @par Thread Safety:
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
|
||||||
* @par Concepts:
|
|
||||||
* Async_Object, Error_Source.
|
|
||||||
*/
|
*/
|
||||||
template <typename Protocol,
|
template <typename Protocol,
|
||||||
typename Service = datagram_socket_service<Protocol> >
|
typename DatagramSocketService = datagram_socket_service<Protocol> >
|
||||||
class basic_datagram_socket
|
class basic_datagram_socket
|
||||||
: public basic_socket<Protocol, Service>
|
: public basic_socket<Protocol, DatagramSocketService>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The native representation of a socket.
|
/// The native representation of a socket.
|
||||||
typedef typename Service::native_type native_type;
|
typedef typename DatagramSocketService::native_type native_type;
|
||||||
|
|
||||||
/// The protocol type.
|
/// The protocol type.
|
||||||
typedef Protocol protocol_type;
|
typedef Protocol protocol_type;
|
||||||
@ -65,7 +63,7 @@ public:
|
|||||||
* socket.
|
* socket.
|
||||||
*/
|
*/
|
||||||
explicit basic_datagram_socket(asio::io_service& io_service)
|
explicit basic_datagram_socket(asio::io_service& io_service)
|
||||||
: basic_socket<Protocol, Service>(io_service)
|
: basic_socket<Protocol, DatagramSocketService>(io_service)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,11 +77,11 @@ public:
|
|||||||
*
|
*
|
||||||
* @param protocol An object specifying protocol parameters to be used.
|
* @param protocol An object specifying protocol parameters to be used.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_datagram_socket(asio::io_service& io_service,
|
basic_datagram_socket(asio::io_service& io_service,
|
||||||
const protocol_type& protocol)
|
const protocol_type& protocol)
|
||||||
: basic_socket<Protocol, Service>(io_service, protocol)
|
: basic_socket<Protocol, DatagramSocketService>(io_service, protocol)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,11 +99,11 @@ public:
|
|||||||
* @param endpoint An endpoint on the local machine to which the datagram
|
* @param endpoint An endpoint on the local machine to which the datagram
|
||||||
* socket will be bound.
|
* socket will be bound.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_datagram_socket(asio::io_service& io_service,
|
basic_datagram_socket(asio::io_service& io_service,
|
||||||
const endpoint_type& endpoint)
|
const endpoint_type& endpoint)
|
||||||
: basic_socket<Protocol, Service>(io_service, endpoint)
|
: basic_socket<Protocol, DatagramSocketService>(io_service, endpoint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,11 +120,12 @@ public:
|
|||||||
*
|
*
|
||||||
* @param native_socket The new underlying socket implementation.
|
* @param native_socket The new underlying socket implementation.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_datagram_socket(asio::io_service& io_service,
|
basic_datagram_socket(asio::io_service& io_service,
|
||||||
const protocol_type& protocol, const native_type& native_socket)
|
const protocol_type& protocol, const native_type& native_socket)
|
||||||
: basic_socket<Protocol, Service>(io_service, protocol, native_socket)
|
: basic_socket<Protocol, DatagramSocketService>(
|
||||||
|
io_service, protocol, native_socket)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,22 +139,25 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes sent.
|
* @returns The number of bytes sent.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @note The send operation can only be used with a connected socket. Use
|
* @note The send operation can only be used with a connected socket. Use
|
||||||
* the send_to function to send data on an unconnected datagram socket.
|
* the send_to function to send data on an unconnected datagram socket.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To send a single data buffer use the @ref buffer function as follows:
|
* To send a single data buffer use the @ref buffer function as follows:
|
||||||
* @code socket.send(asio::buffer(data, size)); @endcode
|
* @code socket.send(asio::buffer(data, size)); @endcode
|
||||||
* See the @ref buffer documentation for information on sending multiple
|
* See the @ref buffer documentation for information on sending multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send(const Const_Buffers& buffers)
|
std::size_t send(const ConstBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return this->service.send(this->implementation, buffers, 0, throw_error());
|
asio::error_code ec;
|
||||||
|
std::size_t s = this->service.send(this->implementation, buffers, 0, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send some data on a connected socket.
|
/// Send some data on a connected socket.
|
||||||
@ -170,17 +172,20 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes sent.
|
* @returns The number of bytes sent.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @note The send operation can only be used with a connected socket. Use
|
* @note The send operation can only be used with a connected socket. Use
|
||||||
* the send_to function to send data on an unconnected datagram socket.
|
* the send_to function to send data on an unconnected datagram socket.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send(const Const_Buffers& buffers,
|
std::size_t send(const ConstBufferSequence& buffers,
|
||||||
socket_base::message_flags flags)
|
socket_base::message_flags flags)
|
||||||
{
|
{
|
||||||
return this->service.send(this->implementation, buffers, flags,
|
asio::error_code ec;
|
||||||
throw_error());
|
std::size_t s = this->service.send(
|
||||||
|
this->implementation, buffers, flags, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send some data on a connected socket.
|
/// Send some data on a connected socket.
|
||||||
@ -193,24 +198,18 @@ public:
|
|||||||
*
|
*
|
||||||
* @param flags Flags specifying how the send call is to be made.
|
* @param flags Flags specifying how the send call is to be made.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation.
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns The number of bytes sent.
|
* @returns The number of bytes sent.
|
||||||
*
|
*
|
||||||
* @note The send operation can only be used with a connected socket. Use
|
* @note The send operation can only be used with a connected socket. Use
|
||||||
* the send_to function to send data on an unconnected datagram socket.
|
* the send_to function to send data on an unconnected datagram socket.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Error_Handler>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send(const Const_Buffers& buffers,
|
std::size_t send(const ConstBufferSequence& buffers,
|
||||||
socket_base::message_flags flags, Error_Handler error_handler)
|
socket_base::message_flags flags, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return this->service.send(this->implementation, buffers, flags,
|
return this->service.send(this->implementation, buffers, flags, ec);
|
||||||
error_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous send on a connected socket.
|
/// Start an asynchronous send on a connected socket.
|
||||||
@ -228,7 +227,7 @@ public:
|
|||||||
* Copies will be made of the handler as required. The function signature of
|
* Copies will be made of the handler as required. The function signature of
|
||||||
* the handler must be:
|
* the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes sent.
|
* std::size_t bytes_transferred // Number of bytes sent.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -240,7 +239,7 @@ public:
|
|||||||
* Use the async_send_to function to send data on an unconnected datagram
|
* Use the async_send_to function to send data on an unconnected datagram
|
||||||
* socket.
|
* socket.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To send a single data buffer use the @ref buffer function as follows:
|
* To send a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* socket.async_send(asio::buffer(data, size), handler);
|
* socket.async_send(asio::buffer(data, size), handler);
|
||||||
@ -249,8 +248,8 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_send(const Const_Buffers& buffers, Handler handler)
|
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_send(this->implementation, buffers, 0, handler);
|
this->service.async_send(this->implementation, buffers, 0, handler);
|
||||||
}
|
}
|
||||||
@ -272,7 +271,7 @@ public:
|
|||||||
* Copies will be made of the handler as required. The function signature of
|
* Copies will be made of the handler as required. The function signature of
|
||||||
* the handler must be:
|
* the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes sent.
|
* std::size_t bytes_transferred // Number of bytes sent.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -284,9 +283,9 @@ public:
|
|||||||
* Use the async_send_to function to send data on an unconnected datagram
|
* Use the async_send_to function to send data on an unconnected datagram
|
||||||
* socket.
|
* socket.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_send(const Const_Buffers& buffers,
|
void async_send(const ConstBufferSequence& buffers,
|
||||||
socket_base::message_flags flags, Handler handler)
|
socket_base::message_flags flags, WriteHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_send(this->implementation, buffers, flags, handler);
|
this->service.async_send(this->implementation, buffers, flags, handler);
|
||||||
}
|
}
|
||||||
@ -303,9 +302,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes sent.
|
* @returns The number of bytes sent.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To send a single data buffer use the @ref buffer function as follows:
|
* To send a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::udp::endpoint destination(
|
* asio::ip::udp::endpoint destination(
|
||||||
@ -316,12 +315,15 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send_to(const Const_Buffers& buffers,
|
std::size_t send_to(const ConstBufferSequence& buffers,
|
||||||
const endpoint_type& destination)
|
const endpoint_type& destination)
|
||||||
{
|
{
|
||||||
return this->service.send_to(this->implementation, buffers, destination, 0,
|
asio::error_code ec;
|
||||||
throw_error());
|
std::size_t s = this->service.send_to(
|
||||||
|
this->implementation, buffers, destination, 0, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a datagram to the specified endpoint.
|
/// Send a datagram to the specified endpoint.
|
||||||
@ -338,14 +340,17 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes sent.
|
* @returns The number of bytes sent.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send_to(const Const_Buffers& buffers,
|
std::size_t send_to(const ConstBufferSequence& buffers,
|
||||||
const endpoint_type& destination, socket_base::message_flags flags)
|
const endpoint_type& destination, socket_base::message_flags flags)
|
||||||
{
|
{
|
||||||
return this->service.send_to(this->implementation, buffers, destination,
|
asio::error_code ec;
|
||||||
flags, throw_error());
|
std::size_t s = this->service.send_to(
|
||||||
|
this->implementation, buffers, destination, flags, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a datagram to the specified endpoint.
|
/// Send a datagram to the specified endpoint.
|
||||||
@ -360,22 +365,17 @@ public:
|
|||||||
*
|
*
|
||||||
* @param flags Flags specifying how the send call is to be made.
|
* @param flags Flags specifying how the send call is to be made.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation.
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns The number of bytes sent.
|
* @returns The number of bytes sent.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Error_Handler>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send_to(const Const_Buffers& buffers,
|
std::size_t send_to(const ConstBufferSequence& buffers,
|
||||||
const endpoint_type& destination, socket_base::message_flags flags,
|
const endpoint_type& destination, socket_base::message_flags flags,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return this->service.send_to(this->implementation, buffers, destination,
|
return this->service.send_to(this->implementation,
|
||||||
flags, error_handler);
|
buffers, destination, flags, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous send.
|
/// Start an asynchronous send.
|
||||||
@ -395,7 +395,7 @@ public:
|
|||||||
* Copies will be made of the handler as required. The function signature of
|
* Copies will be made of the handler as required. The function signature of
|
||||||
* the handler must be:
|
* the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes sent.
|
* std::size_t bytes_transferred // Number of bytes sent.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -403,7 +403,7 @@ public:
|
|||||||
* of the handler will be performed in a manner equivalent to using
|
* of the handler will be performed in a manner equivalent to using
|
||||||
* asio::io_service::post().
|
* asio::io_service::post().
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To send a single data buffer use the @ref buffer function as follows:
|
* To send a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::udp::endpoint destination(
|
* asio::ip::udp::endpoint destination(
|
||||||
@ -415,9 +415,9 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_send_to(const Const_Buffers& buffers,
|
void async_send_to(const ConstBufferSequence& buffers,
|
||||||
const endpoint_type& destination, Handler handler)
|
const endpoint_type& destination, WriteHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_send_to(this->implementation, buffers, destination, 0,
|
this->service.async_send_to(this->implementation, buffers, destination, 0,
|
||||||
handler);
|
handler);
|
||||||
@ -442,7 +442,7 @@ public:
|
|||||||
* Copies will be made of the handler as required. The function signature of
|
* Copies will be made of the handler as required. The function signature of
|
||||||
* the handler must be:
|
* the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes sent.
|
* std::size_t bytes_transferred // Number of bytes sent.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -450,10 +450,10 @@ public:
|
|||||||
* of the handler will be performed in a manner equivalent to using
|
* of the handler will be performed in a manner equivalent to using
|
||||||
* asio::io_service::post().
|
* asio::io_service::post().
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_send_to(const Const_Buffers& buffers,
|
void async_send_to(const ConstBufferSequence& buffers,
|
||||||
const endpoint_type& destination, socket_base::message_flags flags,
|
const endpoint_type& destination, socket_base::message_flags flags,
|
||||||
Handler handler)
|
WriteHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_send_to(this->implementation, buffers, destination,
|
this->service.async_send_to(this->implementation, buffers, destination,
|
||||||
flags, handler);
|
flags, handler);
|
||||||
@ -469,13 +469,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes received.
|
* @returns The number of bytes received.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @note The receive operation can only be used with a connected socket. Use
|
* @note The receive operation can only be used with a connected socket. Use
|
||||||
* the receive_from function to receive data on an unconnected datagram
|
* the receive_from function to receive data on an unconnected datagram
|
||||||
* socket.
|
* socket.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To receive into a single data buffer use the @ref buffer function as
|
* To receive into a single data buffer use the @ref buffer function as
|
||||||
* follows:
|
* follows:
|
||||||
* @code socket.receive(asio::buffer(data, size)); @endcode
|
* @code socket.receive(asio::buffer(data, size)); @endcode
|
||||||
@ -483,11 +483,14 @@ public:
|
|||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive(const Mutable_Buffers& buffers)
|
std::size_t receive(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return this->service.receive(this->implementation, buffers, 0,
|
asio::error_code ec;
|
||||||
throw_error());
|
std::size_t s = this->service.receive(
|
||||||
|
this->implementation, buffers, 0, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive some data on a connected socket.
|
/// Receive some data on a connected socket.
|
||||||
@ -502,18 +505,21 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes received.
|
* @returns The number of bytes received.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @note The receive operation can only be used with a connected socket. Use
|
* @note The receive operation can only be used with a connected socket. Use
|
||||||
* the receive_from function to receive data on an unconnected datagram
|
* the receive_from function to receive data on an unconnected datagram
|
||||||
* socket.
|
* socket.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive(const Mutable_Buffers& buffers,
|
std::size_t receive(const MutableBufferSequence& buffers,
|
||||||
socket_base::message_flags flags)
|
socket_base::message_flags flags)
|
||||||
{
|
{
|
||||||
return this->service.receive(this->implementation, buffers, flags,
|
asio::error_code ec;
|
||||||
throw_error());
|
std::size_t s = this->service.receive(
|
||||||
|
this->implementation, buffers, flags, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive some data on a connected socket.
|
/// Receive some data on a connected socket.
|
||||||
@ -526,12 +532,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param flags Flags specifying how the receive call is to be made.
|
* @param flags Flags specifying how the receive call is to be made.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation.
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns The number of bytes received.
|
* @returns The number of bytes received.
|
||||||
*
|
*
|
||||||
@ -539,12 +540,11 @@ public:
|
|||||||
* the receive_from function to receive data on an unconnected datagram
|
* the receive_from function to receive data on an unconnected datagram
|
||||||
* socket.
|
* socket.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive(const Mutable_Buffers& buffers,
|
std::size_t receive(const MutableBufferSequence& buffers,
|
||||||
socket_base::message_flags flags, Error_Handler error_handler)
|
socket_base::message_flags flags, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return this->service.receive(this->implementation, buffers, flags,
|
return this->service.receive(this->implementation, buffers, flags, ec);
|
||||||
error_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous receive on a connected socket.
|
/// Start an asynchronous receive on a connected socket.
|
||||||
@ -561,7 +561,7 @@ public:
|
|||||||
* completes. Copies will be made of the handler as required. The function
|
* completes. Copies will be made of the handler as required. The function
|
||||||
* signature of the handler must be:
|
* signature of the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes received.
|
* std::size_t bytes_transferred // Number of bytes received.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -573,7 +573,7 @@ public:
|
|||||||
* Use the async_receive_from function to receive data on an unconnected
|
* Use the async_receive_from function to receive data on an unconnected
|
||||||
* datagram socket.
|
* datagram socket.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To receive into a single data buffer use the @ref buffer function as
|
* To receive into a single data buffer use the @ref buffer function as
|
||||||
* follows:
|
* follows:
|
||||||
* @code
|
* @code
|
||||||
@ -583,8 +583,8 @@ public:
|
|||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_receive(const Mutable_Buffers& buffers, Handler handler)
|
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_receive(this->implementation, buffers, 0, handler);
|
this->service.async_receive(this->implementation, buffers, 0, handler);
|
||||||
}
|
}
|
||||||
@ -605,7 +605,7 @@ public:
|
|||||||
* completes. Copies will be made of the handler as required. The function
|
* completes. Copies will be made of the handler as required. The function
|
||||||
* signature of the handler must be:
|
* signature of the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes received.
|
* std::size_t bytes_transferred // Number of bytes received.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -617,9 +617,9 @@ public:
|
|||||||
* Use the async_receive_from function to receive data on an unconnected
|
* Use the async_receive_from function to receive data on an unconnected
|
||||||
* datagram socket.
|
* datagram socket.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_receive(const Mutable_Buffers& buffers,
|
void async_receive(const MutableBufferSequence& buffers,
|
||||||
socket_base::message_flags flags, Handler handler)
|
socket_base::message_flags flags, ReadHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_receive(this->implementation, buffers, flags, handler);
|
this->service.async_receive(this->implementation, buffers, flags, handler);
|
||||||
}
|
}
|
||||||
@ -636,9 +636,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes received.
|
* @returns The number of bytes received.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To receive into a single data buffer use the @ref buffer function as
|
* To receive into a single data buffer use the @ref buffer function as
|
||||||
* follows:
|
* follows:
|
||||||
* @code
|
* @code
|
||||||
@ -650,12 +650,15 @@ public:
|
|||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive_from(const Mutable_Buffers& buffers,
|
std::size_t receive_from(const MutableBufferSequence& buffers,
|
||||||
endpoint_type& sender_endpoint)
|
endpoint_type& sender_endpoint)
|
||||||
{
|
{
|
||||||
return this->service.receive_from(this->implementation, buffers,
|
asio::error_code ec;
|
||||||
sender_endpoint, 0, throw_error());
|
std::size_t s = this->service.receive_from(
|
||||||
|
this->implementation, buffers, sender_endpoint, 0, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive a datagram with the endpoint of the sender.
|
/// Receive a datagram with the endpoint of the sender.
|
||||||
@ -672,14 +675,17 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes received.
|
* @returns The number of bytes received.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive_from(const Mutable_Buffers& buffers,
|
std::size_t receive_from(const MutableBufferSequence& buffers,
|
||||||
endpoint_type& sender_endpoint, socket_base::message_flags flags)
|
endpoint_type& sender_endpoint, socket_base::message_flags flags)
|
||||||
{
|
{
|
||||||
return this->service.receive_from(this->implementation, buffers,
|
asio::error_code ec;
|
||||||
sender_endpoint, flags, throw_error());
|
std::size_t s = this->service.receive_from(
|
||||||
|
this->implementation, buffers, sender_endpoint, flags, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive a datagram with the endpoint of the sender.
|
/// Receive a datagram with the endpoint of the sender.
|
||||||
@ -694,22 +700,17 @@ public:
|
|||||||
*
|
*
|
||||||
* @param flags Flags specifying how the receive call is to be made.
|
* @param flags Flags specifying how the receive call is to be made.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation.
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns The number of bytes received.
|
* @returns The number of bytes received.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive_from(const Mutable_Buffers& buffers,
|
std::size_t receive_from(const MutableBufferSequence& buffers,
|
||||||
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return this->service.receive_from(this->implementation, buffers,
|
return this->service.receive_from(this->implementation, buffers,
|
||||||
sender_endpoint, flags, error_handler);
|
sender_endpoint, flags, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous receive.
|
/// Start an asynchronous receive.
|
||||||
@ -731,7 +732,7 @@ public:
|
|||||||
* completes. Copies will be made of the handler as required. The function
|
* completes. Copies will be made of the handler as required. The function
|
||||||
* signature of the handler must be:
|
* signature of the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::system_error& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes received.
|
* std::size_t bytes_transferred // Number of bytes received.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -739,7 +740,7 @@ public:
|
|||||||
* of the handler will be performed in a manner equivalent to using
|
* of the handler will be performed in a manner equivalent to using
|
||||||
* asio::io_service::post().
|
* asio::io_service::post().
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To receive into a single data buffer use the @ref buffer function as
|
* To receive into a single data buffer use the @ref buffer function as
|
||||||
* follows:
|
* follows:
|
||||||
* @code socket.async_receive_from(
|
* @code socket.async_receive_from(
|
||||||
@ -748,9 +749,9 @@ public:
|
|||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_receive_from(const Mutable_Buffers& buffers,
|
void async_receive_from(const MutableBufferSequence& buffers,
|
||||||
endpoint_type& sender_endpoint, Handler handler)
|
endpoint_type& sender_endpoint, ReadHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_receive_from(this->implementation, buffers,
|
this->service.async_receive_from(this->implementation, buffers,
|
||||||
sender_endpoint, 0, handler);
|
sender_endpoint, 0, handler);
|
||||||
@ -777,7 +778,7 @@ public:
|
|||||||
* completes. Copies will be made of the handler as required. The function
|
* completes. Copies will be made of the handler as required. The function
|
||||||
* signature of the handler must be:
|
* signature of the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes received.
|
* std::size_t bytes_transferred // Number of bytes received.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -785,10 +786,10 @@ public:
|
|||||||
* of the handler will be performed in a manner equivalent to using
|
* of the handler will be performed in a manner equivalent to using
|
||||||
* asio::io_service::post().
|
* asio::io_service::post().
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_receive_from(const Mutable_Buffers& buffers,
|
void async_receive_from(const MutableBufferSequence& buffers,
|
||||||
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
||||||
Handler handler)
|
ReadHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_receive_from(this->implementation, buffers,
|
this->service.async_receive_from(this->implementation, buffers,
|
||||||
sender_endpoint, flags, handler);
|
sender_endpoint, flags, handler);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// basic_deadline_timer.hpp
|
// basic_deadline_timer.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include "asio/basic_io_object.hpp"
|
#include "asio/basic_io_object.hpp"
|
||||||
#include "asio/deadline_timer_service.hpp"
|
#include "asio/deadline_timer_service.hpp"
|
||||||
#include "asio/error.hpp"
|
#include "asio/error.hpp"
|
||||||
|
#include "asio/detail/throw_error.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
@ -35,16 +36,13 @@ namespace asio {
|
|||||||
*
|
*
|
||||||
* Most applications will use the asio::deadline_timer typedef.
|
* Most applications will use the asio::deadline_timer typedef.
|
||||||
*
|
*
|
||||||
* @par Thread Safety:
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
*
|
||||||
* @par Concepts:
|
|
||||||
* Async_Object, Error_Source.
|
|
||||||
*
|
|
||||||
* @sa @ref deadline_timer_reset
|
* @sa @ref deadline_timer_reset
|
||||||
*
|
*
|
||||||
* @par Examples:
|
* @par Examples
|
||||||
* Performing a blocking wait:
|
* Performing a blocking wait:
|
||||||
* @code
|
* @code
|
||||||
* // Construct a timer without setting an expiry time.
|
* // Construct a timer without setting an expiry time.
|
||||||
@ -60,7 +58,7 @@ namespace asio {
|
|||||||
* @par
|
* @par
|
||||||
* Performing an asynchronous wait:
|
* Performing an asynchronous wait:
|
||||||
* @code
|
* @code
|
||||||
* void handler(const asio::error& error)
|
* void handler(const asio::error_code& error)
|
||||||
* {
|
* {
|
||||||
* if (!error)
|
* if (!error)
|
||||||
* {
|
* {
|
||||||
@ -78,18 +76,15 @@ namespace asio {
|
|||||||
* timer.async_wait(handler);
|
* timer.async_wait(handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Time_Type,
|
template <typename Time,
|
||||||
typename Time_Traits = asio::time_traits<Time_Type>,
|
typename TimeTraits = asio::time_traits<Time>,
|
||||||
typename Service = deadline_timer_service<Time_Type, Time_Traits> >
|
typename TimerService = deadline_timer_service<Time, TimeTraits> >
|
||||||
class basic_deadline_timer
|
class basic_deadline_timer
|
||||||
: public basic_io_object<Service>
|
: public basic_io_object<TimerService>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The type used for reporting errors.
|
|
||||||
typedef asio::error error_type;
|
|
||||||
|
|
||||||
/// The time traits type.
|
/// The time traits type.
|
||||||
typedef Time_Traits traits_type;
|
typedef TimeTraits traits_type;
|
||||||
|
|
||||||
/// The time type.
|
/// The time type.
|
||||||
typedef typename traits_type::time_type time_type;
|
typedef typename traits_type::time_type time_type;
|
||||||
@ -107,7 +102,7 @@ public:
|
|||||||
* handlers for any asynchronous operations performed on the timer.
|
* handlers for any asynchronous operations performed on the timer.
|
||||||
*/
|
*/
|
||||||
explicit basic_deadline_timer(asio::io_service& io_service)
|
explicit basic_deadline_timer(asio::io_service& io_service)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<TimerService>(io_service)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,9 +118,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
basic_deadline_timer(asio::io_service& io_service,
|
basic_deadline_timer(asio::io_service& io_service,
|
||||||
const time_type& expiry_time)
|
const time_type& expiry_time)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<TimerService>(io_service)
|
||||||
{
|
{
|
||||||
this->service.expires_at(this->implementation, expiry_time);
|
asio::error_code ec;
|
||||||
|
this->service.expires_at(this->implementation, expiry_time, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructor to set a particular expiry time relative to now.
|
/// Constructor to set a particular expiry time relative to now.
|
||||||
@ -140,9 +137,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
basic_deadline_timer(asio::io_service& io_service,
|
basic_deadline_timer(asio::io_service& io_service,
|
||||||
const duration_type& expiry_time)
|
const duration_type& expiry_time)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<TimerService>(io_service)
|
||||||
{
|
{
|
||||||
this->service.expires_from_now(this->implementation, expiry_time);
|
asio::error_code ec;
|
||||||
|
this->service.expires_from_now(this->implementation, expiry_time, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cancel any asynchronous operations that are waiting on the timer.
|
/// Cancel any asynchronous operations that are waiting on the timer.
|
||||||
@ -154,10 +153,32 @@ public:
|
|||||||
* Cancelling the timer does not change the expiry time.
|
* Cancelling the timer does not change the expiry time.
|
||||||
*
|
*
|
||||||
* @return The number of asynchronous operations that were cancelled.
|
* @return The number of asynchronous operations that were cancelled.
|
||||||
|
*
|
||||||
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
std::size_t cancel()
|
std::size_t cancel()
|
||||||
{
|
{
|
||||||
return this->service.cancel(this->implementation);
|
asio::error_code ec;
|
||||||
|
std::size_t s = this->service.cancel(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancel any asynchronous operations that are waiting on the timer.
|
||||||
|
/**
|
||||||
|
* This function forces the completion of any pending asynchronous wait
|
||||||
|
* operations against the timer. The handler for each cancelled operation will
|
||||||
|
* be invoked with the asio::error::operation_aborted error code.
|
||||||
|
*
|
||||||
|
* Cancelling the timer does not change the expiry time.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @return The number of asynchronous operations that were cancelled.
|
||||||
|
*/
|
||||||
|
std::size_t cancel(asio::error_code& ec)
|
||||||
|
{
|
||||||
|
return this->service.cancel(this->implementation, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the timer's expiry time as an absolute time.
|
/// Get the timer's expiry time as an absolute time.
|
||||||
@ -182,10 +203,37 @@ public:
|
|||||||
* @param expiry_time The expiry time to be used for the timer.
|
* @param expiry_time The expiry time to be used for the timer.
|
||||||
*
|
*
|
||||||
* @return The number of asynchronous operations that were cancelled.
|
* @return The number of asynchronous operations that were cancelled.
|
||||||
|
*
|
||||||
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
std::size_t expires_at(const time_type& expiry_time)
|
std::size_t expires_at(const time_type& expiry_time)
|
||||||
{
|
{
|
||||||
return this->service.expires_at(this->implementation, expiry_time);
|
asio::error_code ec;
|
||||||
|
std::size_t s = this->service.expires_at(
|
||||||
|
this->implementation, expiry_time, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the timer's expiry time as an absolute time.
|
||||||
|
/**
|
||||||
|
* This function sets the expiry time. Any pending asynchronous wait
|
||||||
|
* operations will be cancelled. The handler for each cancelled operation will
|
||||||
|
* be invoked with the asio::error::operation_aborted error code.
|
||||||
|
*
|
||||||
|
* See @ref deadline_timer_reset for more information on altering the expiry
|
||||||
|
* time of an active timer.
|
||||||
|
*
|
||||||
|
* @param expiry_time The expiry time to be used for the timer.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @return The number of asynchronous operations that were cancelled.
|
||||||
|
*/
|
||||||
|
std::size_t expires_at(const time_type& expiry_time,
|
||||||
|
asio::error_code& ec)
|
||||||
|
{
|
||||||
|
return this->service.expires_at(this->implementation, expiry_time, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the timer's expiry time relative to now.
|
/// Get the timer's expiry time relative to now.
|
||||||
@ -210,10 +258,38 @@ public:
|
|||||||
* @param expiry_time The expiry time to be used for the timer.
|
* @param expiry_time The expiry time to be used for the timer.
|
||||||
*
|
*
|
||||||
* @return The number of asynchronous operations that were cancelled.
|
* @return The number of asynchronous operations that were cancelled.
|
||||||
|
*
|
||||||
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
std::size_t expires_from_now(const duration_type& expiry_time)
|
std::size_t expires_from_now(const duration_type& expiry_time)
|
||||||
{
|
{
|
||||||
return this->service.expires_from_now(this->implementation, expiry_time);
|
asio::error_code ec;
|
||||||
|
std::size_t s = this->service.expires_from_now(
|
||||||
|
this->implementation, expiry_time, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the timer's expiry time relative to now.
|
||||||
|
/**
|
||||||
|
* This function sets the expiry time. Any pending asynchronous wait
|
||||||
|
* operations will be cancelled. The handler for each cancelled operation will
|
||||||
|
* be invoked with the asio::error::operation_aborted error code.
|
||||||
|
*
|
||||||
|
* See @ref deadline_timer_reset for more information on altering the expiry
|
||||||
|
* time of an active timer.
|
||||||
|
*
|
||||||
|
* @param expiry_time The expiry time to be used for the timer.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @return The number of asynchronous operations that were cancelled.
|
||||||
|
*/
|
||||||
|
std::size_t expires_from_now(const duration_type& expiry_time,
|
||||||
|
asio::error_code& ec)
|
||||||
|
{
|
||||||
|
return this->service.expires_from_now(
|
||||||
|
this->implementation, expiry_time, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a blocking wait on the timer.
|
/// Perform a blocking wait on the timer.
|
||||||
@ -221,11 +297,25 @@ public:
|
|||||||
* This function is used to wait for the timer to expire. This function
|
* This function is used to wait for the timer to expire. This function
|
||||||
* blocks and does not return until the timer has expired.
|
* blocks and does not return until the timer has expired.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
void wait()
|
void wait()
|
||||||
{
|
{
|
||||||
this->service.wait(this->implementation);
|
asio::error_code ec;
|
||||||
|
this->service.wait(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Perform a blocking wait on the timer.
|
||||||
|
/**
|
||||||
|
* This function is used to wait for the timer to expire. This function
|
||||||
|
* blocks and does not return until the timer has expired.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
void wait(asio::error_code& ec)
|
||||||
|
{
|
||||||
|
this->service.wait(this->implementation, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous wait on the timer.
|
/// Start an asynchronous wait on the timer.
|
||||||
@ -245,15 +335,15 @@ public:
|
|||||||
* will be made of the handler as required. The function signature of the
|
* will be made of the handler as required. The function signature of the
|
||||||
* handler must be:
|
* handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error // Result of operation
|
* const asio::error_code& error // Result of operation.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
* not, the handler will not be invoked from within this function. Invocation
|
* not, the handler will not be invoked from within this function. Invocation
|
||||||
* of the handler will be performed in a manner equivalent to using
|
* of the handler will be performed in a manner equivalent to using
|
||||||
* asio::io_service::post().
|
* asio::io_service::post().
|
||||||
*/
|
*/
|
||||||
template <typename Handler>
|
template <typename WaitHandler>
|
||||||
void async_wait(Handler handler)
|
void async_wait(WaitHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_wait(this->implementation, handler);
|
this->service.async_wait(this->implementation, handler);
|
||||||
}
|
}
|
||||||
@ -281,7 +371,7 @@ public:
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* void on_timeout(const asio::error& e)
|
* void on_timeout(const asio::error_code& e)
|
||||||
* {
|
* {
|
||||||
* if (e != asio::error::operation_aborted)
|
* if (e != asio::error::operation_aborted)
|
||||||
* {
|
* {
|
||||||
@ -296,8 +386,8 @@ public:
|
|||||||
* late and the wait handler has already been executed, or will soon be
|
* late and the wait handler has already been executed, or will soon be
|
||||||
* executed. If it returns 1 then the wait handler was successfully cancelled.
|
* executed. If it returns 1 then the wait handler was successfully cancelled.
|
||||||
*
|
*
|
||||||
* @li If a wait handler is cancelled, the asio::error passed to it
|
* @li If a wait handler is cancelled, the asio::error_code passed to
|
||||||
* contains the value asio::error::operation_aborted.
|
* it contains the value asio::error::operation_aborted.
|
||||||
*
|
*
|
||||||
* @sa asio::basic_deadline_timer
|
* @sa asio::basic_deadline_timer
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// basic_io_object.hpp
|
// basic_io_object.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -23,13 +23,13 @@
|
|||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
/// Base class for all I/O objects.
|
/// Base class for all I/O objects.
|
||||||
template <typename Service>
|
template <typename IoObjectService>
|
||||||
class basic_io_object
|
class basic_io_object
|
||||||
: private noncopyable
|
: private noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The type of the service that will be used to provide I/O operations.
|
/// The type of the service that will be used to provide I/O operations.
|
||||||
typedef Service service_type;
|
typedef IoObjectService service_type;
|
||||||
|
|
||||||
/// The underlying implementation type of I/O object.
|
/// The underlying implementation type of I/O object.
|
||||||
typedef typename service_type::implementation_type implementation_type;
|
typedef typename service_type::implementation_type implementation_type;
|
||||||
@ -50,7 +50,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
/// Construct a basic_io_object.
|
/// Construct a basic_io_object.
|
||||||
explicit basic_io_object(asio::io_service& io_service)
|
explicit basic_io_object(asio::io_service& io_service)
|
||||||
: service(asio::use_service<Service>(io_service))
|
: service(asio::use_service<IoObjectService>(io_service))
|
||||||
{
|
{
|
||||||
service.construct(implementation);
|
service.construct(implementation);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// basic_socket.hpp
|
// basic_socket.hpp
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
#include "asio/basic_io_object.hpp"
|
#include "asio/basic_io_object.hpp"
|
||||||
#include "asio/error.hpp"
|
#include "asio/error.hpp"
|
||||||
#include "asio/error_handler.hpp"
|
|
||||||
#include "asio/socket_base.hpp"
|
#include "asio/socket_base.hpp"
|
||||||
|
#include "asio/detail/throw_error.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
@ -29,21 +29,18 @@ namespace asio {
|
|||||||
* The basic_socket class template provides functionality that is common to both
|
* The basic_socket class template provides functionality that is common to both
|
||||||
* stream-oriented and datagram-oriented sockets.
|
* stream-oriented and datagram-oriented sockets.
|
||||||
*
|
*
|
||||||
* @par Thread Safety:
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
|
||||||
* @par Concepts:
|
|
||||||
* Error_Source, IO_Object.
|
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Service>
|
template <typename Protocol, typename SocketService>
|
||||||
class basic_socket
|
class basic_socket
|
||||||
: public basic_io_object<Service>,
|
: public basic_io_object<SocketService>,
|
||||||
public socket_base
|
public socket_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The native representation of a socket.
|
/// The native representation of a socket.
|
||||||
typedef typename Service::native_type native_type;
|
typedef typename SocketService::native_type native_type;
|
||||||
|
|
||||||
/// The protocol type.
|
/// The protocol type.
|
||||||
typedef Protocol protocol_type;
|
typedef Protocol protocol_type;
|
||||||
@ -51,11 +48,8 @@ public:
|
|||||||
/// The endpoint type.
|
/// The endpoint type.
|
||||||
typedef typename Protocol::endpoint endpoint_type;
|
typedef typename Protocol::endpoint endpoint_type;
|
||||||
|
|
||||||
/// The type used for reporting errors.
|
|
||||||
typedef asio::error error_type;
|
|
||||||
|
|
||||||
/// A basic_socket is always the lowest layer.
|
/// A basic_socket is always the lowest layer.
|
||||||
typedef basic_socket<Protocol, Service> lowest_layer_type;
|
typedef basic_socket<Protocol, SocketService> lowest_layer_type;
|
||||||
|
|
||||||
/// Construct a basic_socket without opening it.
|
/// Construct a basic_socket without opening it.
|
||||||
/**
|
/**
|
||||||
@ -65,7 +59,7 @@ public:
|
|||||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||||
*/
|
*/
|
||||||
explicit basic_socket(asio::io_service& io_service)
|
explicit basic_socket(asio::io_service& io_service)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<SocketService>(io_service)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,13 +72,15 @@ public:
|
|||||||
*
|
*
|
||||||
* @param protocol An object specifying protocol parameters to be used.
|
* @param protocol An object specifying protocol parameters to be used.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_socket(asio::io_service& io_service,
|
basic_socket(asio::io_service& io_service,
|
||||||
const protocol_type& protocol)
|
const protocol_type& protocol)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<SocketService>(io_service)
|
||||||
{
|
{
|
||||||
this->service.open(this->implementation, protocol, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.open(this->implementation, protocol, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a basic_socket, opening it and binding it to the given local
|
/// Construct a basic_socket, opening it and binding it to the given local
|
||||||
@ -100,15 +96,17 @@ public:
|
|||||||
* @param endpoint An endpoint on the local machine to which the socket will
|
* @param endpoint An endpoint on the local machine to which the socket will
|
||||||
* be bound.
|
* be bound.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_socket(asio::io_service& io_service,
|
basic_socket(asio::io_service& io_service,
|
||||||
const endpoint_type& endpoint)
|
const endpoint_type& endpoint)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<SocketService>(io_service)
|
||||||
{
|
{
|
||||||
this->service.open(this->implementation, endpoint.protocol(),
|
asio::error_code ec;
|
||||||
throw_error());
|
this->service.open(this->implementation, endpoint.protocol(), ec);
|
||||||
this->service.bind(this->implementation, endpoint, throw_error());
|
asio::detail::throw_error(ec);
|
||||||
|
this->service.bind(this->implementation, endpoint, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a basic_socket on an existing native socket.
|
/// Construct a basic_socket on an existing native socket.
|
||||||
@ -122,14 +120,15 @@ public:
|
|||||||
*
|
*
|
||||||
* @param native_socket A native socket.
|
* @param native_socket A native socket.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_socket(asio::io_service& io_service,
|
basic_socket(asio::io_service& io_service,
|
||||||
const protocol_type& protocol, const native_type& native_socket)
|
const protocol_type& protocol, const native_type& native_socket)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<SocketService>(io_service)
|
||||||
{
|
{
|
||||||
this->service.assign(this->implementation, protocol, native_socket,
|
asio::error_code ec;
|
||||||
throw_error());
|
this->service.assign(this->implementation, protocol, native_socket, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference to the lowest layer.
|
/// Get a reference to the lowest layer.
|
||||||
@ -152,9 +151,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param protocol An object specifying protocol parameters to be used.
|
* @param protocol An object specifying protocol parameters to be used.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* socket.open(asio::ip::tcp::v4());
|
* socket.open(asio::ip::tcp::v4());
|
||||||
@ -162,7 +161,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void open(const protocol_type& protocol = protocol_type())
|
void open(const protocol_type& protocol = protocol_type())
|
||||||
{
|
{
|
||||||
this->service.open(this->implementation, protocol, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.open(this->implementation, protocol, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Open the socket using the specified protocol.
|
/// Open the socket using the specified protocol.
|
||||||
@ -171,28 +172,23 @@ public:
|
|||||||
*
|
*
|
||||||
* @param protocol An object specifying which protocol is to be used.
|
* @param protocol An object specifying which protocol is to be used.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* socket.open(asio::ip::tcp::v4(), asio::assign_error(error));
|
* socket.open(asio::ip::tcp::v4(), ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code open(const protocol_type& protocol,
|
||||||
void open(const protocol_type& protocol, Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.open(this->implementation, protocol, error_handler);
|
return this->service.open(this->implementation, protocol, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assign an existing native socket to the socket.
|
/// Assign an existing native socket to the socket.
|
||||||
@ -203,12 +199,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @param native_socket A native socket.
|
* @param native_socket A native socket.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
void assign(const protocol_type& protocol, const native_type& native_socket)
|
void assign(const protocol_type& protocol, const native_type& native_socket)
|
||||||
{
|
{
|
||||||
this->service.assign(this->implementation, protocol, native_socket,
|
asio::error_code ec;
|
||||||
throw_error());
|
this->service.assign(this->implementation, protocol, native_socket, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assign an existing native socket to the socket.
|
/// Assign an existing native socket to the socket.
|
||||||
@ -219,19 +216,19 @@ public:
|
|||||||
*
|
*
|
||||||
* @param native_socket A native socket.
|
* @param native_socket A native socket.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code assign(const protocol_type& protocol,
|
||||||
void assign(const protocol_type& protocol, const native_type& native_socket,
|
const native_type& native_socket, asio::error_code& ec)
|
||||||
Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
this->service.assign(this->implementation, protocol, native_socket,
|
return this->service.assign(this->implementation,
|
||||||
error_handler);
|
protocol, native_socket, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether the socket is open.
|
||||||
|
bool is_open() const
|
||||||
|
{
|
||||||
|
return this->service.is_open(this->implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close the socket.
|
/// Close the socket.
|
||||||
@ -240,11 +237,13 @@ public:
|
|||||||
* or connect operations will be cancelled immediately, and will complete
|
* or connect operations will be cancelled immediately, and will complete
|
||||||
* with the asio::error::operation_aborted error.
|
* with the asio::error::operation_aborted error.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
void close()
|
void close()
|
||||||
{
|
{
|
||||||
this->service.close(this->implementation, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.close(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close the socket.
|
/// Close the socket.
|
||||||
@ -253,29 +252,23 @@ public:
|
|||||||
* or connect operations will be cancelled immediately, and will complete
|
* or connect operations will be cancelled immediately, and will complete
|
||||||
* with the asio::error::operation_aborted error.
|
* with the asio::error::operation_aborted error.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* socket.close(asio::assign_error(error));
|
* socket.close(ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code close(asio::error_code& ec)
|
||||||
void close(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
this->service.close(this->implementation, error_handler);
|
return this->service.close(this->implementation, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the native socket representation.
|
/// Get the native socket representation.
|
||||||
@ -295,11 +288,13 @@ public:
|
|||||||
* operations to finish immediately, and the handlers for cancelled operations
|
* operations to finish immediately, and the handlers for cancelled operations
|
||||||
* will be passed the asio::error::operation_aborted error.
|
* will be passed the asio::error::operation_aborted error.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
void cancel()
|
void cancel()
|
||||||
{
|
{
|
||||||
this->service.cancel(this->implementation, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.cancel(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cancel all asynchronous operations associated with the socket.
|
/// Cancel all asynchronous operations associated with the socket.
|
||||||
@ -308,17 +303,77 @@ public:
|
|||||||
* operations to finish immediately, and the handlers for cancelled operations
|
* operations to finish immediately, and the handlers for cancelled operations
|
||||||
* will be passed the asio::error::operation_aborted error.
|
* will be passed the asio::error::operation_aborted error.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code cancel(asio::error_code& ec)
|
||||||
void cancel(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
this->service.cancel(this->implementation, error_handler);
|
return this->service.cancel(this->implementation, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether the socket is at the out-of-band data mark.
|
||||||
|
/**
|
||||||
|
* This function is used to check whether the socket input is currently
|
||||||
|
* positioned at the out-of-band data mark.
|
||||||
|
*
|
||||||
|
* @return A bool indicating whether the socket is at the out-of-band data
|
||||||
|
* mark.
|
||||||
|
*
|
||||||
|
* @throws asio::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
bool at_mark() const
|
||||||
|
{
|
||||||
|
asio::error_code ec;
|
||||||
|
bool b = this->service.at_mark(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether the socket is at the out-of-band data mark.
|
||||||
|
/**
|
||||||
|
* This function is used to check whether the socket input is currently
|
||||||
|
* positioned at the out-of-band data mark.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @return A bool indicating whether the socket is at the out-of-band data
|
||||||
|
* mark.
|
||||||
|
*/
|
||||||
|
bool at_mark(asio::error_code& ec) const
|
||||||
|
{
|
||||||
|
return this->service.at_mark(this->implementation, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine the number of bytes available for reading.
|
||||||
|
/**
|
||||||
|
* This function is used to determine the number of bytes that may be read
|
||||||
|
* without blocking.
|
||||||
|
*
|
||||||
|
* @return The number of bytes that may be read without blocking, or 0 if an
|
||||||
|
* error occurs.
|
||||||
|
*
|
||||||
|
* @throws asio::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
std::size_t available() const
|
||||||
|
{
|
||||||
|
asio::error_code ec;
|
||||||
|
std::size_t s = this->service.available(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine the number of bytes available for reading.
|
||||||
|
/**
|
||||||
|
* This function is used to determine the number of bytes that may be read
|
||||||
|
* without blocking.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @return The number of bytes that may be read without blocking, or 0 if an
|
||||||
|
* error occurs.
|
||||||
|
*/
|
||||||
|
std::size_t available(asio::error_code& ec) const
|
||||||
|
{
|
||||||
|
return this->service.available(this->implementation, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind the socket to the given local endpoint.
|
/// Bind the socket to the given local endpoint.
|
||||||
@ -329,9 +384,9 @@ public:
|
|||||||
* @param endpoint An endpoint on the local machine to which the socket will
|
* @param endpoint An endpoint on the local machine to which the socket will
|
||||||
* be bound.
|
* be bound.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* socket.open(asio::ip::tcp::v4());
|
* socket.open(asio::ip::tcp::v4());
|
||||||
@ -341,7 +396,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void bind(const endpoint_type& endpoint)
|
void bind(const endpoint_type& endpoint)
|
||||||
{
|
{
|
||||||
this->service.bind(this->implementation, endpoint, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.bind(this->implementation, endpoint, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind the socket to the given local endpoint.
|
/// Bind the socket to the given local endpoint.
|
||||||
@ -352,31 +409,25 @@ public:
|
|||||||
* @param endpoint An endpoint on the local machine to which the socket will
|
* @param endpoint An endpoint on the local machine to which the socket will
|
||||||
* be bound.
|
* be bound.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* socket.open(asio::ip::tcp::v4());
|
* socket.open(asio::ip::tcp::v4());
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* socket.bind(asio::ip::tcp::endpoint(
|
* socket.bind(asio::ip::tcp::endpoint(
|
||||||
* asio::ip::tcp::v4(), 12345),
|
* asio::ip::tcp::v4(), 12345), ec);
|
||||||
* asio::assign_error(error));
|
* if (ec)
|
||||||
* if (error)
|
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code bind(const endpoint_type& endpoint,
|
||||||
void bind(const endpoint_type& endpoint, Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.bind(this->implementation, endpoint, error_handler);
|
return this->service.bind(this->implementation, endpoint, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connect the socket to the specified endpoint.
|
/// Connect the socket to the specified endpoint.
|
||||||
@ -392,9 +443,9 @@ public:
|
|||||||
* @param peer_endpoint The remote endpoint to which the socket will be
|
* @param peer_endpoint The remote endpoint to which the socket will be
|
||||||
* connected.
|
* connected.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* asio::ip::tcp::endpoint endpoint(
|
* asio::ip::tcp::endpoint endpoint(
|
||||||
@ -404,7 +455,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
void connect(const endpoint_type& peer_endpoint)
|
void connect(const endpoint_type& peer_endpoint)
|
||||||
{
|
{
|
||||||
this->service.connect(this->implementation, peer_endpoint, throw_error());
|
asio::error_code ec;
|
||||||
|
if (!is_open())
|
||||||
|
{
|
||||||
|
this->service.open(this->implementation, peer_endpoint.protocol(), ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
}
|
||||||
|
this->service.connect(this->implementation, peer_endpoint, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connect the socket to the specified endpoint.
|
/// Connect the socket to the specified endpoint.
|
||||||
@ -420,30 +478,34 @@ public:
|
|||||||
* @param peer_endpoint The remote endpoint to which the socket will be
|
* @param peer_endpoint The remote endpoint to which the socket will be
|
||||||
* connected.
|
* connected.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* asio::ip::tcp::endpoint endpoint(
|
* asio::ip::tcp::endpoint endpoint(
|
||||||
* asio::ip::address::from_string("1.2.3.4"), 12345);
|
* asio::ip::address::from_string("1.2.3.4"), 12345);
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* socket.connect(endpoint, asio::assign_error(error));
|
* socket.connect(endpoint, ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code connect(const endpoint_type& peer_endpoint,
|
||||||
void connect(const endpoint_type& peer_endpoint, Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.connect(this->implementation, peer_endpoint, error_handler);
|
if (!is_open())
|
||||||
|
{
|
||||||
|
if (this->service.open(this->implementation,
|
||||||
|
peer_endpoint.protocol(), ec))
|
||||||
|
{
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->service.connect(this->implementation, peer_endpoint, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous connect.
|
/// Start an asynchronous connect.
|
||||||
@ -462,16 +524,16 @@ public:
|
|||||||
* completes. Copies will be made of the handler as required. The function
|
* completes. Copies will be made of the handler as required. The function
|
||||||
* signature of the handler must be:
|
* signature of the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error // Result of operation
|
* const asio::error_code& error // Result of operation
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
* not, the handler will not be invoked from within this function. Invocation
|
* not, the handler will not be invoked from within this function. Invocation
|
||||||
* of the handler will be performed in a manner equivalent to using
|
* of the handler will be performed in a manner equivalent to using
|
||||||
* asio::io_service::post().
|
* asio::io_service::post().
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* void connect_handler(const asio::error& error)
|
* void connect_handler(const asio::error_code& error)
|
||||||
* {
|
* {
|
||||||
* if (!error)
|
* if (!error)
|
||||||
* {
|
* {
|
||||||
@ -487,9 +549,20 @@ public:
|
|||||||
* socket.async_connect(endpoint, connect_handler);
|
* socket.async_connect(endpoint, connect_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Handler>
|
template <typename ConnectHandler>
|
||||||
void async_connect(const endpoint_type& peer_endpoint, Handler handler)
|
void async_connect(const endpoint_type& peer_endpoint, ConnectHandler handler)
|
||||||
{
|
{
|
||||||
|
if (!is_open())
|
||||||
|
{
|
||||||
|
asio::error_code ec;
|
||||||
|
if (this->service.open(this->implementation,
|
||||||
|
peer_endpoint.protocol(), ec))
|
||||||
|
{
|
||||||
|
this->io_service().post(asio::detail::bind_handler(handler, ec));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this->service.async_connect(this->implementation, peer_endpoint, handler);
|
this->service.async_connect(this->implementation, peer_endpoint, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,9 +572,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param option The new option value to be set on the socket.
|
* @param option The new option value to be set on the socket.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @sa Socket_Option @n
|
* @sa SettableSocketOption @n
|
||||||
* asio::socket_base::broadcast @n
|
* asio::socket_base::broadcast @n
|
||||||
* asio::socket_base::do_not_route @n
|
* asio::socket_base::do_not_route @n
|
||||||
* asio::socket_base::keep_alive @n
|
* asio::socket_base::keep_alive @n
|
||||||
@ -518,7 +591,7 @@ public:
|
|||||||
* asio::ip::multicast::hops @n
|
* asio::ip::multicast::hops @n
|
||||||
* asio::ip::tcp::no_delay
|
* asio::ip::tcp::no_delay
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Setting the IPPROTO_TCP/TCP_NODELAY option:
|
* Setting the IPPROTO_TCP/TCP_NODELAY option:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
@ -527,10 +600,12 @@ public:
|
|||||||
* socket.set_option(option);
|
* socket.set_option(option);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Option>
|
template <typename SettableSocketOption>
|
||||||
void set_option(const Socket_Option& option)
|
void set_option(const SettableSocketOption& option)
|
||||||
{
|
{
|
||||||
this->service.set_option(this->implementation, option, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.set_option(this->implementation, option, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set an option on the socket.
|
/// Set an option on the socket.
|
||||||
@ -539,14 +614,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param option The new option value to be set on the socket.
|
* @param option The new option value to be set on the socket.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @sa Socket_Option @n
|
* @sa SettableSocketOption @n
|
||||||
* asio::socket_base::broadcast @n
|
* asio::socket_base::broadcast @n
|
||||||
* asio::socket_base::do_not_route @n
|
* asio::socket_base::do_not_route @n
|
||||||
* asio::socket_base::keep_alive @n
|
* asio::socket_base::keep_alive @n
|
||||||
@ -563,24 +633,25 @@ public:
|
|||||||
* asio::ip::multicast::hops @n
|
* asio::ip::multicast::hops @n
|
||||||
* asio::ip::tcp::no_delay
|
* asio::ip::tcp::no_delay
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Setting the IPPROTO_TCP/TCP_NODELAY option:
|
* Setting the IPPROTO_TCP/TCP_NODELAY option:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::ip::tcp::no_delay option(true);
|
* asio::ip::tcp::no_delay option(true);
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* socket.set_option(option, asio::assign_error(error));
|
* socket.set_option(option, ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Option, typename Error_Handler>
|
template <typename SettableSocketOption>
|
||||||
void set_option(const Socket_Option& option, Error_Handler error_handler)
|
asio::error_code set_option(const SettableSocketOption& option,
|
||||||
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.set_option(this->implementation, option, error_handler);
|
return this->service.set_option(this->implementation, option, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an option from the socket.
|
/// Get an option from the socket.
|
||||||
@ -589,9 +660,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param option The option value to be obtained from the socket.
|
* @param option The option value to be obtained from the socket.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @sa Socket_Option @n
|
* @sa GettableSocketOption @n
|
||||||
* asio::socket_base::broadcast @n
|
* asio::socket_base::broadcast @n
|
||||||
* asio::socket_base::do_not_route @n
|
* asio::socket_base::do_not_route @n
|
||||||
* asio::socket_base::keep_alive @n
|
* asio::socket_base::keep_alive @n
|
||||||
@ -608,7 +679,7 @@ public:
|
|||||||
* asio::ip::multicast::hops @n
|
* asio::ip::multicast::hops @n
|
||||||
* asio::ip::tcp::no_delay
|
* asio::ip::tcp::no_delay
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
|
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
@ -618,10 +689,12 @@ public:
|
|||||||
* bool is_set = option.get();
|
* bool is_set = option.get();
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Option>
|
template <typename GettableSocketOption>
|
||||||
void get_option(Socket_Option& option) const
|
void get_option(GettableSocketOption& option) const
|
||||||
{
|
{
|
||||||
this->service.get_option(this->implementation, option, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.get_option(this->implementation, option, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an option from the socket.
|
/// Get an option from the socket.
|
||||||
@ -630,14 +703,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param option The option value to be obtained from the socket.
|
* @param option The option value to be obtained from the socket.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @sa Socket_Option @n
|
* @sa GettableSocketOption @n
|
||||||
* asio::socket_base::broadcast @n
|
* asio::socket_base::broadcast @n
|
||||||
* asio::socket_base::do_not_route @n
|
* asio::socket_base::do_not_route @n
|
||||||
* asio::socket_base::keep_alive @n
|
* asio::socket_base::keep_alive @n
|
||||||
@ -654,25 +722,26 @@ public:
|
|||||||
* asio::ip::multicast::hops @n
|
* asio::ip::multicast::hops @n
|
||||||
* asio::ip::tcp::no_delay
|
* asio::ip::tcp::no_delay
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
|
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::ip::tcp::socket::keep_alive option;
|
* asio::ip::tcp::socket::keep_alive option;
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* socket.get_option(option, asio::assign_error(error));
|
* socket.get_option(option, ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* bool is_set = option.get();
|
* bool is_set = option.get();
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Option, typename Error_Handler>
|
template <typename GettableSocketOption>
|
||||||
void get_option(Socket_Option& option, Error_Handler error_handler) const
|
asio::error_code get_option(GettableSocketOption& option,
|
||||||
|
asio::error_code& ec) const
|
||||||
{
|
{
|
||||||
this->service.get_option(this->implementation, option, error_handler);
|
return this->service.get_option(this->implementation, option, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an IO control command on the socket.
|
/// Perform an IO control command on the socket.
|
||||||
@ -681,13 +750,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @param command The IO control command to be performed on the socket.
|
* @param command The IO control command to be performed on the socket.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @sa IO_Control_Command @n
|
* @sa IoControlCommand @n
|
||||||
* asio::socket_base::bytes_readable @n
|
* asio::socket_base::bytes_readable @n
|
||||||
* asio::socket_base::non_blocking_io
|
* asio::socket_base::non_blocking_io
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Getting the number of bytes ready to read:
|
* Getting the number of bytes ready to read:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
@ -697,10 +766,12 @@ public:
|
|||||||
* std::size_t bytes_readable = command.get();
|
* std::size_t bytes_readable = command.get();
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename IO_Control_Command>
|
template <typename IoControlCommand>
|
||||||
void io_control(IO_Control_Command& command)
|
void io_control(IoControlCommand& command)
|
||||||
{
|
{
|
||||||
this->service.io_control(this->implementation, command, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.io_control(this->implementation, command, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an IO control command on the socket.
|
/// Perform an IO control command on the socket.
|
||||||
@ -709,36 +780,32 @@ public:
|
|||||||
*
|
*
|
||||||
* @param command The IO control command to be performed on the socket.
|
* @param command The IO control command to be performed on the socket.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @sa IO_Control_Command @n
|
* @sa IoControlCommand @n
|
||||||
* asio::socket_base::bytes_readable @n
|
* asio::socket_base::bytes_readable @n
|
||||||
* asio::socket_base::non_blocking_io
|
* asio::socket_base::non_blocking_io
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Getting the number of bytes ready to read:
|
* Getting the number of bytes ready to read:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::ip::tcp::socket::bytes_readable command;
|
* asio::ip::tcp::socket::bytes_readable command;
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* socket.io_control(command, asio::assign_error(error));
|
* socket.io_control(command, ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* std::size_t bytes_readable = command.get();
|
* std::size_t bytes_readable = command.get();
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename IO_Control_Command, typename Error_Handler>
|
template <typename IoControlCommand>
|
||||||
void io_control(IO_Control_Command& command, Error_Handler error_handler)
|
asio::error_code io_control(IoControlCommand& command,
|
||||||
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.io_control(this->implementation, command, error_handler);
|
return this->service.io_control(this->implementation, command, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the local endpoint of the socket.
|
/// Get the local endpoint of the socket.
|
||||||
@ -747,9 +814,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns An object that represents the local endpoint of the socket.
|
* @returns An object that represents the local endpoint of the socket.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* ...
|
* ...
|
||||||
@ -758,41 +825,36 @@ public:
|
|||||||
*/
|
*/
|
||||||
endpoint_type local_endpoint() const
|
endpoint_type local_endpoint() const
|
||||||
{
|
{
|
||||||
return this->service.local_endpoint(this->implementation, throw_error());
|
asio::error_code ec;
|
||||||
|
endpoint_type ep = this->service.local_endpoint(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the local endpoint of the socket.
|
/// Get the local endpoint of the socket.
|
||||||
/**
|
/**
|
||||||
* This function is used to obtain the locally bound endpoint of the socket.
|
* This function is used to obtain the locally bound endpoint of the socket.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns An object that represents the local endpoint of the socket.
|
* @returns An object that represents the local endpoint of the socket.
|
||||||
* Returns a default-constructed endpoint object if an error occurred and the
|
* Returns a default-constructed endpoint object if an error occurred.
|
||||||
* error handler did not throw an exception.
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* asio::ip::tcp::endpoint endpoint
|
* asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
|
||||||
* = socket.local_endpoint(asio::assign_error(error));
|
* if (ec)
|
||||||
* if (error)
|
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
endpoint_type local_endpoint(asio::error_code& ec) const
|
||||||
endpoint_type local_endpoint(Error_Handler error_handler) const
|
|
||||||
{
|
{
|
||||||
return this->service.local_endpoint(this->implementation, error_handler);
|
return this->service.local_endpoint(this->implementation, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the remote endpoint of the socket.
|
/// Get the remote endpoint of the socket.
|
||||||
@ -801,9 +863,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns An object that represents the remote endpoint of the socket.
|
* @returns An object that represents the remote endpoint of the socket.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* ...
|
* ...
|
||||||
@ -812,41 +874,36 @@ public:
|
|||||||
*/
|
*/
|
||||||
endpoint_type remote_endpoint() const
|
endpoint_type remote_endpoint() const
|
||||||
{
|
{
|
||||||
return this->service.remote_endpoint(this->implementation, throw_error());
|
asio::error_code ec;
|
||||||
|
endpoint_type ep = this->service.remote_endpoint(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the remote endpoint of the socket.
|
/// Get the remote endpoint of the socket.
|
||||||
/**
|
/**
|
||||||
* This function is used to obtain the remote endpoint of the socket.
|
* This function is used to obtain the remote endpoint of the socket.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns An object that represents the remote endpoint of the socket.
|
* @returns An object that represents the remote endpoint of the socket.
|
||||||
* Returns a default-constructed endpoint object if an error occurred and the
|
* Returns a default-constructed endpoint object if an error occurred.
|
||||||
* error handler did not throw an exception.
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* asio::ip::tcp::endpoint endpoint
|
* asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
|
||||||
* = socket.remote_endpoint(asio::assign_error(error));
|
* if (ec)
|
||||||
* if (error)
|
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
endpoint_type remote_endpoint(asio::error_code& ec) const
|
||||||
endpoint_type remote_endpoint(Error_Handler error_handler) const
|
|
||||||
{
|
{
|
||||||
return this->service.remote_endpoint(this->implementation, error_handler);
|
return this->service.remote_endpoint(this->implementation, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable sends or receives on the socket.
|
/// Disable sends or receives on the socket.
|
||||||
@ -856,9 +913,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param what Determines what types of operation will no longer be allowed.
|
* @param what Determines what types of operation will no longer be allowed.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Shutting down the send side of the socket:
|
* Shutting down the send side of the socket:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
@ -868,7 +925,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void shutdown(shutdown_type what)
|
void shutdown(shutdown_type what)
|
||||||
{
|
{
|
||||||
this->service.shutdown(this->implementation, what, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.shutdown(this->implementation, what, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable sends or receives on the socket.
|
/// Disable sends or receives on the socket.
|
||||||
@ -878,31 +937,25 @@ public:
|
|||||||
*
|
*
|
||||||
* @param what Determines what types of operation will no longer be allowed.
|
* @param what Determines what types of operation will no longer be allowed.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Shutting down the send side of the socket:
|
* Shutting down the send side of the socket:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* socket.shutdown(asio::ip::tcp::socket::shutdown_send,
|
* socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
|
||||||
* asio::assign_error(error));
|
* if (ec)
|
||||||
* if (error)
|
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code shutdown(shutdown_type what,
|
||||||
void shutdown(shutdown_type what, Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.shutdown(this->implementation, what, error_handler);
|
return this->service.shutdown(this->implementation, what, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// basic_socket_acceptor.hpp
|
// basic_socket_acceptor.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -20,9 +20,9 @@
|
|||||||
#include "asio/basic_io_object.hpp"
|
#include "asio/basic_io_object.hpp"
|
||||||
#include "asio/basic_socket.hpp"
|
#include "asio/basic_socket.hpp"
|
||||||
#include "asio/error.hpp"
|
#include "asio/error.hpp"
|
||||||
#include "asio/error_handler.hpp"
|
|
||||||
#include "asio/socket_acceptor_service.hpp"
|
#include "asio/socket_acceptor_service.hpp"
|
||||||
#include "asio/socket_base.hpp"
|
#include "asio/socket_base.hpp"
|
||||||
|
#include "asio/detail/throw_error.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
@ -31,14 +31,11 @@ namespace asio {
|
|||||||
* The basic_socket_acceptor class template is used for accepting new socket
|
* The basic_socket_acceptor class template is used for accepting new socket
|
||||||
* connections.
|
* connections.
|
||||||
*
|
*
|
||||||
* @par Thread Safety:
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
*
|
||||||
* @par Concepts:
|
* @par Example
|
||||||
* Async_Object, Error_Source.
|
|
||||||
*
|
|
||||||
* @par Example:
|
|
||||||
* Opening a socket acceptor with the SO_REUSEADDR option enabled:
|
* Opening a socket acceptor with the SO_REUSEADDR option enabled:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
@ -50,14 +47,14 @@ namespace asio {
|
|||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Protocol,
|
template <typename Protocol,
|
||||||
typename Service = socket_acceptor_service<Protocol> >
|
typename SocketAcceptorService = socket_acceptor_service<Protocol> >
|
||||||
class basic_socket_acceptor
|
class basic_socket_acceptor
|
||||||
: public basic_io_object<Service>,
|
: public basic_io_object<SocketAcceptorService>,
|
||||||
public socket_base
|
public socket_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The native representation of an acceptor.
|
/// The native representation of an acceptor.
|
||||||
typedef typename Service::native_type native_type;
|
typedef typename SocketAcceptorService::native_type native_type;
|
||||||
|
|
||||||
/// The protocol type.
|
/// The protocol type.
|
||||||
typedef Protocol protocol_type;
|
typedef Protocol protocol_type;
|
||||||
@ -65,9 +62,6 @@ public:
|
|||||||
/// The endpoint type.
|
/// The endpoint type.
|
||||||
typedef typename Protocol::endpoint endpoint_type;
|
typedef typename Protocol::endpoint endpoint_type;
|
||||||
|
|
||||||
/// The type used for reporting errors.
|
|
||||||
typedef asio::error error_type;
|
|
||||||
|
|
||||||
/// Construct an acceptor without opening it.
|
/// Construct an acceptor without opening it.
|
||||||
/**
|
/**
|
||||||
* This constructor creates an acceptor without opening it to listen for new
|
* This constructor creates an acceptor without opening it to listen for new
|
||||||
@ -79,7 +73,7 @@ public:
|
|||||||
* acceptor.
|
* acceptor.
|
||||||
*/
|
*/
|
||||||
explicit basic_socket_acceptor(asio::io_service& io_service)
|
explicit basic_socket_acceptor(asio::io_service& io_service)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<SocketAcceptorService>(io_service)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,13 +87,15 @@ public:
|
|||||||
*
|
*
|
||||||
* @param protocol An object specifying protocol parameters to be used.
|
* @param protocol An object specifying protocol parameters to be used.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_socket_acceptor(asio::io_service& io_service,
|
basic_socket_acceptor(asio::io_service& io_service,
|
||||||
const protocol_type& protocol)
|
const protocol_type& protocol)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<SocketAcceptorService>(io_service)
|
||||||
{
|
{
|
||||||
this->service.open(this->implementation, protocol, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.open(this->implementation, protocol, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct an acceptor opened on the given endpoint.
|
/// Construct an acceptor opened on the given endpoint.
|
||||||
@ -117,7 +113,7 @@ public:
|
|||||||
* @param reuse_addr Whether the constructor should set the socket option
|
* @param reuse_addr Whether the constructor should set the socket option
|
||||||
* socket_base::reuse_address.
|
* socket_base::reuse_address.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @note This constructor is equivalent to the following code:
|
* @note This constructor is equivalent to the following code:
|
||||||
* @code
|
* @code
|
||||||
@ -131,18 +127,22 @@ public:
|
|||||||
*/
|
*/
|
||||||
basic_socket_acceptor(asio::io_service& io_service,
|
basic_socket_acceptor(asio::io_service& io_service,
|
||||||
const endpoint_type& endpoint, bool reuse_addr = true)
|
const endpoint_type& endpoint, bool reuse_addr = true)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<SocketAcceptorService>(io_service)
|
||||||
{
|
{
|
||||||
this->service.open(this->implementation, endpoint.protocol(),
|
asio::error_code ec;
|
||||||
throw_error());
|
this->service.open(this->implementation, endpoint.protocol(), ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
if (reuse_addr)
|
if (reuse_addr)
|
||||||
{
|
{
|
||||||
this->service.set_option(this->implementation,
|
this->service.set_option(this->implementation,
|
||||||
socket_base::reuse_address(true), throw_error());
|
socket_base::reuse_address(true), ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
this->service.bind(this->implementation, endpoint, throw_error());
|
this->service.bind(this->implementation, endpoint, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
this->service.listen(this->implementation,
|
this->service.listen(this->implementation,
|
||||||
socket_base::max_connections, throw_error());
|
socket_base::max_connections, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a basic_socket_acceptor on an existing native acceptor.
|
/// Construct a basic_socket_acceptor on an existing native acceptor.
|
||||||
@ -158,14 +158,15 @@ public:
|
|||||||
*
|
*
|
||||||
* @param native_acceptor A native acceptor.
|
* @param native_acceptor A native acceptor.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_socket_acceptor(asio::io_service& io_service,
|
basic_socket_acceptor(asio::io_service& io_service,
|
||||||
const protocol_type& protocol, const native_type& native_acceptor)
|
const protocol_type& protocol, const native_type& native_acceptor)
|
||||||
: basic_io_object<Service>(io_service)
|
: basic_io_object<SocketAcceptorService>(io_service)
|
||||||
{
|
{
|
||||||
this->service.assign(this->implementation, protocol, native_acceptor,
|
asio::error_code ec;
|
||||||
throw_error());
|
this->service.assign(this->implementation, protocol, native_acceptor, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Open the acceptor using the specified protocol.
|
/// Open the acceptor using the specified protocol.
|
||||||
@ -175,7 +176,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param protocol An object specifying which protocol is to be used.
|
* @param protocol An object specifying which protocol is to be used.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @throws asio::system_error Thrown on failure.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* acceptor.open(asio::ip::tcp::v4());
|
* acceptor.open(asio::ip::tcp::v4());
|
||||||
@ -183,7 +186,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void open(const protocol_type& protocol = protocol_type())
|
void open(const protocol_type& protocol = protocol_type())
|
||||||
{
|
{
|
||||||
this->service.open(this->implementation, protocol, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.open(this->implementation, protocol, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Open the acceptor using the specified protocol.
|
/// Open the acceptor using the specified protocol.
|
||||||
@ -193,29 +198,23 @@ public:
|
|||||||
*
|
*
|
||||||
* @param protocol An object specifying which protocol is to be used.
|
* @param protocol An object specifying which protocol is to be used.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* acceptor.open(asio::ip::tcp::v4(),
|
* acceptor.open(asio::ip::tcp::v4(), ec);
|
||||||
* asio::assign_error(error));
|
* if (ec)
|
||||||
* if (error)
|
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code open(const protocol_type& protocol,
|
||||||
void open(const protocol_type& protocol, Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.open(this->implementation, protocol, error_handler);
|
return this->service.open(this->implementation, protocol, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assigns an existing native acceptor to the acceptor.
|
/// Assigns an existing native acceptor to the acceptor.
|
||||||
@ -226,12 +225,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @param native_acceptor A native acceptor.
|
* @param native_acceptor A native acceptor.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
void assign(const protocol_type& protocol, const native_type& native_acceptor)
|
void assign(const protocol_type& protocol, const native_type& native_acceptor)
|
||||||
{
|
{
|
||||||
this->service.assign(this->implementation, protocol, native_acceptor,
|
asio::error_code ec;
|
||||||
throw_error());
|
this->service.assign(this->implementation, protocol, native_acceptor, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assigns an existing native acceptor to the acceptor.
|
/// Assigns an existing native acceptor to the acceptor.
|
||||||
@ -242,19 +242,19 @@ public:
|
|||||||
*
|
*
|
||||||
* @param native_acceptor A native acceptor.
|
* @param native_acceptor A native acceptor.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code assign(const protocol_type& protocol,
|
||||||
void assign(const protocol_type& protocol, const native_type& native_acceptor,
|
const native_type& native_acceptor, asio::error_code& ec)
|
||||||
Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
this->service.assign(this->implementation, protocol, native_acceptor,
|
return this->service.assign(this->implementation,
|
||||||
error_handler);
|
protocol, native_acceptor, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether the acceptor is open.
|
||||||
|
bool is_open() const
|
||||||
|
{
|
||||||
|
return this->service.is_open(this->implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind the acceptor to the given local endpoint.
|
/// Bind the acceptor to the given local endpoint.
|
||||||
@ -265,9 +265,9 @@ public:
|
|||||||
* @param endpoint An endpoint on the local machine to which the socket
|
* @param endpoint An endpoint on the local machine to which the socket
|
||||||
* acceptor will be bound.
|
* acceptor will be bound.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* acceptor.open(asio::ip::tcp::v4());
|
* acceptor.open(asio::ip::tcp::v4());
|
||||||
@ -276,7 +276,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void bind(const endpoint_type& endpoint)
|
void bind(const endpoint_type& endpoint)
|
||||||
{
|
{
|
||||||
this->service.bind(this->implementation, endpoint, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.bind(this->implementation, endpoint, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind the acceptor to the given local endpoint.
|
/// Bind the acceptor to the given local endpoint.
|
||||||
@ -287,30 +289,24 @@ public:
|
|||||||
* @param endpoint An endpoint on the local machine to which the socket
|
* @param endpoint An endpoint on the local machine to which the socket
|
||||||
* acceptor will be bound.
|
* acceptor will be bound.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* acceptor.open(asio::ip::tcp::v4());
|
* acceptor.open(asio::ip::tcp::v4());
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* acceptor.bind(asio::ip::tcp::endpoint(12345),
|
* acceptor.bind(asio::ip::tcp::endpoint(12345), ec);
|
||||||
* asio::assign_error(error));
|
* if (ec)
|
||||||
* if (error)
|
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code bind(const endpoint_type& endpoint,
|
||||||
void bind(const endpoint_type& endpoint, Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.bind(this->implementation, endpoint, error_handler);
|
return this->service.bind(this->implementation, endpoint, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Place the acceptor into the state where it will listen for new
|
/// Place the acceptor into the state where it will listen for new
|
||||||
@ -320,10 +316,14 @@ public:
|
|||||||
* new connections.
|
* new connections.
|
||||||
*
|
*
|
||||||
* @param backlog The maximum length of the queue of pending connections.
|
* @param backlog The maximum length of the queue of pending connections.
|
||||||
|
*
|
||||||
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
void listen(int backlog = socket_base::max_connections)
|
void listen(int backlog = socket_base::max_connections)
|
||||||
{
|
{
|
||||||
this->service.listen(this->implementation, backlog, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.listen(this->implementation, backlog, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Place the acceptor into the state where it will listen for new
|
/// Place the acceptor into the state where it will listen for new
|
||||||
@ -334,30 +334,23 @@ public:
|
|||||||
*
|
*
|
||||||
* @param backlog The maximum length of the queue of pending connections.
|
* @param backlog The maximum length of the queue of pending connections.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* acceptor.listen(asio::socket_base::max_connections,
|
* acceptor.listen(asio::socket_base::max_connections, ec);
|
||||||
* asio::assign_error(error));
|
* if (ec)
|
||||||
* if (error)
|
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code listen(int backlog, asio::error_code& ec)
|
||||||
void listen(int backlog, Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
this->service.listen(this->implementation, backlog, error_handler);
|
return this->service.listen(this->implementation, backlog, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close the acceptor.
|
/// Close the acceptor.
|
||||||
@ -368,11 +361,13 @@ public:
|
|||||||
* A subsequent call to open() is required before the acceptor can again be
|
* A subsequent call to open() is required before the acceptor can again be
|
||||||
* used to again perform socket accept operations.
|
* used to again perform socket accept operations.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
void close()
|
void close()
|
||||||
{
|
{
|
||||||
this->service.close(this->implementation, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.close(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close the acceptor.
|
/// Close the acceptor.
|
||||||
@ -383,29 +378,23 @@ public:
|
|||||||
* A subsequent call to open() is required before the acceptor can again be
|
* A subsequent call to open() is required before the acceptor can again be
|
||||||
* used to again perform socket accept operations.
|
* used to again perform socket accept operations.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* acceptor.close(asio::assign_error(error));
|
* acceptor.close(ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code close(asio::error_code& ec)
|
||||||
void close(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
this->service.close(this->implementation, error_handler);
|
return this->service.close(this->implementation, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the native acceptor representation.
|
/// Get the native acceptor representation.
|
||||||
@ -425,11 +414,13 @@ public:
|
|||||||
* operations to finish immediately, and the handlers for cancelled operations
|
* operations to finish immediately, and the handlers for cancelled operations
|
||||||
* will be passed the asio::error::operation_aborted error.
|
* will be passed the asio::error::operation_aborted error.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
void cancel()
|
void cancel()
|
||||||
{
|
{
|
||||||
this->service.cancel(this->implementation, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.cancel(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cancel all asynchronous operations associated with the acceptor.
|
/// Cancel all asynchronous operations associated with the acceptor.
|
||||||
@ -438,17 +429,11 @@ public:
|
|||||||
* operations to finish immediately, and the handlers for cancelled operations
|
* operations to finish immediately, and the handlers for cancelled operations
|
||||||
* will be passed the asio::error::operation_aborted error.
|
* will be passed the asio::error::operation_aborted error.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
asio::error_code cancel(asio::error_code& ec)
|
||||||
void cancel(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
this->service.cancel(this->implementation, error_handler);
|
return this->service.cancel(this->implementation, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set an option on the acceptor.
|
/// Set an option on the acceptor.
|
||||||
@ -457,13 +442,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @param option The new option value to be set on the acceptor.
|
* @param option The new option value to be set on the acceptor.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @sa Socket_Option @n
|
* @sa SettableSocketOption @n
|
||||||
* asio::socket_base::reuse_address
|
* asio::socket_base::reuse_address
|
||||||
* asio::socket_base::enable_connection_aborted
|
* asio::socket_base::enable_connection_aborted
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Setting the SOL_SOCKET/SO_REUSEADDR option:
|
* Setting the SOL_SOCKET/SO_REUSEADDR option:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
@ -472,10 +457,12 @@ public:
|
|||||||
* acceptor.set_option(option);
|
* acceptor.set_option(option);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Option>
|
template <typename SettableSocketOption>
|
||||||
void set_option(const Option& option)
|
void set_option(const SettableSocketOption& option)
|
||||||
{
|
{
|
||||||
this->service.set_option(this->implementation, option, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.set_option(this->implementation, option, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set an option on the acceptor.
|
/// Set an option on the acceptor.
|
||||||
@ -484,35 +471,31 @@ public:
|
|||||||
*
|
*
|
||||||
* @param option The new option value to be set on the acceptor.
|
* @param option The new option value to be set on the acceptor.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @sa Socket_Option @n
|
* @sa SettableSocketOption @n
|
||||||
* asio::socket_base::reuse_address
|
* asio::socket_base::reuse_address
|
||||||
* asio::socket_base::enable_connection_aborted
|
* asio::socket_base::enable_connection_aborted
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Setting the SOL_SOCKET/SO_REUSEADDR option:
|
* Setting the SOL_SOCKET/SO_REUSEADDR option:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::ip::tcp::acceptor::reuse_address option(true);
|
* asio::ip::tcp::acceptor::reuse_address option(true);
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* acceptor.set_option(option, asio::assign_error(error));
|
* acceptor.set_option(option, ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Option, typename Error_Handler>
|
template <typename SettableSocketOption>
|
||||||
void set_option(const Option& option, Error_Handler error_handler)
|
asio::error_code set_option(const SettableSocketOption& option,
|
||||||
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.set_option(this->implementation, option, error_handler);
|
return this->service.set_option(this->implementation, option, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an option from the acceptor.
|
/// Get an option from the acceptor.
|
||||||
@ -522,12 +505,12 @@ public:
|
|||||||
*
|
*
|
||||||
* @param option The option value to be obtained from the acceptor.
|
* @param option The option value to be obtained from the acceptor.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @sa Socket_Option @n
|
* @sa GettableSocketOption @n
|
||||||
* asio::socket_base::reuse_address
|
* asio::socket_base::reuse_address
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
|
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
@ -537,10 +520,12 @@ public:
|
|||||||
* bool is_set = option.get();
|
* bool is_set = option.get();
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Option>
|
template <typename GettableSocketOption>
|
||||||
void get_option(Option& option)
|
void get_option(GettableSocketOption& option)
|
||||||
{
|
{
|
||||||
this->service.get_option(this->implementation, option, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.get_option(this->implementation, option, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an option from the acceptor.
|
/// Get an option from the acceptor.
|
||||||
@ -550,35 +535,31 @@ public:
|
|||||||
*
|
*
|
||||||
* @param option The option value to be obtained from the acceptor.
|
* @param option The option value to be obtained from the acceptor.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @sa Socket_Option @n
|
* @sa GettableSocketOption @n
|
||||||
* asio::socket_base::reuse_address
|
* asio::socket_base::reuse_address
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
|
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::ip::tcp::acceptor::reuse_address option;
|
* asio::ip::tcp::acceptor::reuse_address option;
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* acceptor.get_option(option, asio::assign_error(error));
|
* acceptor.get_option(option, ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* bool is_set = option.get();
|
* bool is_set = option.get();
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Option, typename Error_Handler>
|
template <typename GettableSocketOption>
|
||||||
void get_option(Option& option, Error_Handler error_handler)
|
asio::error_code get_option(GettableSocketOption& option,
|
||||||
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.get_option(this->implementation, option, error_handler);
|
return this->service.get_option(this->implementation, option, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the local endpoint of the acceptor.
|
/// Get the local endpoint of the acceptor.
|
||||||
@ -587,9 +568,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns An object that represents the local endpoint of the acceptor.
|
* @returns An object that represents the local endpoint of the acceptor.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
@ -598,41 +579,37 @@ public:
|
|||||||
*/
|
*/
|
||||||
endpoint_type local_endpoint() const
|
endpoint_type local_endpoint() const
|
||||||
{
|
{
|
||||||
return this->service.local_endpoint(this->implementation, throw_error());
|
asio::error_code ec;
|
||||||
|
endpoint_type ep = this->service.local_endpoint(this->implementation, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the local endpoint of the acceptor.
|
/// Get the local endpoint of the acceptor.
|
||||||
/**
|
/**
|
||||||
* This function is used to obtain the locally bound endpoint of the acceptor.
|
* This function is used to obtain the locally bound endpoint of the acceptor.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns An object that represents the local endpoint of the acceptor.
|
* @returns An object that represents the local endpoint of the acceptor.
|
||||||
* Returns a default-constructed endpoint object if an error occurred and the
|
* Returns a default-constructed endpoint object if an error occurred and the
|
||||||
* error handler did not throw an exception.
|
* error handler did not throw an exception.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* asio::ip::tcp::endpoint endpoint
|
* asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
|
||||||
* = acceptor.local_endpoint(asio::assign_error(error));
|
* if (ec)
|
||||||
* if (error)
|
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Error_Handler>
|
endpoint_type local_endpoint(asio::error_code& ec) const
|
||||||
endpoint_type local_endpoint(Error_Handler error_handler) const
|
|
||||||
{
|
{
|
||||||
return this->service.local_endpoint(this->implementation, error_handler);
|
return this->service.local_endpoint(this->implementation, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accept a new connection.
|
/// Accept a new connection.
|
||||||
@ -643,9 +620,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param peer The socket into which the new connection will be accepted.
|
* @param peer The socket into which the new connection will be accepted.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
@ -653,10 +630,12 @@ public:
|
|||||||
* acceptor.accept(socket);
|
* acceptor.accept(socket);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Service>
|
template <typename SocketService>
|
||||||
void accept(basic_socket<protocol_type, Socket_Service>& peer)
|
void accept(basic_socket<protocol_type, SocketService>& peer)
|
||||||
{
|
{
|
||||||
this->service.accept(this->implementation, peer, throw_error());
|
asio::error_code ec;
|
||||||
|
this->service.accept(this->implementation, peer, 0, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accept a new connection.
|
/// Accept a new connection.
|
||||||
@ -667,31 +646,27 @@ public:
|
|||||||
*
|
*
|
||||||
* @param peer The socket into which the new connection will be accepted.
|
* @param peer The socket into which the new connection will be accepted.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::ip::tcp::soocket socket(io_service);
|
* asio::ip::tcp::soocket socket(io_service);
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* acceptor.accept(socket, asio::assign_error(error));
|
* acceptor.accept(socket, ec);
|
||||||
* if (error)
|
* if (ec)
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Service, typename Error_Handler>
|
template <typename SocketService>
|
||||||
void accept(basic_socket<protocol_type, Socket_Service>& peer,
|
asio::error_code accept(
|
||||||
Error_Handler error_handler)
|
basic_socket<protocol_type, SocketService>& peer,
|
||||||
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.accept(this->implementation, peer, error_handler);
|
return this->service.accept(this->implementation, peer, 0, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous accept.
|
/// Start an asynchronous accept.
|
||||||
@ -707,16 +682,16 @@ public:
|
|||||||
* completes. Copies will be made of the handler as required. The function
|
* completes. Copies will be made of the handler as required. The function
|
||||||
* signature of the handler must be:
|
* signature of the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error // Result of operation
|
* const asio::error_code& error // Result of operation.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
* not, the handler will not be invoked from within this function. Invocation
|
* not, the handler will not be invoked from within this function. Invocation
|
||||||
* of the handler will be performed in a manner equivalent to using
|
* of the handler will be performed in a manner equivalent to using
|
||||||
* asio::io_service::post().
|
* asio::io_service::post().
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* void accept_handler(const asio::error& error)
|
* void accept_handler(const asio::error_code& error)
|
||||||
* {
|
* {
|
||||||
* if (!error)
|
* if (!error)
|
||||||
* {
|
* {
|
||||||
@ -732,11 +707,11 @@ public:
|
|||||||
* acceptor.async_accept(socket, accept_handler);
|
* acceptor.async_accept(socket, accept_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Service, typename Handler>
|
template <typename SocketService, typename AcceptHandler>
|
||||||
void async_accept(basic_socket<protocol_type, Socket_Service>& peer,
|
void async_accept(basic_socket<protocol_type, SocketService>& peer,
|
||||||
Handler handler)
|
AcceptHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_accept(this->implementation, peer, handler);
|
this->service.async_accept(this->implementation, peer, 0, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accept a new connection and obtain the endpoint of the peer
|
/// Accept a new connection and obtain the endpoint of the peer
|
||||||
@ -751,23 +726,24 @@ public:
|
|||||||
* @param peer_endpoint An endpoint object which will receive the endpoint of
|
* @param peer_endpoint An endpoint object which will receive the endpoint of
|
||||||
* the remote peer.
|
* the remote peer.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* asio::ip::tcp::endpoint endpoint;
|
* asio::ip::tcp::endpoint endpoint;
|
||||||
* acceptor.accept_endpoint(socket, endpoint);
|
* acceptor.accept(socket, endpoint);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Service>
|
template <typename SocketService>
|
||||||
void accept_endpoint(basic_socket<protocol_type, Socket_Service>& peer,
|
void accept(basic_socket<protocol_type, SocketService>& peer,
|
||||||
endpoint_type& peer_endpoint)
|
endpoint_type& peer_endpoint)
|
||||||
{
|
{
|
||||||
this->service.accept_endpoint(this->implementation, peer, peer_endpoint,
|
asio::error_code ec;
|
||||||
throw_error());
|
this->service.accept(this->implementation, peer, &peer_endpoint, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accept a new connection and obtain the endpoint of the peer
|
/// Accept a new connection and obtain the endpoint of the peer
|
||||||
@ -782,34 +758,28 @@ public:
|
|||||||
* @param peer_endpoint An endpoint object which will receive the endpoint of
|
* @param peer_endpoint An endpoint object which will receive the endpoint of
|
||||||
* the remote peer.
|
* the remote peer.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||||
* ...
|
* ...
|
||||||
* asio::ip::tcp::socket socket(io_service);
|
* asio::ip::tcp::socket socket(io_service);
|
||||||
* asio::ip::tcp::endpoint endpoint;
|
* asio::ip::tcp::endpoint endpoint;
|
||||||
* asio::error error;
|
* asio::error_code ec;
|
||||||
* acceptor.accept_endpoint(socket, endpoint,
|
* acceptor.accept(socket, endpoint, ec);
|
||||||
* asio::assign_error(error));
|
* if (ec)
|
||||||
* if (error)
|
|
||||||
* {
|
* {
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Service, typename Error_Handler>
|
template <typename SocketService>
|
||||||
void accept_endpoint(basic_socket<protocol_type, Socket_Service>& peer,
|
asio::error_code accept(
|
||||||
endpoint_type& peer_endpoint, Error_Handler error_handler)
|
basic_socket<protocol_type, SocketService>& peer,
|
||||||
|
endpoint_type& peer_endpoint, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
this->service.accept_endpoint(this->implementation, peer, peer_endpoint,
|
return this->service.accept(this->implementation, peer, &peer_endpoint, ec);
|
||||||
error_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous accept.
|
/// Start an asynchronous accept.
|
||||||
@ -831,19 +801,19 @@ public:
|
|||||||
* completes. Copies will be made of the handler as required. The function
|
* completes. Copies will be made of the handler as required. The function
|
||||||
* signature of the handler must be:
|
* signature of the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error // Result of operation
|
* const asio::error_code& error // Result of operation.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
* not, the handler will not be invoked from within this function. Invocation
|
* not, the handler will not be invoked from within this function. Invocation
|
||||||
* of the handler will be performed in a manner equivalent to using
|
* of the handler will be performed in a manner equivalent to using
|
||||||
* asio::io_service::post().
|
* asio::io_service::post().
|
||||||
*/
|
*/
|
||||||
template <typename Socket_Service, typename Handler>
|
template <typename SocketService, typename AcceptHandler>
|
||||||
void async_accept_endpoint(basic_socket<protocol_type, Socket_Service>& peer,
|
void async_accept(basic_socket<protocol_type, SocketService>& peer,
|
||||||
endpoint_type& peer_endpoint, Handler handler)
|
endpoint_type& peer_endpoint, AcceptHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_accept_endpoint(this->implementation, peer,
|
this->service.async_accept(this->implementation,
|
||||||
peer_endpoint, handler);
|
peer, &peer_endpoint, handler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// basic_socket_iostream.hpp
|
// basic_socket_iostream.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -33,74 +33,42 @@
|
|||||||
#endif // !defined(ASIO_SOCKET_IOSTREAM_MAX_ARITY)
|
#endif // !defined(ASIO_SOCKET_IOSTREAM_MAX_ARITY)
|
||||||
|
|
||||||
// A macro that should expand to:
|
// A macro that should expand to:
|
||||||
// template < typename T1, ..., typename Tn >
|
// template <typename T1, ..., typename Tn>
|
||||||
// explicit basic_socket_iostream( T1 x1, ..., Tn xn )
|
// explicit basic_socket_iostream(T1 x1, ..., Tn xn)
|
||||||
// : basic_iostream<char>(&this->boost::base_from_member<
|
// : basic_iostream<char>(&this->boost::base_from_member<
|
||||||
// basic_socket_streambuf<Protocol, Service> >::member)
|
// basic_socket_streambuf<Protocol, StreamSocketService> >::member)
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// rdbuf()->connect ( x1, ..., xn );
|
|
||||||
// }
|
|
||||||
// catch (asio::error&)
|
|
||||||
// {
|
// {
|
||||||
|
// if (rdbuf()->connect(x1, ..., xn) == 0)
|
||||||
// this->setstate(std::ios_base::failbit);
|
// this->setstate(std::ios_base::failbit);
|
||||||
// if (this->exceptions() & std::ios_base::failbit)
|
|
||||||
// throw;
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
// This macro should only persist within this file.
|
// This macro should only persist within this file.
|
||||||
|
|
||||||
#define ASIO_PRIVATE_CTR_DEF( z, n, data ) \
|
#define ASIO_PRIVATE_CTR_DEF(z, n, data) \
|
||||||
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
|
||||||
explicit basic_socket_iostream( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
|
explicit basic_socket_iostream(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
|
||||||
: std::basic_iostream<char>(&this->boost::base_from_member< \
|
: std::basic_iostream<char>(&this->boost::base_from_member< \
|
||||||
basic_socket_streambuf<Protocol, Service> >::member) \
|
basic_socket_streambuf<Protocol, StreamSocketService> >::member) \
|
||||||
{ \
|
|
||||||
try \
|
|
||||||
{ \
|
|
||||||
rdbuf()->connect( BOOST_PP_ENUM_PARAMS(n, x) ); \
|
|
||||||
} \
|
|
||||||
catch (asio::error&) \
|
|
||||||
{ \
|
{ \
|
||||||
|
if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \
|
||||||
this->setstate(std::ios_base::failbit); \
|
this->setstate(std::ios_base::failbit); \
|
||||||
if (this->exceptions() & std::ios_base::failbit) \
|
|
||||||
throw; \
|
|
||||||
} \
|
|
||||||
} \
|
} \
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
// A macro that should expand to:
|
// A macro that should expand to:
|
||||||
// template < typename T1, ..., typename Tn >
|
// template <typename T1, ..., typename Tn>
|
||||||
// void connect( T1 x1, ..., Tn xn )
|
// void connect(T1 x1, ..., Tn xn)
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// rdbuf()->connect ( x1, ..., xn );
|
|
||||||
// }
|
|
||||||
// catch (asio::error&)
|
|
||||||
// {
|
// {
|
||||||
|
// if (rdbuf()->connect(x1, ..., xn) == 0)
|
||||||
// this->setstate(std::ios_base::failbit);
|
// this->setstate(std::ios_base::failbit);
|
||||||
// if (this->exceptions() & std::ios_base::failbit)
|
|
||||||
// throw;
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
// This macro should only persist within this file.
|
// This macro should only persist within this file.
|
||||||
|
|
||||||
#define ASIO_PRIVATE_CONNECT_DEF( z, n, data ) \
|
#define ASIO_PRIVATE_CONNECT_DEF(z, n, data) \
|
||||||
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
|
||||||
void connect( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
|
void connect(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
|
||||||
{ \
|
|
||||||
try \
|
|
||||||
{ \
|
|
||||||
rdbuf()->connect( BOOST_PP_ENUM_PARAMS(n, x) ); \
|
|
||||||
} \
|
|
||||||
catch (asio::error&) \
|
|
||||||
{ \
|
{ \
|
||||||
|
if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \
|
||||||
this->setstate(std::ios_base::failbit); \
|
this->setstate(std::ios_base::failbit); \
|
||||||
if (this->exceptions() & std::ios_base::failbit) \
|
|
||||||
throw; \
|
|
||||||
} \
|
|
||||||
} \
|
} \
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
@ -108,16 +76,17 @@ namespace asio {
|
|||||||
|
|
||||||
/// Iostream interface for a socket.
|
/// Iostream interface for a socket.
|
||||||
template <typename Protocol,
|
template <typename Protocol,
|
||||||
typename Service = stream_socket_service<Protocol> >
|
typename StreamSocketService = stream_socket_service<Protocol> >
|
||||||
class basic_socket_iostream
|
class basic_socket_iostream
|
||||||
: public boost::base_from_member<basic_socket_streambuf<Protocol, Service> >,
|
: public boost::base_from_member<
|
||||||
|
basic_socket_streambuf<Protocol, StreamSocketService> >,
|
||||||
public std::basic_iostream<char>
|
public std::basic_iostream<char>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Construct a basic_socket_iostream without establishing a connection.
|
/// Construct a basic_socket_iostream without establishing a connection.
|
||||||
basic_socket_iostream()
|
basic_socket_iostream()
|
||||||
: std::basic_iostream<char>(&this->boost::base_from_member<
|
: std::basic_iostream<char>(&this->boost::base_from_member<
|
||||||
basic_socket_streambuf<Protocol, Service> >::member)
|
basic_socket_streambuf<Protocol, StreamSocketService> >::member)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,15 +123,16 @@ public:
|
|||||||
/// Close the connection.
|
/// Close the connection.
|
||||||
void close()
|
void close()
|
||||||
{
|
{
|
||||||
rdbuf()->close();
|
if (rdbuf()->close() == 0)
|
||||||
|
this->setstate(std::ios_base::failbit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a pointer to the underlying streambuf.
|
/// Return a pointer to the underlying streambuf.
|
||||||
basic_socket_streambuf<Protocol, Service>* rdbuf() const
|
basic_socket_streambuf<Protocol, StreamSocketService>* rdbuf() const
|
||||||
{
|
{
|
||||||
return const_cast<basic_socket_streambuf<Protocol, Service>*>(
|
return const_cast<basic_socket_streambuf<Protocol, StreamSocketService>*>(
|
||||||
&this->boost::base_from_member<
|
&this->boost::base_from_member<
|
||||||
basic_socket_streambuf<Protocol, Service> >::member);
|
basic_socket_streambuf<Protocol, StreamSocketService> >::member);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// basic_socket_streambuf.hpp
|
// basic_socket_streambuf.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -28,61 +28,41 @@
|
|||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/basic_socket.hpp"
|
#include "asio/basic_socket.hpp"
|
||||||
#include "asio/error_handler.hpp"
|
|
||||||
#include "asio/io_service.hpp"
|
#include "asio/io_service.hpp"
|
||||||
#include "asio/stream_socket_service.hpp"
|
#include "asio/stream_socket_service.hpp"
|
||||||
|
#include "asio/detail/throw_error.hpp"
|
||||||
|
|
||||||
#if !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY)
|
#if !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY)
|
||||||
#define ASIO_SOCKET_STREAMBUF_MAX_ARITY 5
|
#define ASIO_SOCKET_STREAMBUF_MAX_ARITY 5
|
||||||
#endif // !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY)
|
#endif // !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY)
|
||||||
|
|
||||||
// A macro that should expand to:
|
// A macro that should expand to:
|
||||||
// template < typename T1, ..., typename Tn >
|
// template <typename T1, ..., typename Tn>
|
||||||
// explicit basic_socket_streambuf( T1 x1, ..., Tn xn )
|
// basic_socket_streambuf<Protocol, StreamSocketService>* connect(
|
||||||
// : basic_socket<Protocol, Service>(
|
// T1 x1, ..., Tn xn)
|
||||||
// boost::base_from_member<io_service>::member)
|
|
||||||
// {
|
// {
|
||||||
// init_buffers();
|
// init_buffers();
|
||||||
|
// asio::error_code ec;
|
||||||
|
// this->basic_socket<Protocol, StreamSocketService>::close(ec);
|
||||||
// typedef typename Protocol::resolver_query resolver_query;
|
// typedef typename Protocol::resolver_query resolver_query;
|
||||||
// resolver_query query( x1, ..., xn );
|
// resolver_query query(x1, ..., xn);
|
||||||
// resolve_and_connect(query);
|
// resolve_and_connect(query, ec);
|
||||||
// }
|
// return !ec ? this : 0;
|
||||||
// This macro should only persist within this file.
|
|
||||||
|
|
||||||
#define ASIO_PRIVATE_CTR_DEF( z, n, data ) \
|
|
||||||
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
|
||||||
explicit basic_socket_streambuf( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
|
|
||||||
: basic_socket<Protocol, Service>( \
|
|
||||||
boost::base_from_member<io_service>::member) \
|
|
||||||
{ \
|
|
||||||
init_buffers(); \
|
|
||||||
typedef typename Protocol::resolver_query resolver_query; \
|
|
||||||
resolver_query query( BOOST_PP_ENUM_PARAMS(n, x) ); \
|
|
||||||
resolve_and_connect(query); \
|
|
||||||
} \
|
|
||||||
/**/
|
|
||||||
|
|
||||||
// A macro that should expand to:
|
|
||||||
// template < typename T1, ..., typename Tn >
|
|
||||||
// void connect( T1 x1, ..., Tn xn )
|
|
||||||
// {
|
|
||||||
// this->basic_socket<Protocol, Service>::close();
|
|
||||||
// init_buffers();
|
|
||||||
// typedef typename Protocol::resolver_query resolver_query;
|
|
||||||
// resolver_query query( x1, ..., xn );
|
|
||||||
// resolve_and_connect(query);
|
|
||||||
// }
|
// }
|
||||||
// This macro should only persist within this file.
|
// This macro should only persist within this file.
|
||||||
|
|
||||||
#define ASIO_PRIVATE_CONNECT_DEF( z, n, data ) \
|
#define ASIO_PRIVATE_CONNECT_DEF( z, n, data ) \
|
||||||
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
|
||||||
void connect( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
|
basic_socket_streambuf<Protocol, StreamSocketService>* connect( \
|
||||||
|
BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
|
||||||
{ \
|
{ \
|
||||||
this->basic_socket<Protocol, Service>::close(); \
|
|
||||||
init_buffers(); \
|
init_buffers(); \
|
||||||
|
asio::error_code ec; \
|
||||||
|
this->basic_socket<Protocol, StreamSocketService>::close(ec); \
|
||||||
typedef typename Protocol::resolver_query resolver_query; \
|
typedef typename Protocol::resolver_query resolver_query; \
|
||||||
resolver_query query( BOOST_PP_ENUM_PARAMS(n, x) ); \
|
resolver_query query(BOOST_PP_ENUM_PARAMS(n, x)); \
|
||||||
resolve_and_connect(query); \
|
resolve_and_connect(query, ec); \
|
||||||
|
return !ec ? this : 0; \
|
||||||
} \
|
} \
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
@ -90,11 +70,11 @@ namespace asio {
|
|||||||
|
|
||||||
/// Iostream streambuf for a socket.
|
/// Iostream streambuf for a socket.
|
||||||
template <typename Protocol,
|
template <typename Protocol,
|
||||||
typename Service = stream_socket_service<Protocol> >
|
typename StreamSocketService = stream_socket_service<Protocol> >
|
||||||
class basic_socket_streambuf
|
class basic_socket_streambuf
|
||||||
: public std::streambuf,
|
: public std::streambuf,
|
||||||
private boost::base_from_member<io_service>,
|
private boost::base_from_member<io_service>,
|
||||||
public basic_socket<Protocol, Service>
|
public basic_socket<Protocol, StreamSocketService>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The endpoint type.
|
/// The endpoint type.
|
||||||
@ -102,59 +82,50 @@ public:
|
|||||||
|
|
||||||
/// Construct a basic_socket_streambuf without establishing a connection.
|
/// Construct a basic_socket_streambuf without establishing a connection.
|
||||||
basic_socket_streambuf()
|
basic_socket_streambuf()
|
||||||
: basic_socket<Protocol, Service>(
|
: basic_socket<Protocol, StreamSocketService>(
|
||||||
boost::base_from_member<asio::io_service>::member)
|
boost::base_from_member<asio::io_service>::member),
|
||||||
|
unbuffered_(false)
|
||||||
{
|
{
|
||||||
init_buffers();
|
init_buffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Establish a connection to the specified endpoint.
|
|
||||||
explicit basic_socket_streambuf(const endpoint_type& endpoint)
|
|
||||||
: basic_socket<Protocol, Service>(
|
|
||||||
boost::base_from_member<asio::io_service>::member)
|
|
||||||
{
|
|
||||||
init_buffers();
|
|
||||||
this->basic_socket<Protocol, Service>::connect(endpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(GENERATING_DOCUMENTATION)
|
|
||||||
/// Establish a connection to an endpoint corresponding to a resolver query.
|
|
||||||
/**
|
|
||||||
* This constructor automatically establishes a connection based on the
|
|
||||||
* supplied resolver query parameters. The arguments are used to construct
|
|
||||||
* a resolver query object.
|
|
||||||
*/
|
|
||||||
template <typename T1, ..., typename TN>
|
|
||||||
explicit basic_socket_streambuf(T1 t1, ..., TN tn);
|
|
||||||
#else
|
|
||||||
BOOST_PP_REPEAT_FROM_TO(
|
|
||||||
1, BOOST_PP_INC(ASIO_SOCKET_STREAMBUF_MAX_ARITY),
|
|
||||||
ASIO_PRIVATE_CTR_DEF, _ )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Destructor flushes buffered data.
|
/// Destructor flushes buffered data.
|
||||||
~basic_socket_streambuf()
|
virtual ~basic_socket_streambuf()
|
||||||
{
|
{
|
||||||
sync();
|
if (pptr() != pbase())
|
||||||
|
overflow(traits_type::eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Establish a connection to the specified endpoint.
|
/// Establish a connection.
|
||||||
void connect(const endpoint_type& endpoint)
|
/**
|
||||||
|
* This function establishes a connection to the specified endpoint.
|
||||||
|
*
|
||||||
|
* @return \c this if a connection was successfully established, a null
|
||||||
|
* pointer otherwise.
|
||||||
|
*/
|
||||||
|
basic_socket_streambuf<Protocol, StreamSocketService>* connect(
|
||||||
|
const endpoint_type& endpoint)
|
||||||
{
|
{
|
||||||
this->basic_socket<Protocol, Service>::close();
|
|
||||||
init_buffers();
|
init_buffers();
|
||||||
this->basic_socket<Protocol, Service>::connect(endpoint);
|
asio::error_code ec;
|
||||||
|
this->basic_socket<Protocol, StreamSocketService>::close(ec);
|
||||||
|
this->basic_socket<Protocol, StreamSocketService>::connect(endpoint, ec);
|
||||||
|
return !ec ? this : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(GENERATING_DOCUMENTATION)
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
/// Establish a connection to an endpoint corresponding to a resolver query.
|
/// Establish a connection.
|
||||||
/**
|
/**
|
||||||
* This function automatically establishes a connection based on the supplied
|
* This function automatically establishes a connection based on the supplied
|
||||||
* resolver query parameters. The arguments are used to construct a resolver
|
* resolver query parameters. The arguments are used to construct a resolver
|
||||||
* query object.
|
* query object.
|
||||||
|
*
|
||||||
|
* @return \c this if a connection was successfully established, a null
|
||||||
|
* pointer otherwise.
|
||||||
*/
|
*/
|
||||||
template <typename T1, ..., typename TN>
|
template <typename T1, ..., typename TN>
|
||||||
void connect(T1 t1, ..., TN tn);
|
basic_socket_streambuf<Protocol, StreamSocketService>* connect(
|
||||||
|
T1 t1, ..., TN tn);
|
||||||
#else
|
#else
|
||||||
BOOST_PP_REPEAT_FROM_TO(
|
BOOST_PP_REPEAT_FROM_TO(
|
||||||
1, BOOST_PP_INC(ASIO_SOCKET_STREAMBUF_MAX_ARITY),
|
1, BOOST_PP_INC(ASIO_SOCKET_STREAMBUF_MAX_ARITY),
|
||||||
@ -162,11 +133,18 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Close the connection.
|
/// Close the connection.
|
||||||
void close()
|
/**
|
||||||
|
* @return \c this if a connection was successfully established, a null
|
||||||
|
* pointer otherwise.
|
||||||
|
*/
|
||||||
|
basic_socket_streambuf<Protocol, StreamSocketService>* close()
|
||||||
{
|
{
|
||||||
|
asio::error_code ec;
|
||||||
sync();
|
sync();
|
||||||
this->basic_socket<Protocol, Service>::close();
|
this->basic_socket<Protocol, StreamSocketService>::close(ec);
|
||||||
|
if (!ec)
|
||||||
init_buffers();
|
init_buffers();
|
||||||
|
return !ec ? this : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -174,17 +152,13 @@ protected:
|
|||||||
{
|
{
|
||||||
if (gptr() == egptr())
|
if (gptr() == egptr())
|
||||||
{
|
{
|
||||||
asio::error error;
|
asio::error_code ec;
|
||||||
std::size_t bytes_transferred = this->service.receive(
|
std::size_t bytes_transferred = this->service.receive(
|
||||||
this->implementation,
|
this->implementation,
|
||||||
asio::buffer(asio::buffer(get_buffer_) + putback_max),
|
asio::buffer(asio::buffer(get_buffer_) + putback_max),
|
||||||
0, asio::assign_error(error));
|
0, ec);
|
||||||
if (error)
|
if (ec)
|
||||||
{
|
|
||||||
if (error != asio::error::eof)
|
|
||||||
throw error;
|
|
||||||
return traits_type::eof();
|
return traits_type::eof();
|
||||||
}
|
|
||||||
setg(get_buffer_.begin(), get_buffer_.begin() + putback_max,
|
setg(get_buffer_.begin(), get_buffer_.begin() + putback_max,
|
||||||
get_buffer_.begin() + putback_max + bytes_transferred);
|
get_buffer_.begin() + putback_max + bytes_transferred);
|
||||||
return traits_type::to_int_type(*gptr());
|
return traits_type::to_int_type(*gptr());
|
||||||
@ -197,42 +171,67 @@ protected:
|
|||||||
|
|
||||||
int_type overflow(int_type c)
|
int_type overflow(int_type c)
|
||||||
{
|
{
|
||||||
if (!traits_type::eq_int_type(c, traits_type::eof()))
|
if (unbuffered_)
|
||||||
{
|
{
|
||||||
if (pptr() == epptr())
|
if (traits_type::eq_int_type(c, traits_type::eof()))
|
||||||
{
|
{
|
||||||
|
// Nothing to do.
|
||||||
|
return traits_type::not_eof(c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Send the single character immediately.
|
||||||
|
asio::error_code ec;
|
||||||
|
char_type ch = traits_type::to_char_type(c);
|
||||||
|
this->service.send(this->implementation,
|
||||||
|
asio::buffer(&ch, sizeof(char_type)), 0, ec);
|
||||||
|
if (ec)
|
||||||
|
return traits_type::eof();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Send all data in the output buffer.
|
||||||
asio::const_buffer buffer =
|
asio::const_buffer buffer =
|
||||||
asio::buffer(pbase(), pptr() - pbase());
|
asio::buffer(pbase(), pptr() - pbase());
|
||||||
while (asio::buffer_size(buffer) > 0)
|
while (asio::buffer_size(buffer) > 0)
|
||||||
{
|
{
|
||||||
|
asio::error_code ec;
|
||||||
std::size_t bytes_transferred = this->service.send(
|
std::size_t bytes_transferred = this->service.send(
|
||||||
this->implementation, asio::buffer(buffer),
|
this->implementation, asio::buffer(buffer),
|
||||||
0, asio::throw_error());
|
0, ec);
|
||||||
|
if (ec)
|
||||||
|
return traits_type::eof();
|
||||||
buffer = buffer + bytes_transferred;
|
buffer = buffer + bytes_transferred;
|
||||||
}
|
}
|
||||||
setp(put_buffer_.begin(), put_buffer_.end());
|
setp(put_buffer_.begin(), put_buffer_.end());
|
||||||
}
|
|
||||||
|
|
||||||
|
// If the new character is eof then our work here is done.
|
||||||
|
if (traits_type::eq_int_type(c, traits_type::eof()))
|
||||||
|
return traits_type::not_eof(c);
|
||||||
|
|
||||||
|
// Add the new character to the output buffer.
|
||||||
*pptr() = traits_type::to_char_type(c);
|
*pptr() = traits_type::to_char_type(c);
|
||||||
pbump(1);
|
pbump(1);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
return traits_type::not_eof(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sync()
|
int sync()
|
||||||
{
|
{
|
||||||
asio::const_buffer buffer =
|
return overflow(traits_type::eof());
|
||||||
asio::buffer(pbase(), pptr() - pbase());
|
|
||||||
while (asio::buffer_size(buffer) > 0)
|
|
||||||
{
|
|
||||||
std::size_t bytes_transferred = this->service.send(
|
|
||||||
this->implementation, asio::buffer(buffer),
|
|
||||||
0, asio::throw_error());
|
|
||||||
buffer = buffer + bytes_transferred;
|
|
||||||
}
|
}
|
||||||
setp(put_buffer_.begin(), put_buffer_.end());
|
|
||||||
|
std::streambuf* setbuf(char_type* s, std::streamsize n)
|
||||||
|
{
|
||||||
|
if (pptr() == pbase() && s == 0 && n == 0)
|
||||||
|
{
|
||||||
|
unbuffered_ = true;
|
||||||
|
setp(0, 0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,37 +241,42 @@ private:
|
|||||||
setg(get_buffer_.begin(),
|
setg(get_buffer_.begin(),
|
||||||
get_buffer_.begin() + putback_max,
|
get_buffer_.begin() + putback_max,
|
||||||
get_buffer_.begin() + putback_max);
|
get_buffer_.begin() + putback_max);
|
||||||
|
if (unbuffered_)
|
||||||
|
setp(0, 0);
|
||||||
|
else
|
||||||
setp(put_buffer_.begin(), put_buffer_.end());
|
setp(put_buffer_.begin(), put_buffer_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void resolve_and_connect(const typename Protocol::resolver_query& query)
|
void resolve_and_connect(const typename Protocol::resolver_query& query,
|
||||||
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
typedef typename Protocol::resolver resolver_type;
|
typedef typename Protocol::resolver resolver_type;
|
||||||
typedef typename Protocol::resolver_iterator iterator_type;
|
typedef typename Protocol::resolver_iterator iterator_type;
|
||||||
resolver_type resolver(
|
resolver_type resolver(
|
||||||
boost::base_from_member<asio::io_service>::member);
|
boost::base_from_member<asio::io_service>::member);
|
||||||
iterator_type iterator = resolver.resolve(query);
|
iterator_type i = resolver.resolve(query, ec);
|
||||||
asio::error error(asio::error::host_not_found);
|
if (!ec)
|
||||||
while (error && iterator != iterator_type())
|
|
||||||
{
|
{
|
||||||
this->basic_socket<Protocol, Service>::close();
|
iterator_type end;
|
||||||
this->basic_socket<Protocol, Service>::connect(
|
ec = asio::error::host_not_found;
|
||||||
*iterator, asio::assign_error(error));
|
while (ec && i != end)
|
||||||
++iterator;
|
{
|
||||||
|
this->basic_socket<Protocol, StreamSocketService>::close();
|
||||||
|
this->basic_socket<Protocol, StreamSocketService>::connect(*i, ec);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (error)
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum { putback_max = 8 };
|
enum { putback_max = 8 };
|
||||||
enum { buffer_size = 512 };
|
enum { buffer_size = 512 };
|
||||||
boost::array<char, buffer_size> get_buffer_;
|
boost::array<char, buffer_size> get_buffer_;
|
||||||
boost::array<char, buffer_size> put_buffer_;
|
boost::array<char, buffer_size> put_buffer_;
|
||||||
|
bool unbuffered_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
||||||
#undef ASIO_PRIVATE_CTR_DEF
|
|
||||||
#undef ASIO_PRIVATE_CONNECT_DEF
|
#undef ASIO_PRIVATE_CONNECT_DEF
|
||||||
|
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// basic_stream_socket.hpp
|
// basic_stream_socket.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -23,8 +23,9 @@
|
|||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/basic_socket.hpp"
|
#include "asio/basic_socket.hpp"
|
||||||
#include "asio/error_handler.hpp"
|
#include "asio/error.hpp"
|
||||||
#include "asio/stream_socket_service.hpp"
|
#include "asio/stream_socket_service.hpp"
|
||||||
|
#include "asio/detail/throw_error.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
@ -33,22 +34,21 @@ namespace asio {
|
|||||||
* The basic_stream_socket class template provides asynchronous and blocking
|
* The basic_stream_socket class template provides asynchronous and blocking
|
||||||
* stream-oriented socket functionality.
|
* stream-oriented socket functionality.
|
||||||
*
|
*
|
||||||
* @par Thread Safety:
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
*
|
||||||
* @par Concepts:
|
* @par Concepts:
|
||||||
* Async_Read_Stream, Async_Write_Stream, Error_Source, IO_Object, Stream,
|
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||||
* Sync_Read_Stream, Sync_Write_Stream.
|
|
||||||
*/
|
*/
|
||||||
template <typename Protocol,
|
template <typename Protocol,
|
||||||
typename Service = stream_socket_service<Protocol> >
|
typename StreamSocketService = stream_socket_service<Protocol> >
|
||||||
class basic_stream_socket
|
class basic_stream_socket
|
||||||
: public basic_socket<Protocol, Service>
|
: public basic_socket<Protocol, StreamSocketService>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The native representation of a socket.
|
/// The native representation of a socket.
|
||||||
typedef typename Service::native_type native_type;
|
typedef typename StreamSocketService::native_type native_type;
|
||||||
|
|
||||||
/// The protocol type.
|
/// The protocol type.
|
||||||
typedef Protocol protocol_type;
|
typedef Protocol protocol_type;
|
||||||
@ -66,7 +66,7 @@ public:
|
|||||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||||
*/
|
*/
|
||||||
explicit basic_stream_socket(asio::io_service& io_service)
|
explicit basic_stream_socket(asio::io_service& io_service)
|
||||||
: basic_socket<Protocol, Service>(io_service)
|
: basic_socket<Protocol, StreamSocketService>(io_service)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,11 +80,11 @@ public:
|
|||||||
*
|
*
|
||||||
* @param protocol An object specifying protocol parameters to be used.
|
* @param protocol An object specifying protocol parameters to be used.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_stream_socket(asio::io_service& io_service,
|
basic_stream_socket(asio::io_service& io_service,
|
||||||
const protocol_type& protocol)
|
const protocol_type& protocol)
|
||||||
: basic_socket<Protocol, Service>(io_service, protocol)
|
: basic_socket<Protocol, StreamSocketService>(io_service, protocol)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,11 +101,11 @@ public:
|
|||||||
* @param endpoint An endpoint on the local machine to which the stream
|
* @param endpoint An endpoint on the local machine to which the stream
|
||||||
* socket will be bound.
|
* socket will be bound.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_stream_socket(asio::io_service& io_service,
|
basic_stream_socket(asio::io_service& io_service,
|
||||||
const endpoint_type& endpoint)
|
const endpoint_type& endpoint)
|
||||||
: basic_socket<Protocol, Service>(io_service, endpoint)
|
: basic_socket<Protocol, StreamSocketService>(io_service, endpoint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,11 +121,12 @@ public:
|
|||||||
*
|
*
|
||||||
* @param native_socket The new underlying socket implementation.
|
* @param native_socket The new underlying socket implementation.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_stream_socket(asio::io_service& io_service,
|
basic_stream_socket(asio::io_service& io_service,
|
||||||
const protocol_type& protocol, const native_type& native_socket)
|
const protocol_type& protocol, const native_type& native_socket)
|
||||||
: basic_socket<Protocol, Service>(io_service, protocol, native_socket)
|
: basic_socket<Protocol, StreamSocketService>(
|
||||||
|
io_service, protocol, native_socket)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,13 +140,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes sent.
|
* @returns The number of bytes sent.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @note The send operation may not transmit all of the data to the peer.
|
* @note The send operation may not transmit all of the data to the peer.
|
||||||
* Consider using the @ref write function if you need to ensure that all data
|
* Consider using the @ref write function if you need to ensure that all data
|
||||||
* is written before the blocking operation completes.
|
* is written before the blocking operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To send a single data buffer use the @ref buffer function as follows:
|
* To send a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* socket.send(asio::buffer(data, size));
|
* socket.send(asio::buffer(data, size));
|
||||||
@ -154,10 +155,14 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send(const Const_Buffers& buffers)
|
std::size_t send(const ConstBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return this->service.send(this->implementation, buffers, 0, throw_error());
|
asio::error_code ec;
|
||||||
|
std::size_t s = this->service.send(
|
||||||
|
this->implementation, buffers, 0, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send some data on the socket.
|
/// Send some data on the socket.
|
||||||
@ -172,13 +177,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes sent.
|
* @returns The number of bytes sent.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure.
|
* @throws asio::system_error Thrown on failure.
|
||||||
*
|
*
|
||||||
* @note The send operation may not transmit all of the data to the peer.
|
* @note The send operation may not transmit all of the data to the peer.
|
||||||
* Consider using the @ref write function if you need to ensure that all data
|
* Consider using the @ref write function if you need to ensure that all data
|
||||||
* is written before the blocking operation completes.
|
* is written before the blocking operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To send a single data buffer use the @ref buffer function as follows:
|
* To send a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* socket.send(asio::buffer(data, size), 0);
|
* socket.send(asio::buffer(data, size), 0);
|
||||||
@ -187,12 +192,15 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send(const Const_Buffers& buffers,
|
std::size_t send(const ConstBufferSequence& buffers,
|
||||||
socket_base::message_flags flags)
|
socket_base::message_flags flags)
|
||||||
{
|
{
|
||||||
return this->service.send(this->implementation, buffers, flags,
|
asio::error_code ec;
|
||||||
throw_error());
|
std::size_t s = this->service.send(
|
||||||
|
this->implementation, buffers, flags, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send some data on the socket.
|
/// Send some data on the socket.
|
||||||
@ -205,27 +213,19 @@ public:
|
|||||||
*
|
*
|
||||||
* @param flags Flags specifying how the send call is to be made.
|
* @param flags Flags specifying how the send call is to be made.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation.
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns The number of bytes sent. Returns 0 if an error occurred and the
|
* @returns The number of bytes sent. Returns 0 if an error occurred.
|
||||||
* error handler did not throw an exception.
|
|
||||||
*
|
*
|
||||||
* @note The send operation may not transmit all of the data to the peer.
|
* @note The send operation may not transmit all of the data to the peer.
|
||||||
* Consider using the @ref write function if you need to ensure that all data
|
* Consider using the @ref write function if you need to ensure that all data
|
||||||
* is written before the blocking operation completes.
|
* is written before the blocking operation completes.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Error_Handler>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send(const Const_Buffers& buffers,
|
std::size_t send(const ConstBufferSequence& buffers,
|
||||||
socket_base::message_flags flags,
|
socket_base::message_flags flags, asio::error_code& ec)
|
||||||
Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
return this->service.send(this->implementation, buffers, flags,
|
return this->service.send(this->implementation, buffers, flags, ec);
|
||||||
error_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous send.
|
/// Start an asynchronous send.
|
||||||
@ -242,7 +242,7 @@ public:
|
|||||||
* Copies will be made of the handler as required. The function signature of
|
* Copies will be made of the handler as required. The function signature of
|
||||||
* the handler must be:
|
* the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes sent.
|
* std::size_t bytes_transferred // Number of bytes sent.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -254,7 +254,7 @@ public:
|
|||||||
* Consider using the @ref async_write function if you need to ensure that all
|
* Consider using the @ref async_write function if you need to ensure that all
|
||||||
* data is written before the asynchronous operation completes.
|
* data is written before the asynchronous operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To send a single data buffer use the @ref buffer function as follows:
|
* To send a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* socket.async_send(asio::buffer(data, size), handler);
|
* socket.async_send(asio::buffer(data, size), handler);
|
||||||
@ -263,8 +263,8 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_send(const Const_Buffers& buffers, Handler handler)
|
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_send(this->implementation, buffers, 0, handler);
|
this->service.async_send(this->implementation, buffers, 0, handler);
|
||||||
}
|
}
|
||||||
@ -285,7 +285,7 @@ public:
|
|||||||
* Copies will be made of the handler as required. The function signature of
|
* Copies will be made of the handler as required. The function signature of
|
||||||
* the handler must be:
|
* the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes sent.
|
* std::size_t bytes_transferred // Number of bytes sent.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -297,7 +297,7 @@ public:
|
|||||||
* Consider using the @ref async_write function if you need to ensure that all
|
* Consider using the @ref async_write function if you need to ensure that all
|
||||||
* data is written before the asynchronous operation completes.
|
* data is written before the asynchronous operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To send a single data buffer use the @ref buffer function as follows:
|
* To send a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* socket.async_send(asio::buffer(data, size), 0, handler);
|
* socket.async_send(asio::buffer(data, size), 0, handler);
|
||||||
@ -306,9 +306,9 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_send(const Const_Buffers& buffers,
|
void async_send(const ConstBufferSequence& buffers,
|
||||||
socket_base::message_flags flags, Handler handler)
|
socket_base::message_flags flags, WriteHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_send(this->implementation, buffers, flags, handler);
|
this->service.async_send(this->implementation, buffers, flags, handler);
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes received.
|
* @returns The number of bytes received.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure. An error code of
|
* @throws asio::system_error Thrown on failure. An error code of
|
||||||
* asio::error::eof indicates that the connection was closed by the
|
* asio::error::eof indicates that the connection was closed by the
|
||||||
* peer.
|
* peer.
|
||||||
*
|
*
|
||||||
@ -331,7 +331,7 @@ public:
|
|||||||
* bytes. Consider using the @ref read function if you need to ensure that the
|
* bytes. Consider using the @ref read function if you need to ensure that the
|
||||||
* requested amount of data is read before the blocking operation completes.
|
* requested amount of data is read before the blocking operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To receive into a single data buffer use the @ref buffer function as
|
* To receive into a single data buffer use the @ref buffer function as
|
||||||
* follows:
|
* follows:
|
||||||
* @code
|
* @code
|
||||||
@ -341,11 +341,13 @@ public:
|
|||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive(const Mutable_Buffers& buffers)
|
std::size_t receive(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return this->service.receive(this->implementation, buffers, 0,
|
asio::error_code ec;
|
||||||
throw_error());
|
std::size_t s = this->service.receive(this->implementation, buffers, 0, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive some data on the socket.
|
/// Receive some data on the socket.
|
||||||
@ -360,7 +362,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes received.
|
* @returns The number of bytes received.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure. An error code of
|
* @throws asio::system_error Thrown on failure. An error code of
|
||||||
* asio::error::eof indicates that the connection was closed by the
|
* asio::error::eof indicates that the connection was closed by the
|
||||||
* peer.
|
* peer.
|
||||||
*
|
*
|
||||||
@ -368,7 +370,7 @@ public:
|
|||||||
* bytes. Consider using the @ref read function if you need to ensure that the
|
* bytes. Consider using the @ref read function if you need to ensure that the
|
||||||
* requested amount of data is read before the blocking operation completes.
|
* requested amount of data is read before the blocking operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To receive into a single data buffer use the @ref buffer function as
|
* To receive into a single data buffer use the @ref buffer function as
|
||||||
* follows:
|
* follows:
|
||||||
* @code
|
* @code
|
||||||
@ -378,12 +380,15 @@ public:
|
|||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive(const Mutable_Buffers& buffers,
|
std::size_t receive(const MutableBufferSequence& buffers,
|
||||||
socket_base::message_flags flags)
|
socket_base::message_flags flags)
|
||||||
{
|
{
|
||||||
return this->service.receive(this->implementation, buffers, flags,
|
asio::error_code ec;
|
||||||
throw_error());
|
std::size_t s = this->service.receive(
|
||||||
|
this->implementation, buffers, flags, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive some data on a connected socket.
|
/// Receive some data on a connected socket.
|
||||||
@ -396,26 +401,19 @@ public:
|
|||||||
*
|
*
|
||||||
* @param flags Flags specifying how the receive call is to be made.
|
* @param flags Flags specifying how the receive call is to be made.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns The number of bytes received. Returns 0 if an error occurred and
|
* @returns The number of bytes received. Returns 0 if an error occurred.
|
||||||
* the error handler did not throw an exception.
|
|
||||||
*
|
*
|
||||||
* @note The receive operation may not receive all of the requested number of
|
* @note The receive operation may not receive all of the requested number of
|
||||||
* bytes. Consider using the @ref read function if you need to ensure that the
|
* bytes. Consider using the @ref read function if you need to ensure that the
|
||||||
* requested amount of data is read before the blocking operation completes.
|
* requested amount of data is read before the blocking operation completes.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive(const Mutable_Buffers& buffers,
|
std::size_t receive(const MutableBufferSequence& buffers,
|
||||||
socket_base::message_flags flags, Error_Handler error_handler)
|
socket_base::message_flags flags, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return this->service.receive(this->implementation, buffers, flags,
|
return this->service.receive(this->implementation, buffers, flags, ec);
|
||||||
error_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous receive.
|
/// Start an asynchronous receive.
|
||||||
@ -432,7 +430,7 @@ public:
|
|||||||
* completes. Copies will be made of the handler as required. The function
|
* completes. Copies will be made of the handler as required. The function
|
||||||
* signature of the handler must be:
|
* signature of the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes received.
|
* std::size_t bytes_transferred // Number of bytes received.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -445,7 +443,7 @@ public:
|
|||||||
* that the requested amount of data is received before the asynchronous
|
* that the requested amount of data is received before the asynchronous
|
||||||
* operation completes.
|
* operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To receive into a single data buffer use the @ref buffer function as
|
* To receive into a single data buffer use the @ref buffer function as
|
||||||
* follows:
|
* follows:
|
||||||
* @code
|
* @code
|
||||||
@ -455,8 +453,8 @@ public:
|
|||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_receive(const Mutable_Buffers& buffers, Handler handler)
|
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_receive(this->implementation, buffers, 0, handler);
|
this->service.async_receive(this->implementation, buffers, 0, handler);
|
||||||
}
|
}
|
||||||
@ -477,7 +475,7 @@ public:
|
|||||||
* completes. Copies will be made of the handler as required. The function
|
* completes. Copies will be made of the handler as required. The function
|
||||||
* signature of the handler must be:
|
* signature of the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes received.
|
* std::size_t bytes_transferred // Number of bytes received.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -490,7 +488,7 @@ public:
|
|||||||
* that the requested amount of data is received before the asynchronous
|
* that the requested amount of data is received before the asynchronous
|
||||||
* operation completes.
|
* operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To receive into a single data buffer use the @ref buffer function as
|
* To receive into a single data buffer use the @ref buffer function as
|
||||||
* follows:
|
* follows:
|
||||||
* @code
|
* @code
|
||||||
@ -500,9 +498,9 @@ public:
|
|||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_receive(const Mutable_Buffers& buffers,
|
void async_receive(const MutableBufferSequence& buffers,
|
||||||
socket_base::message_flags flags, Handler handler)
|
socket_base::message_flags flags, ReadHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_receive(this->implementation, buffers, flags, handler);
|
this->service.async_receive(this->implementation, buffers, flags, handler);
|
||||||
}
|
}
|
||||||
@ -517,7 +515,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes written.
|
* @returns The number of bytes written.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure. An error code of
|
* @throws asio::system_error Thrown on failure. An error code of
|
||||||
* asio::error::eof indicates that the connection was closed by the
|
* asio::error::eof indicates that the connection was closed by the
|
||||||
* peer.
|
* peer.
|
||||||
*
|
*
|
||||||
@ -525,7 +523,7 @@ public:
|
|||||||
* peer. Consider using the @ref write function if you need to ensure that
|
* peer. Consider using the @ref write function if you need to ensure that
|
||||||
* all data is written before the blocking operation completes.
|
* all data is written before the blocking operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To write a single data buffer use the @ref buffer function as follows:
|
* To write a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* socket.write_some(asio::buffer(data, size));
|
* socket.write_some(asio::buffer(data, size));
|
||||||
@ -534,10 +532,13 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t write_some(const Const_Buffers& buffers)
|
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return this->service.send(this->implementation, buffers, 0, throw_error());
|
asio::error_code ec;
|
||||||
|
std::size_t s = this->service.send(this->implementation, buffers, 0, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write some data to the socket.
|
/// Write some data to the socket.
|
||||||
@ -548,25 +549,19 @@ public:
|
|||||||
*
|
*
|
||||||
* @param buffers One or more data buffers to be written to the socket.
|
* @param buffers One or more data buffers to be written to the socket.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation.
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns The number of bytes written. Returns 0 if an error occurred and
|
* @returns The number of bytes written. Returns 0 if an error occurred.
|
||||||
* the error handler did not throw an exception.
|
|
||||||
*
|
*
|
||||||
* @note The write_some operation may not transmit all of the data to the
|
* @note The write_some operation may not transmit all of the data to the
|
||||||
* peer. Consider using the @ref write function if you need to ensure that
|
* peer. Consider using the @ref write function if you need to ensure that
|
||||||
* all data is written before the blocking operation completes.
|
* all data is written before the blocking operation completes.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Error_Handler>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t write_some(const Const_Buffers& buffers,
|
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return this->service.send(this->implementation, buffers, 0, error_handler);
|
return this->service.send(this->implementation, buffers, 0, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous write.
|
/// Start an asynchronous write.
|
||||||
@ -583,7 +578,7 @@ public:
|
|||||||
* Copies will be made of the handler as required. The function signature of
|
* Copies will be made of the handler as required. The function signature of
|
||||||
* the handler must be:
|
* the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes written.
|
* std::size_t bytes_transferred // Number of bytes written.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -595,7 +590,7 @@ public:
|
|||||||
* Consider using the @ref async_write function if you need to ensure that all
|
* Consider using the @ref async_write function if you need to ensure that all
|
||||||
* data is written before the asynchronous operation completes.
|
* data is written before the asynchronous operation completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To write a single data buffer use the @ref buffer function as follows:
|
* To write a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* socket.async_write_some(asio::buffer(data, size), handler);
|
* socket.async_write_some(asio::buffer(data, size), handler);
|
||||||
@ -604,8 +599,9 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_write_some(const Const_Buffers& buffers, Handler handler)
|
void async_write_some(const ConstBufferSequence& buffers,
|
||||||
|
WriteHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_send(this->implementation, buffers, 0, handler);
|
this->service.async_send(this->implementation, buffers, 0, handler);
|
||||||
}
|
}
|
||||||
@ -620,7 +616,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @returns The number of bytes read.
|
* @returns The number of bytes read.
|
||||||
*
|
*
|
||||||
* @throws asio::error Thrown on failure. An error code of
|
* @throws asio::system_error Thrown on failure. An error code of
|
||||||
* asio::error::eof indicates that the connection was closed by the
|
* asio::error::eof indicates that the connection was closed by the
|
||||||
* peer.
|
* peer.
|
||||||
*
|
*
|
||||||
@ -629,7 +625,7 @@ public:
|
|||||||
* the requested amount of data is read before the blocking operation
|
* the requested amount of data is read before the blocking operation
|
||||||
* completes.
|
* completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To read into a single data buffer use the @ref buffer function as follows:
|
* To read into a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* socket.read_some(asio::buffer(data, size));
|
* socket.read_some(asio::buffer(data, size));
|
||||||
@ -638,11 +634,13 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t read_some(const Mutable_Buffers& buffers)
|
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return this->service.receive(this->implementation, buffers, 0,
|
asio::error_code ec;
|
||||||
throw_error());
|
std::size_t s = this->service.receive(this->implementation, buffers, 0, ec);
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read some data from the socket.
|
/// Read some data from the socket.
|
||||||
@ -653,27 +651,20 @@ public:
|
|||||||
*
|
*
|
||||||
* @param buffers One or more buffers into which the data will be read.
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
*
|
*
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation.
|
|
||||||
* ); @endcode
|
|
||||||
*
|
*
|
||||||
* @returns The number of bytes read. Returns 0 if an error occurred and the
|
* @returns The number of bytes read. Returns 0 if an error occurred.
|
||||||
* error handler did not throw an exception.
|
|
||||||
*
|
*
|
||||||
* @note The read_some operation may not read all of the requested number of
|
* @note The read_some operation may not read all of the requested number of
|
||||||
* bytes. Consider using the @ref read function if you need to ensure that
|
* bytes. Consider using the @ref read function if you need to ensure that
|
||||||
* the requested amount of data is read before the blocking operation
|
* the requested amount of data is read before the blocking operation
|
||||||
* completes.
|
* completes.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t read_some(const Mutable_Buffers& buffers,
|
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return this->service.receive(this->implementation, buffers, 0,
|
return this->service.receive(this->implementation, buffers, 0, ec);
|
||||||
error_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous read.
|
/// Start an asynchronous read.
|
||||||
@ -690,7 +681,7 @@ public:
|
|||||||
* Copies will be made of the handler as required. The function signature of
|
* Copies will be made of the handler as required. The function signature of
|
||||||
* the handler must be:
|
* the handler must be:
|
||||||
* @code void handler(
|
* @code void handler(
|
||||||
* const asio::error& error, // Result of operation.
|
* const asio::error_code& error, // Result of operation.
|
||||||
* std::size_t bytes_transferred // Number of bytes read.
|
* std::size_t bytes_transferred // Number of bytes read.
|
||||||
* ); @endcode
|
* ); @endcode
|
||||||
* Regardless of whether the asynchronous operation completes immediately or
|
* Regardless of whether the asynchronous operation completes immediately or
|
||||||
@ -703,7 +694,7 @@ public:
|
|||||||
* requested amount of data is read before the asynchronous operation
|
* requested amount of data is read before the asynchronous operation
|
||||||
* completes.
|
* completes.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* To read into a single data buffer use the @ref buffer function as follows:
|
* To read into a single data buffer use the @ref buffer function as follows:
|
||||||
* @code
|
* @code
|
||||||
* socket.async_read_some(asio::buffer(data, size), handler);
|
* socket.async_read_some(asio::buffer(data, size), handler);
|
||||||
@ -712,101 +703,12 @@ public:
|
|||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
*/
|
*/
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
|
void async_read_some(const MutableBufferSequence& buffers,
|
||||||
|
ReadHandler handler)
|
||||||
{
|
{
|
||||||
this->service.async_receive(this->implementation, buffers, 0, handler);
|
this->service.async_receive(this->implementation, buffers, 0, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peek at the incoming data on the stream socket.
|
|
||||||
/**
|
|
||||||
* This function is used to peek at the incoming data on the stream socket,
|
|
||||||
* without removing it from the input queue. The function call will block
|
|
||||||
* until data has been read successfully or an error occurs.
|
|
||||||
*
|
|
||||||
* @param buffers One or more buffers into which the data will be read.
|
|
||||||
*
|
|
||||||
* @returns The number of bytes read.
|
|
||||||
*
|
|
||||||
* @throws asio::error Thrown on failure.
|
|
||||||
*
|
|
||||||
* @par Example:
|
|
||||||
* To peek using a single data buffer use the @ref buffer function as
|
|
||||||
* follows:
|
|
||||||
* @code socket.peek(asio::buffer(data, size)); @endcode
|
|
||||||
* See the @ref buffer documentation for information on using multiple
|
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
|
||||||
* std::vector.
|
|
||||||
*/
|
|
||||||
template <typename Mutable_Buffers>
|
|
||||||
std::size_t peek(const Mutable_Buffers& buffers)
|
|
||||||
{
|
|
||||||
return this->service.receive(this->implementation, buffers,
|
|
||||||
socket_base::message_peek, throw_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Peek at the incoming data on the stream socket.
|
|
||||||
/**
|
|
||||||
* This function is used to peek at the incoming data on the stream socket,
|
|
||||||
* without removing it from the input queue. The function call will block
|
|
||||||
* until data has been read successfully or an error occurs.
|
|
||||||
*
|
|
||||||
* @param buffers One or more buffers into which the data will be read.
|
|
||||||
*
|
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation.
|
|
||||||
* ); @endcode
|
|
||||||
*
|
|
||||||
* @returns The number of bytes read. Returns 0 if an error occurred and the
|
|
||||||
* error handler did not throw an exception.
|
|
||||||
*/
|
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
|
||||||
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
|
|
||||||
{
|
|
||||||
return this->service.receive(this->implementation, buffers,
|
|
||||||
socket_base::message_peek, error_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determine the amount of data that may be read without blocking.
|
|
||||||
/**
|
|
||||||
* This function is used to determine the amount of data, in bytes, that may
|
|
||||||
* be read from the stream socket without blocking.
|
|
||||||
*
|
|
||||||
* @returns The number of bytes of data that can be read without blocking.
|
|
||||||
*
|
|
||||||
* @throws asio::error Thrown on failure.
|
|
||||||
*/
|
|
||||||
std::size_t in_avail()
|
|
||||||
{
|
|
||||||
socket_base::bytes_readable command;
|
|
||||||
this->service.io_control(this->implementation, command, throw_error());
|
|
||||||
return command.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determine the amount of data that may be read without blocking.
|
|
||||||
/**
|
|
||||||
* This function is used to determine the amount of data, in bytes, that may
|
|
||||||
* be read from the stream socket without blocking.
|
|
||||||
*
|
|
||||||
* @param error_handler A handler to be called when the operation completes,
|
|
||||||
* to indicate whether or not an error has occurred. Copies will be made of
|
|
||||||
* the handler as required. The function signature of the handler must be:
|
|
||||||
* @code void error_handler(
|
|
||||||
* const asio::error& error // Result of operation
|
|
||||||
* ); @endcode
|
|
||||||
*
|
|
||||||
* @returns The number of bytes of data that can be read without blocking.
|
|
||||||
*/
|
|
||||||
template <typename Error_Handler>
|
|
||||||
std::size_t in_avail(Error_Handler error_handler)
|
|
||||||
{
|
|
||||||
socket_base::bytes_readable command;
|
|
||||||
this->service.io_control(this->implementation, command, error_handler);
|
|
||||||
return command.get();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// basic_streambuf.hpp
|
// basic_streambuf.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -45,8 +45,8 @@ public:
|
|||||||
/// The type used to represent the put area as a list of buffers.
|
/// The type used to represent the put area as a list of buffers.
|
||||||
typedef implementation_defined mutable_buffers_type;
|
typedef implementation_defined mutable_buffers_type;
|
||||||
#else
|
#else
|
||||||
typedef asio::const_buffer_container_1 const_buffers_type;
|
typedef asio::const_buffers_1 const_buffers_type;
|
||||||
typedef asio::mutable_buffer_container_1 mutable_buffers_type;
|
typedef asio::mutable_buffers_1 mutable_buffers_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Construct a buffer with a specified maximum size.
|
/// Construct a buffer with a specified maximum size.
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// buffer.hpp
|
// buffer.hpp
|
||||||
// ~~~~~~~~~~
|
// ~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -26,6 +26,20 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
# if defined(_HAS_ITERATOR_DEBUGGING)
|
||||||
|
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||||
|
# define ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||||
|
# endif // defined(_HAS_ITERATOR_DEBUGGING)
|
||||||
|
#endif // defined(BOOST_MSVC)
|
||||||
|
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
# include "asio/detail/push_options.hpp"
|
||||||
|
# include <boost/function.hpp>
|
||||||
|
# include "asio/detail/pop_options.hpp"
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
class mutable_buffer;
|
class mutable_buffer;
|
||||||
@ -61,6 +75,21 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
mutable_buffer(void* data, std::size_t size,
|
||||||
|
boost::function<void()> debug_check)
|
||||||
|
: data_(data),
|
||||||
|
size_(size),
|
||||||
|
debug_check_(debug_check)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::function<void()>& get_debug_check() const
|
||||||
|
{
|
||||||
|
return debug_check_;
|
||||||
|
}
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend void* asio::detail::buffer_cast_helper(
|
friend void* asio::detail::buffer_cast_helper(
|
||||||
const mutable_buffer& b);
|
const mutable_buffer& b);
|
||||||
@ -69,12 +98,20 @@ private:
|
|||||||
|
|
||||||
void* data_;
|
void* data_;
|
||||||
std::size_t size_;
|
std::size_t size_;
|
||||||
|
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
boost::function<void()> debug_check_;
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
inline void* buffer_cast_helper(const mutable_buffer& b)
|
inline void* buffer_cast_helper(const mutable_buffer& b)
|
||||||
{
|
{
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
if (b.debug_check_)
|
||||||
|
b.debug_check_();
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
return b.data_;
|
return b.data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,10 +126,10 @@ inline std::size_t buffer_size_helper(const mutable_buffer& b)
|
|||||||
/**
|
/**
|
||||||
* @relates mutable_buffer
|
* @relates mutable_buffer
|
||||||
*/
|
*/
|
||||||
template <typename Pointer_To_Pod_Type>
|
template <typename PointerToPodType>
|
||||||
inline Pointer_To_Pod_Type buffer_cast(const mutable_buffer& b)
|
inline PointerToPodType buffer_cast(const mutable_buffer& b)
|
||||||
{
|
{
|
||||||
return static_cast<Pointer_To_Pod_Type>(detail::buffer_cast_helper(b));
|
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of bytes in a non-modifiable buffer.
|
/// Get the number of bytes in a non-modifiable buffer.
|
||||||
@ -114,7 +151,11 @@ inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
|
|||||||
return mutable_buffer();
|
return mutable_buffer();
|
||||||
char* new_data = buffer_cast<char*>(b) + start;
|
char* new_data = buffer_cast<char*>(b) + start;
|
||||||
std::size_t new_size = buffer_size(b) - start;
|
std::size_t new_size = buffer_size(b) - start;
|
||||||
return mutable_buffer(new_data, new_size);
|
return mutable_buffer(new_data, new_size
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, b.get_debug_check()
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new modifiable buffer that is offset from the start of another.
|
/// Create a new modifiable buffer that is offset from the start of another.
|
||||||
@ -127,12 +168,16 @@ inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
|
|||||||
return mutable_buffer();
|
return mutable_buffer();
|
||||||
char* new_data = buffer_cast<char*>(b) + start;
|
char* new_data = buffer_cast<char*>(b) + start;
|
||||||
std::size_t new_size = buffer_size(b) - start;
|
std::size_t new_size = buffer_size(b) - start;
|
||||||
return mutable_buffer(new_data, new_size);
|
return mutable_buffer(new_data, new_size
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, b.get_debug_check()
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adapts a single modifiable buffer so that it meets the requirements of the
|
/// Adapts a single modifiable buffer so that it meets the requirements of the
|
||||||
/// Mutable_Buffers concept.
|
/// MutableBufferSequence concept.
|
||||||
class mutable_buffer_container_1
|
class mutable_buffers_1
|
||||||
: public mutable_buffer
|
: public mutable_buffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -143,7 +188,7 @@ public:
|
|||||||
typedef const mutable_buffer* const_iterator;
|
typedef const mutable_buffer* const_iterator;
|
||||||
|
|
||||||
/// Construct to represent a single modifiable buffer.
|
/// Construct to represent a single modifiable buffer.
|
||||||
explicit mutable_buffer_container_1(const mutable_buffer& b)
|
explicit mutable_buffers_1(const mutable_buffer& b)
|
||||||
: mutable_buffer(b)
|
: mutable_buffer(b)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -188,9 +233,27 @@ public:
|
|||||||
const_buffer(const mutable_buffer& b)
|
const_buffer(const mutable_buffer& b)
|
||||||
: data_(asio::detail::buffer_cast_helper(b)),
|
: data_(asio::detail::buffer_cast_helper(b)),
|
||||||
size_(asio::detail::buffer_size_helper(b))
|
size_(asio::detail::buffer_size_helper(b))
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, debug_check_(b.get_debug_check())
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
const_buffer(const void* data, std::size_t size,
|
||||||
|
boost::function<void()> debug_check)
|
||||||
|
: data_(data),
|
||||||
|
size_(size),
|
||||||
|
debug_check_(debug_check)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::function<void()>& get_debug_check() const
|
||||||
|
{
|
||||||
|
return debug_check_;
|
||||||
|
}
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend const void* asio::detail::buffer_cast_helper(
|
friend const void* asio::detail::buffer_cast_helper(
|
||||||
const const_buffer& b);
|
const const_buffer& b);
|
||||||
@ -199,12 +262,20 @@ private:
|
|||||||
|
|
||||||
const void* data_;
|
const void* data_;
|
||||||
std::size_t size_;
|
std::size_t size_;
|
||||||
|
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
boost::function<void()> debug_check_;
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
inline const void* buffer_cast_helper(const const_buffer& b)
|
inline const void* buffer_cast_helper(const const_buffer& b)
|
||||||
{
|
{
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
if (b.debug_check_)
|
||||||
|
b.debug_check_();
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
return b.data_;
|
return b.data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,10 +290,10 @@ inline std::size_t buffer_size_helper(const const_buffer& b)
|
|||||||
/**
|
/**
|
||||||
* @relates const_buffer
|
* @relates const_buffer
|
||||||
*/
|
*/
|
||||||
template <typename Pointer_To_Pod_Type>
|
template <typename PointerToPodType>
|
||||||
inline Pointer_To_Pod_Type buffer_cast(const const_buffer& b)
|
inline PointerToPodType buffer_cast(const const_buffer& b)
|
||||||
{
|
{
|
||||||
return static_cast<Pointer_To_Pod_Type>(detail::buffer_cast_helper(b));
|
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of bytes in a non-modifiable buffer.
|
/// Get the number of bytes in a non-modifiable buffer.
|
||||||
@ -244,7 +315,11 @@ inline const_buffer operator+(const const_buffer& b, std::size_t start)
|
|||||||
return const_buffer();
|
return const_buffer();
|
||||||
const char* new_data = buffer_cast<const char*>(b) + start;
|
const char* new_data = buffer_cast<const char*>(b) + start;
|
||||||
std::size_t new_size = buffer_size(b) - start;
|
std::size_t new_size = buffer_size(b) - start;
|
||||||
return const_buffer(new_data, new_size);
|
return const_buffer(new_data, new_size
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, b.get_debug_check()
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that is offset from the start of another.
|
/// Create a new non-modifiable buffer that is offset from the start of another.
|
||||||
@ -257,12 +332,16 @@ inline const_buffer operator+(std::size_t start, const const_buffer& b)
|
|||||||
return const_buffer();
|
return const_buffer();
|
||||||
const char* new_data = buffer_cast<const char*>(b) + start;
|
const char* new_data = buffer_cast<const char*>(b) + start;
|
||||||
std::size_t new_size = buffer_size(b) - start;
|
std::size_t new_size = buffer_size(b) - start;
|
||||||
return const_buffer(new_data, new_size);
|
return const_buffer(new_data, new_size
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, b.get_debug_check()
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adapts a single non-modifiable buffer so that it meets the requirements of
|
/// Adapts a single non-modifiable buffer so that it meets the requirements of
|
||||||
/// the Const_Buffers concept.
|
/// the ConstBufferSequence concept.
|
||||||
class const_buffer_container_1
|
class const_buffers_1
|
||||||
: public const_buffer
|
: public const_buffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -273,7 +352,7 @@ public:
|
|||||||
typedef const const_buffer* const_iterator;
|
typedef const const_buffer* const_iterator;
|
||||||
|
|
||||||
/// Construct to represent a single non-modifiable buffer.
|
/// Construct to represent a single non-modifiable buffer.
|
||||||
explicit const_buffer_container_1(const const_buffer& b)
|
explicit const_buffers_1(const const_buffer& b)
|
||||||
: const_buffer(b)
|
: const_buffer(b)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -291,6 +370,30 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class buffer_debug_check
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
buffer_debug_check(Iterator iter)
|
||||||
|
: iter_(iter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()()
|
||||||
|
{
|
||||||
|
*iter_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Iterator iter_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
|
||||||
/** @defgroup buffer asio::buffer
|
/** @defgroup buffer asio::buffer
|
||||||
*
|
*
|
||||||
* @brief The asio::buffer function is used to create a buffer object to
|
* @brief The asio::buffer function is used to create a buffer object to
|
||||||
@ -302,9 +405,9 @@ public:
|
|||||||
* @code sock.write(asio::buffer(data, size)); @endcode
|
* @code sock.write(asio::buffer(data, size)); @endcode
|
||||||
*
|
*
|
||||||
* In the above example, the return value of asio::buffer meets the
|
* In the above example, the return value of asio::buffer meets the
|
||||||
* requirements of the Const_Buffers concept so that it may be directly passed
|
* requirements of the ConstBufferSequence concept so that it may be directly
|
||||||
* to the socket's write function. A buffer created for modifiable memory also
|
* passed to the socket's write function. A buffer created for modifiable
|
||||||
* meets the requirements of the Mutable_Buffers concept.
|
* memory also meets the requirements of the MutableBufferSequence concept.
|
||||||
*
|
*
|
||||||
* An individual buffer may be created from a builtin array, std::vector or
|
* An individual buffer may be created from a builtin array, std::vector or
|
||||||
* boost::array of POD elements. This helps prevent buffer overruns by
|
* boost::array of POD elements. This helps prevent buffer overruns by
|
||||||
@ -321,7 +424,7 @@ public:
|
|||||||
*
|
*
|
||||||
* To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
|
* To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
|
||||||
* buffer objects may be assigned into a container that supports the
|
* buffer objects may be assigned into a container that supports the
|
||||||
* Mutable_Buffers (for read) or Const_Buffers (for write) concepts:
|
* MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
|
||||||
*
|
*
|
||||||
* @code
|
* @code
|
||||||
* char d1[128];
|
* char d1[128];
|
||||||
@ -343,99 +446,107 @@ public:
|
|||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
/// Create a new modifiable buffer from an existing buffer.
|
/// Create a new modifiable buffer from an existing buffer.
|
||||||
inline mutable_buffer_container_1 buffer(const mutable_buffer& b)
|
inline mutable_buffers_1 buffer(const mutable_buffer& b)
|
||||||
{
|
{
|
||||||
return mutable_buffer_container_1(b);
|
return mutable_buffers_1(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new modifiable buffer from an existing buffer.
|
/// Create a new modifiable buffer from an existing buffer.
|
||||||
inline mutable_buffer_container_1 buffer(const mutable_buffer& b,
|
inline mutable_buffers_1 buffer(const mutable_buffer& b,
|
||||||
std::size_t max_size_in_bytes)
|
std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return mutable_buffer_container_1(
|
return mutable_buffers_1(
|
||||||
mutable_buffer(buffer_cast<void*>(b),
|
mutable_buffer(buffer_cast<void*>(b),
|
||||||
buffer_size(b) < max_size_in_bytes
|
buffer_size(b) < max_size_in_bytes
|
||||||
? buffer_size(b) : max_size_in_bytes));
|
? buffer_size(b) : max_size_in_bytes
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, b.get_debug_check()
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer from an existing buffer.
|
/// Create a new non-modifiable buffer from an existing buffer.
|
||||||
inline const_buffer_container_1 buffer(const const_buffer& b)
|
inline const_buffers_1 buffer(const const_buffer& b)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(b);
|
return const_buffers_1(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer from an existing buffer.
|
/// Create a new non-modifiable buffer from an existing buffer.
|
||||||
inline const_buffer_container_1 buffer(const const_buffer& b,
|
inline const_buffers_1 buffer(const const_buffer& b,
|
||||||
std::size_t max_size_in_bytes)
|
std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(
|
return const_buffers_1(
|
||||||
const_buffer(buffer_cast<const void*>(b),
|
const_buffer(buffer_cast<const void*>(b),
|
||||||
buffer_size(b) < max_size_in_bytes
|
buffer_size(b) < max_size_in_bytes
|
||||||
? buffer_size(b) : max_size_in_bytes));
|
? buffer_size(b) : max_size_in_bytes
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, b.get_debug_check()
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new modifiable buffer that represents the given memory range.
|
/// Create a new modifiable buffer that represents the given memory range.
|
||||||
inline mutable_buffer_container_1 buffer(void* data, std::size_t size_in_bytes)
|
inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
|
||||||
{
|
{
|
||||||
return mutable_buffer_container_1(mutable_buffer(data, size_in_bytes));
|
return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given memory range.
|
/// Create a new non-modifiable buffer that represents the given memory range.
|
||||||
inline const_buffer_container_1 buffer(const void* data,
|
inline const_buffers_1 buffer(const void* data,
|
||||||
std::size_t size_in_bytes)
|
std::size_t size_in_bytes)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(const_buffer(data, size_in_bytes));
|
return const_buffers_1(const_buffer(data, size_in_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new modifiable buffer that represents the given POD array.
|
/// Create a new modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline mutable_buffer_container_1 buffer(Pod_Type (&data)[N])
|
inline mutable_buffers_1 buffer(PodType (&data)[N])
|
||||||
{
|
{
|
||||||
return mutable_buffer_container_1(mutable_buffer(data, N * sizeof(Pod_Type)));
|
return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new modifiable buffer that represents the given POD array.
|
/// Create a new modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline mutable_buffer_container_1 buffer(Pod_Type (&data)[N],
|
inline mutable_buffers_1 buffer(PodType (&data)[N],
|
||||||
std::size_t max_size_in_bytes)
|
std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return mutable_buffer_container_1(
|
return mutable_buffers_1(
|
||||||
mutable_buffer(data,
|
mutable_buffer(data,
|
||||||
N * sizeof(Pod_Type) < max_size_in_bytes
|
N * sizeof(PodType) < max_size_in_bytes
|
||||||
? N * sizeof(Pod_Type) : max_size_in_bytes));
|
? N * sizeof(PodType) : max_size_in_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline const_buffer_container_1 buffer(const Pod_Type (&data)[N])
|
inline const_buffers_1 buffer(const PodType (&data)[N])
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(const_buffer(data, N * sizeof(Pod_Type)));
|
return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline const_buffer_container_1 buffer(const Pod_Type (&data)[N],
|
inline const_buffers_1 buffer(const PodType (&data)[N],
|
||||||
std::size_t max_size_in_bytes)
|
std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(
|
return const_buffers_1(
|
||||||
const_buffer(data,
|
const_buffer(data,
|
||||||
N * sizeof(Pod_Type) < max_size_in_bytes
|
N * sizeof(PodType) < max_size_in_bytes
|
||||||
? N * sizeof(Pod_Type) : max_size_in_bytes));
|
? N * sizeof(PodType) : max_size_in_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||||
|
|
||||||
// Borland C++ thinks the overloads:
|
// Borland C++ thinks the overloads:
|
||||||
//
|
//
|
||||||
// unspecified buffer(boost::array<Pod_Type, N>& array ...);
|
// unspecified buffer(boost::array<PodType, N>& array ...);
|
||||||
//
|
//
|
||||||
// and
|
// and
|
||||||
//
|
//
|
||||||
// unspecified buffer(boost::array<const Pod_Type, N>& array ...);
|
// unspecified buffer(boost::array<const PodType, N>& array ...);
|
||||||
//
|
//
|
||||||
// are ambiguous. This will be worked around by using a buffer_types traits
|
// are ambiguous. This will be worked around by using a buffer_types traits
|
||||||
// class that contains typedefs for the appropriate buffer and container
|
// class that contains typedefs for the appropriate buffer and container
|
||||||
// classes, based on whether Pod_Type is const or non-const.
|
// classes, based on whether PodType is const or non-const.
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
@ -446,109 +557,109 @@ template <>
|
|||||||
struct buffer_types_base<false>
|
struct buffer_types_base<false>
|
||||||
{
|
{
|
||||||
typedef mutable_buffer buffer_type;
|
typedef mutable_buffer buffer_type;
|
||||||
typedef mutable_buffer_container_1 container_type;
|
typedef mutable_buffers_1 container_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct buffer_types_base<true>
|
struct buffer_types_base<true>
|
||||||
{
|
{
|
||||||
typedef const_buffer buffer_type;
|
typedef const_buffer buffer_type;
|
||||||
typedef const_buffer_container_1 container_type;
|
typedef const_buffers_1 container_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Pod_Type>
|
template <typename PodType>
|
||||||
struct buffer_types
|
struct buffer_types
|
||||||
: public buffer_types_base<boost::is_const<Pod_Type>::value>
|
: public buffer_types_base<boost::is_const<PodType>::value>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline typename detail::buffer_types<Pod_Type>::container_type
|
inline typename detail::buffer_types<PodType>::container_type
|
||||||
buffer(boost::array<Pod_Type, N>& data)
|
buffer(boost::array<PodType, N>& data)
|
||||||
{
|
{
|
||||||
typedef typename asio::detail::buffer_types<Pod_Type>::buffer_type
|
typedef typename asio::detail::buffer_types<PodType>::buffer_type
|
||||||
buffer_type;
|
buffer_type;
|
||||||
typedef typename asio::detail::buffer_types<Pod_Type>::container_type
|
typedef typename asio::detail::buffer_types<PodType>::container_type
|
||||||
container_type;
|
container_type;
|
||||||
return container_type(
|
return container_type(
|
||||||
buffer_type(data.c_array(), data.size() * sizeof(Pod_Type)));
|
buffer_type(data.c_array(), data.size() * sizeof(PodType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline typename detail::buffer_types<Pod_Type>::container_type
|
inline typename detail::buffer_types<PodType>::container_type
|
||||||
buffer(boost::array<Pod_Type, N>& data, std::size_t max_size_in_bytes)
|
buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
typedef typename asio::detail::buffer_types<Pod_Type>::buffer_type
|
typedef typename asio::detail::buffer_types<PodType>::buffer_type
|
||||||
buffer_type;
|
buffer_type;
|
||||||
typedef typename asio::detail::buffer_types<Pod_Type>::container_type
|
typedef typename asio::detail::buffer_types<PodType>::container_type
|
||||||
container_type;
|
container_type;
|
||||||
return container_type(
|
return container_type(
|
||||||
buffer_type(data.c_array(),
|
buffer_type(data.c_array(),
|
||||||
data.size() * sizeof(Pod_Type) < max_size_in_bytes
|
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||||
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
|
? data.size() * sizeof(PodType) : max_size_in_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||||
|
|
||||||
/// Create a new modifiable buffer that represents the given POD array.
|
/// Create a new modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline mutable_buffer_container_1 buffer(boost::array<Pod_Type, N>& data)
|
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
|
||||||
{
|
{
|
||||||
return mutable_buffer_container_1(
|
return mutable_buffers_1(
|
||||||
mutable_buffer(data.c_array(), data.size() * sizeof(Pod_Type)));
|
mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new modifiable buffer that represents the given POD array.
|
/// Create a new modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline mutable_buffer_container_1 buffer(boost::array<Pod_Type, N>& data,
|
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
|
||||||
std::size_t max_size_in_bytes)
|
std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return mutable_buffer_container_1(
|
return mutable_buffers_1(
|
||||||
mutable_buffer(data.c_array(),
|
mutable_buffer(data.c_array(),
|
||||||
data.size() * sizeof(Pod_Type) < max_size_in_bytes
|
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||||
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
|
? data.size() * sizeof(PodType) : max_size_in_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline const_buffer_container_1 buffer(boost::array<const Pod_Type, N>& data)
|
inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(
|
return const_buffers_1(
|
||||||
const_buffer(data.data(), data.size() * sizeof(Pod_Type)));
|
const_buffer(data.data(), data.size() * sizeof(PodType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline const_buffer_container_1 buffer(boost::array<const Pod_Type, N>& data,
|
inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
|
||||||
std::size_t max_size_in_bytes)
|
std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(
|
return const_buffers_1(
|
||||||
const_buffer(data.data(),
|
const_buffer(data.data(),
|
||||||
data.size() * sizeof(Pod_Type) < max_size_in_bytes
|
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||||
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
|
? data.size() * sizeof(PodType) : max_size_in_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline const_buffer_container_1 buffer(const boost::array<Pod_Type, N>& data)
|
inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(
|
return const_buffers_1(
|
||||||
const_buffer(data.data(), data.size() * sizeof(Pod_Type)));
|
const_buffer(data.data(), data.size() * sizeof(PodType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||||
template <typename Pod_Type, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
inline const_buffer_container_1 buffer(const boost::array<Pod_Type, N>& data,
|
inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
|
||||||
std::size_t max_size_in_bytes)
|
std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(
|
return const_buffers_1(
|
||||||
const_buffer(data.data(),
|
const_buffer(data.data(),
|
||||||
data.size() * sizeof(Pod_Type) < max_size_in_bytes
|
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||||
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
|
? data.size() * sizeof(PodType) : max_size_in_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new modifiable buffer that represents the given POD vector.
|
/// Create a new modifiable buffer that represents the given POD vector.
|
||||||
@ -556,11 +667,17 @@ inline const_buffer_container_1 buffer(const boost::array<Pod_Type, N>& data,
|
|||||||
* @note The buffer is invalidated by any vector operation that would also
|
* @note The buffer is invalidated by any vector operation that would also
|
||||||
* invalidate iterators.
|
* invalidate iterators.
|
||||||
*/
|
*/
|
||||||
template <typename Pod_Type, typename Allocator>
|
template <typename PodType, typename Allocator>
|
||||||
inline mutable_buffer_container_1 buffer(std::vector<Pod_Type, Allocator>& data)
|
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
|
||||||
{
|
{
|
||||||
return mutable_buffer_container_1(
|
return mutable_buffers_1(
|
||||||
mutable_buffer(&data[0], data.size() * sizeof(Pod_Type)));
|
mutable_buffer(&data[0], data.size() * sizeof(PodType)
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, detail::buffer_debug_check<
|
||||||
|
typename std::vector<PodType, Allocator>::iterator
|
||||||
|
>(data.begin())
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new modifiable buffer that represents the given POD vector.
|
/// Create a new modifiable buffer that represents the given POD vector.
|
||||||
@ -568,14 +685,20 @@ inline mutable_buffer_container_1 buffer(std::vector<Pod_Type, Allocator>& data)
|
|||||||
* @note The buffer is invalidated by any vector operation that would also
|
* @note The buffer is invalidated by any vector operation that would also
|
||||||
* invalidate iterators.
|
* invalidate iterators.
|
||||||
*/
|
*/
|
||||||
template <typename Pod_Type, typename Allocator>
|
template <typename PodType, typename Allocator>
|
||||||
inline mutable_buffer_container_1 buffer(std::vector<Pod_Type, Allocator>& data,
|
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
|
||||||
std::size_t max_size_in_bytes)
|
std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return mutable_buffer_container_1(
|
return mutable_buffers_1(
|
||||||
mutable_buffer(&data[0],
|
mutable_buffer(&data[0],
|
||||||
data.size() * sizeof(Pod_Type) < max_size_in_bytes
|
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||||
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
|
? data.size() * sizeof(PodType) : max_size_in_bytes
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, detail::buffer_debug_check<
|
||||||
|
typename std::vector<PodType, Allocator>::iterator
|
||||||
|
>(data.begin())
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given POD vector.
|
/// Create a new non-modifiable buffer that represents the given POD vector.
|
||||||
@ -583,12 +706,18 @@ inline mutable_buffer_container_1 buffer(std::vector<Pod_Type, Allocator>& data,
|
|||||||
* @note The buffer is invalidated by any vector operation that would also
|
* @note The buffer is invalidated by any vector operation that would also
|
||||||
* invalidate iterators.
|
* invalidate iterators.
|
||||||
*/
|
*/
|
||||||
template <typename Pod_Type, typename Allocator>
|
template <typename PodType, typename Allocator>
|
||||||
inline const_buffer_container_1 buffer(
|
inline const_buffers_1 buffer(
|
||||||
const std::vector<Pod_Type, Allocator>& data)
|
const std::vector<PodType, Allocator>& data)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(
|
return const_buffers_1(
|
||||||
const_buffer(&data[0], data.size() * sizeof(Pod_Type)));
|
const_buffer(&data[0], data.size() * sizeof(PodType)
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, detail::buffer_debug_check<
|
||||||
|
typename std::vector<PodType, Allocator>::const_iterator
|
||||||
|
>(data.begin())
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given POD vector.
|
/// Create a new non-modifiable buffer that represents the given POD vector.
|
||||||
@ -596,14 +725,20 @@ inline const_buffer_container_1 buffer(
|
|||||||
* @note The buffer is invalidated by any vector operation that would also
|
* @note The buffer is invalidated by any vector operation that would also
|
||||||
* invalidate iterators.
|
* invalidate iterators.
|
||||||
*/
|
*/
|
||||||
template <typename Pod_Type, typename Allocator>
|
template <typename PodType, typename Allocator>
|
||||||
inline const_buffer_container_1 buffer(
|
inline const_buffers_1 buffer(
|
||||||
const std::vector<Pod_Type, Allocator>& data, std::size_t max_size_in_bytes)
|
const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(
|
return const_buffers_1(
|
||||||
const_buffer(&data[0],
|
const_buffer(&data[0],
|
||||||
data.size() * sizeof(Pod_Type) < max_size_in_bytes
|
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||||
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
|
? data.size() * sizeof(PodType) : max_size_in_bytes
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, detail::buffer_debug_check<
|
||||||
|
typename std::vector<PodType, Allocator>::const_iterator
|
||||||
|
>(data.begin())
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given string.
|
/// Create a new non-modifiable buffer that represents the given string.
|
||||||
@ -611,9 +746,13 @@ inline const_buffer_container_1 buffer(
|
|||||||
* @note The buffer is invalidated by any non-const operation called on the
|
* @note The buffer is invalidated by any non-const operation called on the
|
||||||
* given string object.
|
* given string object.
|
||||||
*/
|
*/
|
||||||
inline const_buffer_container_1 buffer(const std::string& data)
|
inline const_buffers_1 buffer(const std::string& data)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(const_buffer(data.data(), data.size()));
|
return const_buffers_1(const_buffer(data.data(), data.size()
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new non-modifiable buffer that represents the given string.
|
/// Create a new non-modifiable buffer that represents the given string.
|
||||||
@ -621,13 +760,17 @@ inline const_buffer_container_1 buffer(const std::string& data)
|
|||||||
* @note The buffer is invalidated by any non-const operation called on the
|
* @note The buffer is invalidated by any non-const operation called on the
|
||||||
* given string object.
|
* given string object.
|
||||||
*/
|
*/
|
||||||
inline const_buffer_container_1 buffer(const std::string& data,
|
inline const_buffers_1 buffer(const std::string& data,
|
||||||
std::size_t max_size_in_bytes)
|
std::size_t max_size_in_bytes)
|
||||||
{
|
{
|
||||||
return const_buffer_container_1(
|
return const_buffers_1(
|
||||||
const_buffer(data.data(),
|
const_buffer(data.data(),
|
||||||
data.size() < max_size_in_bytes
|
data.size() < max_size_in_bytes
|
||||||
? data.size() : max_size_in_bytes));
|
? data.size() : max_size_in_bytes
|
||||||
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
|
||||||
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// buffered_read_stream.hpp
|
// buffered_read_stream.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -40,13 +40,12 @@ namespace asio {
|
|||||||
* The buffered_read_stream class template can be used to add buffering to the
|
* The buffered_read_stream class template can be used to add buffering to the
|
||||||
* synchronous and asynchronous read operations of a stream.
|
* synchronous and asynchronous read operations of a stream.
|
||||||
*
|
*
|
||||||
* @par Thread Safety:
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
*
|
||||||
* @par Concepts:
|
* @par Concepts:
|
||||||
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
|
* AsyncReadStream, AsyncWriteStream, Stream, Sync_Read_Stream, SyncWriteStream.
|
||||||
* Sync_Read_Stream, Sync_Write_Stream.
|
|
||||||
*/
|
*/
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
class buffered_read_stream
|
class buffered_read_stream
|
||||||
@ -59,9 +58,6 @@ public:
|
|||||||
/// The type of the lowest layer.
|
/// The type of the lowest layer.
|
||||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||||
|
|
||||||
/// The type used for reporting errors.
|
|
||||||
typedef typename next_layer_type::error_type error_type;
|
|
||||||
|
|
||||||
#if defined(GENERATING_DOCUMENTATION)
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
/// The default buffer size.
|
/// The default buffer size.
|
||||||
static const std::size_t default_buffer_size = implementation_defined;
|
static const std::size_t default_buffer_size = implementation_defined;
|
||||||
@ -110,33 +106,33 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Close the stream.
|
/// Close the stream.
|
||||||
template <typename Error_Handler>
|
asio::error_code close(asio::error_code& ec)
|
||||||
void close(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
next_layer_.close(error_handler);
|
return next_layer_.close(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the given data to the stream. Returns the number of bytes written.
|
/// Write the given data to the stream. Returns the number of bytes written.
|
||||||
/// Throws an exception on failure.
|
/// Throws an exception on failure.
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t write_some(const Const_Buffers& buffers)
|
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return next_layer_.write_some(buffers);
|
return next_layer_.write_some(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the given data to the stream. Returns the number of bytes written,
|
/// Write the given data to the stream. Returns the number of bytes written,
|
||||||
/// or 0 if an error occurred and the error handler did not throw.
|
/// or 0 if an error occurred.
|
||||||
template <typename Const_Buffers, typename Error_Handler>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t write_some(const Const_Buffers& buffers,
|
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return next_layer_.write_some(buffers, error_handler);
|
return next_layer_.write_some(buffers, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous write. The data being written must be valid for the
|
/// Start an asynchronous write. The data being written must be valid for the
|
||||||
/// lifetime of the asynchronous operation.
|
/// lifetime of the asynchronous operation.
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_write_some(const Const_Buffers& buffers, Handler handler)
|
void async_write_some(const ConstBufferSequence& buffers,
|
||||||
|
WriteHandler handler)
|
||||||
{
|
{
|
||||||
next_layer_.async_write_some(buffers, handler);
|
next_layer_.async_write_some(buffers, handler);
|
||||||
}
|
}
|
||||||
@ -157,10 +153,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Fill the buffer with some data. Returns the number of bytes placed in the
|
/// Fill the buffer with some data. Returns the number of bytes placed in the
|
||||||
/// buffer as a result of the operation, or 0 if an error occurred and the
|
/// buffer as a result of the operation, or 0 if an error occurred.
|
||||||
/// error handler did not throw.
|
std::size_t fill(asio::error_code& ec)
|
||||||
template <typename Error_Handler>
|
|
||||||
std::size_t fill(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
detail::buffer_resize_guard<detail::buffered_stream_storage>
|
detail::buffer_resize_guard<detail::buffered_stream_storage>
|
||||||
resize_guard(storage_);
|
resize_guard(storage_);
|
||||||
@ -169,18 +163,18 @@ public:
|
|||||||
storage_.resize(previous_size + next_layer_.read_some(buffer(
|
storage_.resize(previous_size + next_layer_.read_some(buffer(
|
||||||
storage_.data() + previous_size,
|
storage_.data() + previous_size,
|
||||||
storage_.size() - previous_size),
|
storage_.size() - previous_size),
|
||||||
error_handler));
|
ec));
|
||||||
resize_guard.commit();
|
resize_guard.commit();
|
||||||
return storage_.size() - previous_size;
|
return storage_.size() - previous_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Handler>
|
template <typename ReadHandler>
|
||||||
class fill_handler
|
class fill_handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
fill_handler(asio::io_service& io_service,
|
fill_handler(asio::io_service& io_service,
|
||||||
detail::buffered_stream_storage& storage,
|
detail::buffered_stream_storage& storage,
|
||||||
std::size_t previous_size, Handler handler)
|
std::size_t previous_size, ReadHandler handler)
|
||||||
: io_service_(io_service),
|
: io_service_(io_service),
|
||||||
storage_(storage),
|
storage_(storage),
|
||||||
previous_size_(previous_size),
|
previous_size_(previous_size),
|
||||||
@ -188,24 +182,24 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Error>
|
void operator()(const asio::error_code& ec,
|
||||||
void operator()(const Error& e, std::size_t bytes_transferred)
|
std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
storage_.resize(previous_size_ + bytes_transferred);
|
storage_.resize(previous_size_ + bytes_transferred);
|
||||||
io_service_.dispatch(detail::bind_handler(
|
io_service_.dispatch(detail::bind_handler(
|
||||||
handler_, e, bytes_transferred));
|
handler_, ec, bytes_transferred));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
asio::io_service& io_service_;
|
asio::io_service& io_service_;
|
||||||
detail::buffered_stream_storage& storage_;
|
detail::buffered_stream_storage& storage_;
|
||||||
std::size_t previous_size_;
|
std::size_t previous_size_;
|
||||||
Handler handler_;
|
ReadHandler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Start an asynchronous fill.
|
/// Start an asynchronous fill.
|
||||||
template <typename Handler>
|
template <typename ReadHandler>
|
||||||
void async_fill(Handler handler)
|
void async_fill(ReadHandler handler)
|
||||||
{
|
{
|
||||||
std::size_t previous_size = storage_.size();
|
std::size_t previous_size = storage_.size();
|
||||||
storage_.resize(storage_.capacity());
|
storage_.resize(storage_.capacity());
|
||||||
@ -213,13 +207,14 @@ public:
|
|||||||
buffer(
|
buffer(
|
||||||
storage_.data() + previous_size,
|
storage_.data() + previous_size,
|
||||||
storage_.size() - previous_size),
|
storage_.size() - previous_size),
|
||||||
fill_handler<Handler>(io_service(), storage_, previous_size, handler));
|
fill_handler<ReadHandler>(io_service(),
|
||||||
|
storage_, previous_size, handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read some data from the stream. Returns the number of bytes read. Throws
|
/// Read some data from the stream. Returns the number of bytes read. Throws
|
||||||
/// an exception on failure.
|
/// an exception on failure.
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t read_some(const Mutable_Buffers& buffers)
|
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
if (storage_.empty())
|
if (storage_.empty())
|
||||||
fill();
|
fill();
|
||||||
@ -227,23 +222,24 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read some data from the stream. Returns the number of bytes read or 0 if
|
/// Read some data from the stream. Returns the number of bytes read or 0 if
|
||||||
/// an error occurred and the error handler did not throw an exception.
|
/// an error occurred.
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t read_some(const Mutable_Buffers& buffers,
|
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (storage_.empty() && !fill(error_handler))
|
ec = asio::error_code();
|
||||||
|
if (storage_.empty() && !fill(ec))
|
||||||
return 0;
|
return 0;
|
||||||
return copy(buffers);
|
return copy(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
class read_some_handler
|
class read_some_handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
read_some_handler(asio::io_service& io_service,
|
read_some_handler(asio::io_service& io_service,
|
||||||
detail::buffered_stream_storage& storage,
|
detail::buffered_stream_storage& storage,
|
||||||
const Mutable_Buffers& buffers, Handler handler)
|
const MutableBufferSequence& buffers, ReadHandler handler)
|
||||||
: io_service_(io_service),
|
: io_service_(io_service),
|
||||||
storage_(storage),
|
storage_(storage),
|
||||||
buffers_(buffers),
|
buffers_(buffers),
|
||||||
@ -251,12 +247,12 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const error_type& e, std::size_t)
|
void operator()(const asio::error_code& ec, std::size_t)
|
||||||
{
|
{
|
||||||
if (e || storage_.empty())
|
if (ec || storage_.empty())
|
||||||
{
|
{
|
||||||
std::size_t length = 0;
|
std::size_t length = 0;
|
||||||
io_service_.dispatch(detail::bind_handler(handler_, e, length));
|
io_service_.dispatch(detail::bind_handler(handler_, ec, length));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -265,8 +261,8 @@ public:
|
|||||||
std::size_t bytes_avail = storage_.size();
|
std::size_t bytes_avail = storage_.size();
|
||||||
std::size_t bytes_copied = 0;
|
std::size_t bytes_copied = 0;
|
||||||
|
|
||||||
typename Mutable_Buffers::const_iterator iter = buffers_.begin();
|
typename MutableBufferSequence::const_iterator iter = buffers_.begin();
|
||||||
typename Mutable_Buffers::const_iterator end = buffers_.end();
|
typename MutableBufferSequence::const_iterator end = buffers_.end();
|
||||||
for (; iter != end && bytes_avail > 0; ++iter)
|
for (; iter != end && bytes_avail > 0; ++iter)
|
||||||
{
|
{
|
||||||
std::size_t max_length = buffer_size(*iter);
|
std::size_t max_length = buffer_size(*iter);
|
||||||
@ -279,38 +275,40 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
storage_.consume(bytes_copied);
|
storage_.consume(bytes_copied);
|
||||||
io_service_.dispatch(detail::bind_handler(handler_, e, bytes_copied));
|
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
asio::io_service& io_service_;
|
asio::io_service& io_service_;
|
||||||
detail::buffered_stream_storage& storage_;
|
detail::buffered_stream_storage& storage_;
|
||||||
Mutable_Buffers buffers_;
|
MutableBufferSequence buffers_;
|
||||||
Handler handler_;
|
ReadHandler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Start an asynchronous read. The buffer into which the data will be read
|
/// Start an asynchronous read. The buffer into which the data will be read
|
||||||
/// must be valid for the lifetime of the asynchronous operation.
|
/// must be valid for the lifetime of the asynchronous operation.
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
|
void async_read_some(const MutableBufferSequence& buffers,
|
||||||
|
ReadHandler handler)
|
||||||
{
|
{
|
||||||
if (storage_.empty())
|
if (storage_.empty())
|
||||||
{
|
{
|
||||||
async_fill(read_some_handler<Mutable_Buffers, Handler>(
|
async_fill(read_some_handler<MutableBufferSequence, ReadHandler>(
|
||||||
io_service(), storage_, buffers, handler));
|
io_service(), storage_, buffers, handler));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::size_t length = copy(buffers);
|
std::size_t length = copy(buffers);
|
||||||
io_service().post(detail::bind_handler(handler, 0, length));
|
io_service().post(detail::bind_handler(
|
||||||
|
handler, asio::error_code(), length));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
||||||
/// Throws an exception on failure.
|
/// Throws an exception on failure.
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t peek(const Mutable_Buffers& buffers)
|
std::size_t peek(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
if (storage_.empty())
|
if (storage_.empty())
|
||||||
fill();
|
fill();
|
||||||
@ -318,11 +316,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Peek at the incoming data on the stream. Returns the number of bytes read,
|
/// Peek at the incoming data on the stream. Returns the number of bytes read,
|
||||||
/// or 0 if an error occurred and the error handler did not throw.
|
/// or 0 if an error occurred.
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
|
std::size_t peek(const MutableBufferSequence& buffers,
|
||||||
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (storage_.empty() && !fill(error_handler))
|
ec = asio::error_code();
|
||||||
|
if (storage_.empty() && !fill(ec))
|
||||||
return 0;
|
return 0;
|
||||||
return peek_copy(buffers);
|
return peek_copy(buffers);
|
||||||
}
|
}
|
||||||
@ -334,25 +334,25 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Determine the amount of data that may be read without blocking.
|
/// Determine the amount of data that may be read without blocking.
|
||||||
template <typename Error_Handler>
|
std::size_t in_avail(asio::error_code& ec)
|
||||||
std::size_t in_avail(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
|
ec = asio::error_code();
|
||||||
return storage_.size();
|
return storage_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Copy data out of the internal buffer to the specified target buffer.
|
/// Copy data out of the internal buffer to the specified target buffer.
|
||||||
/// Returns the number of bytes copied.
|
/// Returns the number of bytes copied.
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t copy(const Mutable_Buffers& buffers)
|
std::size_t copy(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
using namespace std; // For memcpy.
|
using namespace std; // For memcpy.
|
||||||
|
|
||||||
std::size_t bytes_avail = storage_.size();
|
std::size_t bytes_avail = storage_.size();
|
||||||
std::size_t bytes_copied = 0;
|
std::size_t bytes_copied = 0;
|
||||||
|
|
||||||
typename Mutable_Buffers::const_iterator iter = buffers.begin();
|
typename MutableBufferSequence::const_iterator iter = buffers.begin();
|
||||||
typename Mutable_Buffers::const_iterator end = buffers.end();
|
typename MutableBufferSequence::const_iterator end = buffers.end();
|
||||||
for (; iter != end && bytes_avail > 0; ++iter)
|
for (; iter != end && bytes_avail > 0; ++iter)
|
||||||
{
|
{
|
||||||
std::size_t max_length = buffer_size(*iter);
|
std::size_t max_length = buffer_size(*iter);
|
||||||
@ -370,16 +370,16 @@ private:
|
|||||||
/// Copy data from the internal buffer to the specified target buffer, without
|
/// Copy data from the internal buffer to the specified target buffer, without
|
||||||
/// removing the data from the internal buffer. Returns the number of bytes
|
/// removing the data from the internal buffer. Returns the number of bytes
|
||||||
/// copied.
|
/// copied.
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t peek_copy(const Mutable_Buffers& buffers)
|
std::size_t peek_copy(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
using namespace std; // For memcpy.
|
using namespace std; // For memcpy.
|
||||||
|
|
||||||
std::size_t bytes_avail = storage_.size();
|
std::size_t bytes_avail = storage_.size();
|
||||||
std::size_t bytes_copied = 0;
|
std::size_t bytes_copied = 0;
|
||||||
|
|
||||||
typename Mutable_Buffers::const_iterator iter = buffers.begin();
|
typename MutableBufferSequence::const_iterator iter = buffers.begin();
|
||||||
typename Mutable_Buffers::const_iterator end = buffers.end();
|
typename MutableBufferSequence::const_iterator end = buffers.end();
|
||||||
for (; iter != end && bytes_avail > 0; ++iter)
|
for (; iter != end && bytes_avail > 0; ++iter)
|
||||||
{
|
{
|
||||||
std::size_t max_length = buffer_size(*iter);
|
std::size_t max_length = buffer_size(*iter);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// buffered_read_stream_fwd.hpp
|
// buffered_read_stream_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// buffered_stream.hpp
|
// buffered_stream.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -36,13 +36,12 @@ namespace asio {
|
|||||||
* The buffered_stream class template can be used to add buffering to the
|
* The buffered_stream class template can be used to add buffering to the
|
||||||
* synchronous and asynchronous read and write operations of a stream.
|
* synchronous and asynchronous read and write operations of a stream.
|
||||||
*
|
*
|
||||||
* @par Thread Safety:
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
*
|
||||||
* @par Concepts:
|
* @par Concepts:
|
||||||
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
|
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||||
* Sync_Read_Stream, Sync_Write_Stream.
|
|
||||||
*/
|
*/
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
class buffered_stream
|
class buffered_stream
|
||||||
@ -55,9 +54,6 @@ public:
|
|||||||
/// The type of the lowest layer.
|
/// The type of the lowest layer.
|
||||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||||
|
|
||||||
/// The type used for reporting errors.
|
|
||||||
typedef typename next_layer_type::error_type error_type;
|
|
||||||
|
|
||||||
/// Construct, passing the specified argument to initialise the next layer.
|
/// Construct, passing the specified argument to initialise the next layer.
|
||||||
template <typename Arg>
|
template <typename Arg>
|
||||||
explicit buffered_stream(Arg& a)
|
explicit buffered_stream(Arg& a)
|
||||||
@ -100,10 +96,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Close the stream.
|
/// Close the stream.
|
||||||
template <typename Error_Handler>
|
asio::error_code close(asio::error_code& ec)
|
||||||
void close(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
stream_impl_.close(error_handler);
|
return stream_impl_.close(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||||
@ -116,41 +111,41 @@ public:
|
|||||||
|
|
||||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||||
/// bytes written to the next layer on the last write operation, or 0 if an
|
/// bytes written to the next layer on the last write operation, or 0 if an
|
||||||
/// error occurred and the error handler did not throw.
|
/// error occurred.
|
||||||
template <typename Error_Handler>
|
std::size_t flush(asio::error_code& ec)
|
||||||
std::size_t flush(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
return stream_impl_.next_layer().flush(error_handler);
|
return stream_impl_.next_layer().flush(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous flush.
|
/// Start an asynchronous flush.
|
||||||
template <typename Handler>
|
template <typename WriteHandler>
|
||||||
void async_flush(Handler handler)
|
void async_flush(WriteHandler handler)
|
||||||
{
|
{
|
||||||
return stream_impl_.next_layer().async_flush(handler);
|
return stream_impl_.next_layer().async_flush(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the given data to the stream. Returns the number of bytes written.
|
/// Write the given data to the stream. Returns the number of bytes written.
|
||||||
/// Throws an exception on failure.
|
/// Throws an exception on failure.
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t write_some(const Const_Buffers& buffers)
|
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return stream_impl_.write_some(buffers);
|
return stream_impl_.write_some(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the given data to the stream. Returns the number of bytes written,
|
/// Write the given data to the stream. Returns the number of bytes written,
|
||||||
/// or 0 if an error occurred and the error handler did not throw.
|
/// or 0 if an error occurred.
|
||||||
template <typename Const_Buffers, typename Error_Handler>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t write_some(const Const_Buffers& buffers,
|
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return stream_impl_.write_some(buffers, error_handler);
|
return stream_impl_.write_some(buffers, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous write. The data being written must be valid for the
|
/// Start an asynchronous write. The data being written must be valid for the
|
||||||
/// lifetime of the asynchronous operation.
|
/// lifetime of the asynchronous operation.
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_write_some(const Const_Buffers& buffers, Handler handler)
|
void async_write_some(const ConstBufferSequence& buffers,
|
||||||
|
WriteHandler handler)
|
||||||
{
|
{
|
||||||
stream_impl_.async_write_some(buffers, handler);
|
stream_impl_.async_write_some(buffers, handler);
|
||||||
}
|
}
|
||||||
@ -163,60 +158,60 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Fill the buffer with some data. Returns the number of bytes placed in the
|
/// Fill the buffer with some data. Returns the number of bytes placed in the
|
||||||
/// buffer as a result of the operation, or 0 if an error occurred and the
|
/// buffer as a result of the operation, or 0 if an error occurred.
|
||||||
/// error handler did not throw.
|
std::size_t fill(asio::error_code& ec)
|
||||||
template <typename Error_Handler>
|
|
||||||
std::size_t fill(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
return stream_impl_.fill(error_handler);
|
return stream_impl_.fill(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous fill.
|
/// Start an asynchronous fill.
|
||||||
template <typename Handler>
|
template <typename ReadHandler>
|
||||||
void async_fill(Handler handler)
|
void async_fill(ReadHandler handler)
|
||||||
{
|
{
|
||||||
stream_impl_.async_fill(handler);
|
stream_impl_.async_fill(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read some data from the stream. Returns the number of bytes read. Throws
|
/// Read some data from the stream. Returns the number of bytes read. Throws
|
||||||
/// an exception on failure.
|
/// an exception on failure.
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t read_some(const Mutable_Buffers& buffers)
|
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return stream_impl_.read_some(buffers);
|
return stream_impl_.read_some(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read some data from the stream. Returns the number of bytes read or 0 if
|
/// Read some data from the stream. Returns the number of bytes read or 0 if
|
||||||
/// an error occurred and the error handler did not throw an exception.
|
/// an error occurred.
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t read_some(const Mutable_Buffers& buffers,
|
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return stream_impl_.read_some(buffers, error_handler);
|
return stream_impl_.read_some(buffers, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous read. The buffer into which the data will be read
|
/// Start an asynchronous read. The buffer into which the data will be read
|
||||||
/// must be valid for the lifetime of the asynchronous operation.
|
/// must be valid for the lifetime of the asynchronous operation.
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
|
void async_read_some(const MutableBufferSequence& buffers,
|
||||||
|
ReadHandler handler)
|
||||||
{
|
{
|
||||||
stream_impl_.async_read_some(buffers, handler);
|
stream_impl_.async_read_some(buffers, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
||||||
/// Throws an exception on failure.
|
/// Throws an exception on failure.
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t peek(const Mutable_Buffers& buffers)
|
std::size_t peek(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return stream_impl_.peek(buffers);
|
return stream_impl_.peek(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peek at the incoming data on the stream. Returns the number of bytes read,
|
/// Peek at the incoming data on the stream. Returns the number of bytes read,
|
||||||
/// or 0 if an error occurred and the error handler did not throw.
|
/// or 0 if an error occurred.
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
|
std::size_t peek(const MutableBufferSequence& buffers,
|
||||||
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return stream_impl_.peek(buffers, error_handler);
|
return stream_impl_.peek(buffers, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine the amount of data that may be read without blocking.
|
/// Determine the amount of data that may be read without blocking.
|
||||||
@ -226,10 +221,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Determine the amount of data that may be read without blocking.
|
/// Determine the amount of data that may be read without blocking.
|
||||||
template <typename Error_Handler>
|
std::size_t in_avail(asio::error_code& ec)
|
||||||
std::size_t in_avail(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
return stream_impl_.in_avail(error_handler);
|
return stream_impl_.in_avail(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// buffered_stream_fwd.hpp
|
// buffered_stream_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// buffered_write_stream.hpp
|
// buffered_write_stream.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -41,13 +41,12 @@ namespace asio {
|
|||||||
* The buffered_write_stream class template can be used to add buffering to the
|
* The buffered_write_stream class template can be used to add buffering to the
|
||||||
* synchronous and asynchronous write operations of a stream.
|
* synchronous and asynchronous write operations of a stream.
|
||||||
*
|
*
|
||||||
* @par Thread Safety:
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
*
|
||||||
* @par Concepts:
|
* @par Concepts:
|
||||||
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
|
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||||
* Sync_Read_Stream, Sync_Write_Stream.
|
|
||||||
*/
|
*/
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
class buffered_write_stream
|
class buffered_write_stream
|
||||||
@ -60,9 +59,6 @@ public:
|
|||||||
/// The type of the lowest layer.
|
/// The type of the lowest layer.
|
||||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||||
|
|
||||||
/// The type used for reporting errors.
|
|
||||||
typedef typename next_layer_type::error_type error_type;
|
|
||||||
|
|
||||||
#if defined(GENERATING_DOCUMENTATION)
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
/// The default buffer size.
|
/// The default buffer size.
|
||||||
static const std::size_t default_buffer_size = implementation_defined;
|
static const std::size_t default_buffer_size = implementation_defined;
|
||||||
@ -111,10 +107,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Close the stream.
|
/// Close the stream.
|
||||||
template <typename Error_Handler>
|
asio::error_code close(asio::error_code& ec)
|
||||||
void close(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
next_layer_.close(error_handler);
|
return next_layer_.close(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||||
@ -130,53 +125,53 @@ public:
|
|||||||
|
|
||||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||||
/// bytes written to the next layer on the last write operation, or 0 if an
|
/// bytes written to the next layer on the last write operation, or 0 if an
|
||||||
/// error occurred and the error handler did not throw.
|
/// error occurred.
|
||||||
template <typename Error_Handler>
|
std::size_t flush(asio::error_code& ec)
|
||||||
std::size_t flush(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
std::size_t bytes_written = write(next_layer_,
|
std::size_t bytes_written = write(next_layer_,
|
||||||
buffer(storage_.data(), storage_.size()),
|
buffer(storage_.data(), storage_.size()),
|
||||||
transfer_all(), error_handler);
|
transfer_all(), ec);
|
||||||
storage_.consume(bytes_written);
|
storage_.consume(bytes_written);
|
||||||
return bytes_written;
|
return bytes_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Handler>
|
template <typename WriteHandler>
|
||||||
class flush_handler
|
class flush_handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
flush_handler(asio::io_service& io_service,
|
flush_handler(asio::io_service& io_service,
|
||||||
detail::buffered_stream_storage& storage, Handler handler)
|
detail::buffered_stream_storage& storage, WriteHandler handler)
|
||||||
: io_service_(io_service),
|
: io_service_(io_service),
|
||||||
storage_(storage),
|
storage_(storage),
|
||||||
handler_(handler)
|
handler_(handler)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const error_type& e, std::size_t bytes_written)
|
void operator()(const asio::error_code& ec,
|
||||||
|
std::size_t bytes_written)
|
||||||
{
|
{
|
||||||
storage_.consume(bytes_written);
|
storage_.consume(bytes_written);
|
||||||
io_service_.dispatch(detail::bind_handler(handler_, e, bytes_written));
|
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_written));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
asio::io_service& io_service_;
|
asio::io_service& io_service_;
|
||||||
detail::buffered_stream_storage& storage_;
|
detail::buffered_stream_storage& storage_;
|
||||||
Handler handler_;
|
WriteHandler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Start an asynchronous flush.
|
/// Start an asynchronous flush.
|
||||||
template <typename Handler>
|
template <typename WriteHandler>
|
||||||
void async_flush(Handler handler)
|
void async_flush(WriteHandler handler)
|
||||||
{
|
{
|
||||||
async_write(next_layer_, buffer(storage_.data(), storage_.size()),
|
async_write(next_layer_, buffer(storage_.data(), storage_.size()),
|
||||||
flush_handler<Handler>(io_service(), storage_, handler));
|
flush_handler<WriteHandler>(io_service(), storage_, handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the given data to the stream. Returns the number of bytes written.
|
/// Write the given data to the stream. Returns the number of bytes written.
|
||||||
/// Throws an exception on failure.
|
/// Throws an exception on failure.
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t write_some(const Const_Buffers& buffers)
|
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
if (storage_.size() == storage_.capacity())
|
if (storage_.size() == storage_.capacity())
|
||||||
flush();
|
flush();
|
||||||
@ -185,22 +180,23 @@ public:
|
|||||||
|
|
||||||
/// Write the given data to the stream. Returns the number of bytes written,
|
/// Write the given data to the stream. Returns the number of bytes written,
|
||||||
/// or 0 if an error occurred and the error handler did not throw.
|
/// or 0 if an error occurred and the error handler did not throw.
|
||||||
template <typename Const_Buffers, typename Error_Handler>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t write_some(const Const_Buffers& buffers,
|
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (storage_.size() == storage_.capacity() && !flush(error_handler))
|
ec = asio::error_code();
|
||||||
|
if (storage_.size() == storage_.capacity() && !flush(ec))
|
||||||
return 0;
|
return 0;
|
||||||
return copy(buffers);
|
return copy(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
class write_some_handler
|
class write_some_handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
write_some_handler(asio::io_service& io_service,
|
write_some_handler(asio::io_service& io_service,
|
||||||
detail::buffered_stream_storage& storage,
|
detail::buffered_stream_storage& storage,
|
||||||
const Const_Buffers& buffers, Handler handler)
|
const ConstBufferSequence& buffers, WriteHandler handler)
|
||||||
: io_service_(io_service),
|
: io_service_(io_service),
|
||||||
storage_(storage),
|
storage_(storage),
|
||||||
buffers_(buffers),
|
buffers_(buffers),
|
||||||
@ -208,12 +204,12 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const error_type& e, std::size_t)
|
void operator()(const asio::error_code& ec, std::size_t)
|
||||||
{
|
{
|
||||||
if (e)
|
if (ec)
|
||||||
{
|
{
|
||||||
std::size_t length = 0;
|
std::size_t length = 0;
|
||||||
io_service_.dispatch(detail::bind_handler(handler_, e, length));
|
io_service_.dispatch(detail::bind_handler(handler_, ec, length));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -223,8 +219,8 @@ public:
|
|||||||
std::size_t space_avail = storage_.capacity() - orig_size;
|
std::size_t space_avail = storage_.capacity() - orig_size;
|
||||||
std::size_t bytes_copied = 0;
|
std::size_t bytes_copied = 0;
|
||||||
|
|
||||||
typename Const_Buffers::const_iterator iter = buffers_.begin();
|
typename ConstBufferSequence::const_iterator iter = buffers_.begin();
|
||||||
typename Const_Buffers::const_iterator end = buffers_.end();
|
typename ConstBufferSequence::const_iterator end = buffers_.end();
|
||||||
for (; iter != end && space_avail > 0; ++iter)
|
for (; iter != end && space_avail > 0; ++iter)
|
||||||
{
|
{
|
||||||
std::size_t bytes_avail = buffer_size(*iter);
|
std::size_t bytes_avail = buffer_size(*iter);
|
||||||
@ -237,73 +233,77 @@ public:
|
|||||||
space_avail -= length;
|
space_avail -= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
io_service_.dispatch(detail::bind_handler(handler_, e, bytes_copied));
|
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
asio::io_service& io_service_;
|
asio::io_service& io_service_;
|
||||||
detail::buffered_stream_storage& storage_;
|
detail::buffered_stream_storage& storage_;
|
||||||
Const_Buffers buffers_;
|
ConstBufferSequence buffers_;
|
||||||
Handler handler_;
|
WriteHandler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Start an asynchronous write. The data being written must be valid for the
|
/// Start an asynchronous write. The data being written must be valid for the
|
||||||
/// lifetime of the asynchronous operation.
|
/// lifetime of the asynchronous operation.
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_write_some(const Const_Buffers& buffers, Handler handler)
|
void async_write_some(const ConstBufferSequence& buffers,
|
||||||
|
WriteHandler handler)
|
||||||
{
|
{
|
||||||
if (storage_.size() == storage_.capacity())
|
if (storage_.size() == storage_.capacity())
|
||||||
{
|
{
|
||||||
async_flush(write_some_handler<Const_Buffers, Handler>(
|
async_flush(write_some_handler<ConstBufferSequence, WriteHandler>(
|
||||||
io_service(), storage_, buffers, handler));
|
io_service(), storage_, buffers, handler));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::size_t bytes_copied = copy(buffers);
|
std::size_t bytes_copied = copy(buffers);
|
||||||
io_service().post(detail::bind_handler(handler, 0, bytes_copied));
|
io_service().post(detail::bind_handler(
|
||||||
|
handler, asio::error_code(), bytes_copied));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read some data from the stream. Returns the number of bytes read. Throws
|
/// Read some data from the stream. Returns the number of bytes read. Throws
|
||||||
/// an exception on failure.
|
/// an exception on failure.
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t read_some(const Mutable_Buffers& buffers)
|
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return next_layer_.read_some(buffers);
|
return next_layer_.read_some(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read some data from the stream. Returns the number of bytes read or 0 if
|
/// Read some data from the stream. Returns the number of bytes read or 0 if
|
||||||
/// an error occurred and the error handler did not throw an exception.
|
/// an error occurred.
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t read_some(const Mutable_Buffers& buffers,
|
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return next_layer_.read_some(buffers, error_handler);
|
return next_layer_.read_some(buffers, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous read. The buffer into which the data will be read
|
/// Start an asynchronous read. The buffer into which the data will be read
|
||||||
/// must be valid for the lifetime of the asynchronous operation.
|
/// must be valid for the lifetime of the asynchronous operation.
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
|
void async_read_some(const MutableBufferSequence& buffers,
|
||||||
|
ReadHandler handler)
|
||||||
{
|
{
|
||||||
next_layer_.async_read_some(buffers, handler);
|
next_layer_.async_read_some(buffers, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
||||||
/// Throws an exception on failure.
|
/// Throws an exception on failure.
|
||||||
template <typename Mutable_Buffers>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t peek(const Mutable_Buffers& buffers)
|
std::size_t peek(const MutableBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
return next_layer_.peek(buffers);
|
return next_layer_.peek(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peek at the incoming data on the stream. Returns the number of bytes read,
|
/// Peek at the incoming data on the stream. Returns the number of bytes read,
|
||||||
/// or 0 if an error occurred and the error handler did not throw.
|
/// or 0 if an error occurred.
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
|
std::size_t peek(const MutableBufferSequence& buffers,
|
||||||
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return next_layer_.peek(buffers, error_handler);
|
return next_layer_.peek(buffers, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine the amount of data that may be read without blocking.
|
/// Determine the amount of data that may be read without blocking.
|
||||||
@ -313,17 +313,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Determine the amount of data that may be read without blocking.
|
/// Determine the amount of data that may be read without blocking.
|
||||||
template <typename Error_Handler>
|
std::size_t in_avail(asio::error_code& ec)
|
||||||
std::size_t in_avail(Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
return next_layer_.in_avail(error_handler);
|
return next_layer_.in_avail(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Copy data into the internal buffer from the specified source buffer.
|
/// Copy data into the internal buffer from the specified source buffer.
|
||||||
/// Returns the number of bytes copied.
|
/// Returns the number of bytes copied.
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t copy(const Const_Buffers& buffers)
|
std::size_t copy(const ConstBufferSequence& buffers)
|
||||||
{
|
{
|
||||||
using namespace std; // For memcpy.
|
using namespace std; // For memcpy.
|
||||||
|
|
||||||
@ -331,8 +330,8 @@ private:
|
|||||||
std::size_t space_avail = storage_.capacity() - orig_size;
|
std::size_t space_avail = storage_.capacity() - orig_size;
|
||||||
std::size_t bytes_copied = 0;
|
std::size_t bytes_copied = 0;
|
||||||
|
|
||||||
typename Const_Buffers::const_iterator iter = buffers.begin();
|
typename ConstBufferSequence::const_iterator iter = buffers.begin();
|
||||||
typename Const_Buffers::const_iterator end = buffers.end();
|
typename ConstBufferSequence::const_iterator end = buffers.end();
|
||||||
for (; iter != end && space_avail > 0; ++iter)
|
for (; iter != end && space_avail > 0; ++iter)
|
||||||
{
|
{
|
||||||
std::size_t bytes_avail = buffer_size(*iter);
|
std::size_t bytes_avail = buffer_size(*iter);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// buffered_write_stream_fwd.hpp
|
// buffered_write_stream_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// completion_condition.hpp
|
// completion_condition.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// datagram_socket_service.hpp
|
// datagram_socket_service.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -22,10 +22,12 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/io_service.hpp"
|
#include "asio/io_service.hpp"
|
||||||
#include "asio/detail/epoll_reactor.hpp"
|
#include "asio/detail/epoll_reactor.hpp"
|
||||||
#include "asio/detail/kqueue_reactor.hpp"
|
#include "asio/detail/kqueue_reactor.hpp"
|
||||||
#include "asio/detail/select_reactor.hpp"
|
#include "asio/detail/select_reactor.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/reactive_socket_service.hpp"
|
#include "asio/detail/reactive_socket_service.hpp"
|
||||||
#include "asio/detail/win_iocp_socket_service.hpp"
|
#include "asio/detail/win_iocp_socket_service.hpp"
|
||||||
|
|
||||||
@ -34,9 +36,18 @@ namespace asio {
|
|||||||
/// Default service implementation for a datagram socket.
|
/// Default service implementation for a datagram socket.
|
||||||
template <typename Protocol>
|
template <typename Protocol>
|
||||||
class datagram_socket_service
|
class datagram_socket_service
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
: public asio::io_service::service
|
: public asio::io_service::service
|
||||||
|
#else
|
||||||
|
: public asio::detail::service_base<datagram_socket_service<Protocol> >
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// The unique service identifier.
|
||||||
|
static asio::io_service::id id;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// The protocol type.
|
/// The protocol type.
|
||||||
typedef Protocol protocol_type;
|
typedef Protocol protocol_type;
|
||||||
|
|
||||||
@ -75,7 +86,8 @@ public:
|
|||||||
|
|
||||||
/// Construct a new datagram socket service for the specified io_service.
|
/// Construct a new datagram socket service for the specified io_service.
|
||||||
explicit datagram_socket_service(asio::io_service& io_service)
|
explicit datagram_socket_service(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<
|
||||||
|
datagram_socket_service<Protocol> >(io_service),
|
||||||
service_impl_(asio::use_service<service_impl_type>(io_service))
|
service_impl_(asio::use_service<service_impl_type>(io_service))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -98,29 +110,35 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open a new datagram socket implementation.
|
// Open a new datagram socket implementation.
|
||||||
template <typename Error_Handler>
|
asio::error_code open(implementation_type& impl,
|
||||||
void open(implementation_type& impl, const protocol_type& protocol,
|
const protocol_type& protocol, asio::error_code& ec)
|
||||||
Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
if (protocol.type() == SOCK_DGRAM)
|
if (protocol.type() == SOCK_DGRAM)
|
||||||
service_impl_.open(impl, protocol, error_handler);
|
service_impl_.open(impl, protocol, ec);
|
||||||
else
|
else
|
||||||
error_handler(asio::error(asio::error::invalid_argument));
|
ec = asio::error::invalid_argument;
|
||||||
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assign an existing native socket to a datagram socket.
|
/// Assign an existing native socket to a datagram socket.
|
||||||
template <typename Error_Handler>
|
asio::error_code assign(implementation_type& impl,
|
||||||
void assign(implementation_type& impl, const protocol_type& protocol,
|
const protocol_type& protocol, const native_type& native_socket,
|
||||||
const native_type& native_socket, Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
service_impl_.assign(impl, protocol, native_socket, error_handler);
|
return service_impl_.assign(impl, protocol, native_socket, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether the socket is open.
|
||||||
|
bool is_open(const implementation_type& impl) const
|
||||||
|
{
|
||||||
|
return service_impl_.is_open(impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close a datagram socket implementation.
|
/// Close a datagram socket implementation.
|
||||||
template <typename Error_Handler>
|
asio::error_code close(implementation_type& impl,
|
||||||
void close(implementation_type& impl, Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
service_impl_.close(impl, error_handler);
|
return service_impl_.close(impl, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the native socket implementation.
|
/// Get the native socket implementation.
|
||||||
@ -130,154 +148,161 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Cancel all asynchronous operations associated with the socket.
|
/// Cancel all asynchronous operations associated with the socket.
|
||||||
template <typename Error_Handler>
|
asio::error_code cancel(implementation_type& impl,
|
||||||
void cancel(implementation_type& impl, Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
service_impl_.cancel(impl, error_handler);
|
return service_impl_.cancel(impl, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether the socket is at the out-of-band data mark.
|
||||||
|
bool at_mark(const implementation_type& impl,
|
||||||
|
asio::error_code& ec) const
|
||||||
|
{
|
||||||
|
return service_impl_.at_mark(impl, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine the number of bytes available for reading.
|
||||||
|
std::size_t available(const implementation_type& impl,
|
||||||
|
asio::error_code& ec) const
|
||||||
|
{
|
||||||
|
return service_impl_.available(impl, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind the datagram socket to the specified local endpoint.
|
// Bind the datagram socket to the specified local endpoint.
|
||||||
template <typename Error_Handler>
|
asio::error_code bind(implementation_type& impl,
|
||||||
void bind(implementation_type& impl, const endpoint_type& endpoint,
|
const endpoint_type& endpoint, asio::error_code& ec)
|
||||||
Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
service_impl_.bind(impl, endpoint, error_handler);
|
return service_impl_.bind(impl, endpoint, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connect the datagram socket to the specified endpoint.
|
/// Connect the datagram socket to the specified endpoint.
|
||||||
template <typename Error_Handler>
|
asio::error_code connect(implementation_type& impl,
|
||||||
void connect(implementation_type& impl, const endpoint_type& peer_endpoint,
|
const endpoint_type& peer_endpoint, asio::error_code& ec)
|
||||||
Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
service_impl_.connect(impl, peer_endpoint, error_handler);
|
return service_impl_.connect(impl, peer_endpoint, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous connect.
|
/// Start an asynchronous connect.
|
||||||
template <typename Handler>
|
template <typename ConnectHandler>
|
||||||
void async_connect(implementation_type& impl,
|
void async_connect(implementation_type& impl,
|
||||||
const endpoint_type& peer_endpoint, Handler handler)
|
const endpoint_type& peer_endpoint, ConnectHandler handler)
|
||||||
{
|
{
|
||||||
service_impl_.async_connect(impl, peer_endpoint, handler);
|
service_impl_.async_connect(impl, peer_endpoint, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a socket option.
|
/// Set a socket option.
|
||||||
template <typename Option, typename Error_Handler>
|
template <typename SettableSocketOption>
|
||||||
void set_option(implementation_type& impl, const Option& option,
|
asio::error_code set_option(implementation_type& impl,
|
||||||
Error_Handler error_handler)
|
const SettableSocketOption& option, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
service_impl_.set_option(impl, option, error_handler);
|
return service_impl_.set_option(impl, option, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a socket option.
|
/// Get a socket option.
|
||||||
template <typename Option, typename Error_Handler>
|
template <typename GettableSocketOption>
|
||||||
void get_option(const implementation_type& impl, Option& option,
|
asio::error_code get_option(const implementation_type& impl,
|
||||||
Error_Handler error_handler) const
|
GettableSocketOption& option, asio::error_code& ec) const
|
||||||
{
|
{
|
||||||
service_impl_.get_option(impl, option, error_handler);
|
return service_impl_.get_option(impl, option, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an IO control command on the socket.
|
/// Perform an IO control command on the socket.
|
||||||
template <typename IO_Control_Command, typename Error_Handler>
|
template <typename IoControlCommand>
|
||||||
void io_control(implementation_type& impl, IO_Control_Command& command,
|
asio::error_code io_control(implementation_type& impl,
|
||||||
Error_Handler error_handler)
|
IoControlCommand& command, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
service_impl_.io_control(impl, command, error_handler);
|
return service_impl_.io_control(impl, command, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the local endpoint.
|
/// Get the local endpoint.
|
||||||
template <typename Error_Handler>
|
|
||||||
endpoint_type local_endpoint(const implementation_type& impl,
|
endpoint_type local_endpoint(const implementation_type& impl,
|
||||||
Error_Handler error_handler) const
|
asio::error_code& ec) const
|
||||||
{
|
{
|
||||||
endpoint_type endpoint;
|
return service_impl_.local_endpoint(impl, ec);
|
||||||
service_impl_.get_local_endpoint(impl, endpoint, error_handler);
|
|
||||||
return endpoint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the remote endpoint.
|
/// Get the remote endpoint.
|
||||||
template <typename Error_Handler>
|
|
||||||
endpoint_type remote_endpoint(const implementation_type& impl,
|
endpoint_type remote_endpoint(const implementation_type& impl,
|
||||||
Error_Handler error_handler) const
|
asio::error_code& ec) const
|
||||||
{
|
{
|
||||||
endpoint_type endpoint;
|
return service_impl_.remote_endpoint(impl, ec);
|
||||||
service_impl_.get_remote_endpoint(impl, endpoint, error_handler);
|
|
||||||
return endpoint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable sends or receives on the socket.
|
/// Disable sends or receives on the socket.
|
||||||
template <typename Error_Handler>
|
asio::error_code shutdown(implementation_type& impl,
|
||||||
void shutdown(implementation_type& impl, socket_base::shutdown_type what,
|
socket_base::shutdown_type what, asio::error_code& ec)
|
||||||
Error_Handler error_handler)
|
|
||||||
{
|
{
|
||||||
service_impl_.shutdown(impl, what, error_handler);
|
return service_impl_.shutdown(impl, what, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send the given data to the peer.
|
/// Send the given data to the peer.
|
||||||
template <typename Const_Buffers, typename Error_Handler>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send(implementation_type& impl, const Const_Buffers& buffers,
|
std::size_t send(implementation_type& impl,
|
||||||
socket_base::message_flags flags, Error_Handler error_handler)
|
const ConstBufferSequence& buffers,
|
||||||
|
socket_base::message_flags flags, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return service_impl_.send(impl, buffers, flags, error_handler);
|
return service_impl_.send(impl, buffers, flags, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous send.
|
/// Start an asynchronous send.
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_send(implementation_type& impl, const Const_Buffers& buffers,
|
void async_send(implementation_type& impl, const ConstBufferSequence& buffers,
|
||||||
socket_base::message_flags flags, Handler handler)
|
socket_base::message_flags flags, WriteHandler handler)
|
||||||
{
|
{
|
||||||
service_impl_.async_send(impl, buffers, flags, handler);
|
service_impl_.async_send(impl, buffers, flags, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a datagram to the specified endpoint.
|
/// Send a datagram to the specified endpoint.
|
||||||
template <typename Const_Buffers, typename Error_Handler>
|
template <typename ConstBufferSequence>
|
||||||
std::size_t send_to(implementation_type& impl, const Const_Buffers& buffers,
|
std::size_t send_to(implementation_type& impl,
|
||||||
const endpoint_type& destination, socket_base::message_flags flags,
|
const ConstBufferSequence& buffers, const endpoint_type& destination,
|
||||||
Error_Handler error_handler)
|
socket_base::message_flags flags, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return service_impl_.send_to(impl, buffers, destination, flags,
|
return service_impl_.send_to(impl, buffers, destination, flags, ec);
|
||||||
error_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous send.
|
/// Start an asynchronous send.
|
||||||
template <typename Const_Buffers, typename Handler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
void async_send_to(implementation_type& impl, const Const_Buffers& buffers,
|
void async_send_to(implementation_type& impl,
|
||||||
const endpoint_type& destination, socket_base::message_flags flags,
|
const ConstBufferSequence& buffers, const endpoint_type& destination,
|
||||||
Handler handler)
|
socket_base::message_flags flags, WriteHandler handler)
|
||||||
{
|
{
|
||||||
service_impl_.async_send_to(impl, buffers, destination, flags, handler);
|
service_impl_.async_send_to(impl, buffers, destination, flags, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive some data from the peer.
|
/// Receive some data from the peer.
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive(implementation_type& impl, const Mutable_Buffers& buffers,
|
std::size_t receive(implementation_type& impl,
|
||||||
socket_base::message_flags flags, Error_Handler error_handler)
|
const MutableBufferSequence& buffers,
|
||||||
|
socket_base::message_flags flags, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return service_impl_.receive(impl, buffers, flags, error_handler);
|
return service_impl_.receive(impl, buffers, flags, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous receive.
|
/// Start an asynchronous receive.
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_receive(implementation_type& impl, const Mutable_Buffers& buffers,
|
void async_receive(implementation_type& impl,
|
||||||
socket_base::message_flags flags, Handler handler)
|
const MutableBufferSequence& buffers,
|
||||||
|
socket_base::message_flags flags, ReadHandler handler)
|
||||||
{
|
{
|
||||||
service_impl_.async_receive(impl, buffers, flags, handler);
|
service_impl_.async_receive(impl, buffers, flags, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive a datagram with the endpoint of the sender.
|
/// Receive a datagram with the endpoint of the sender.
|
||||||
template <typename Mutable_Buffers, typename Error_Handler>
|
template <typename MutableBufferSequence>
|
||||||
std::size_t receive_from(implementation_type& impl,
|
std::size_t receive_from(implementation_type& impl,
|
||||||
const Mutable_Buffers& buffers, endpoint_type& sender_endpoint,
|
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
|
||||||
socket_base::message_flags flags, Error_Handler error_handler)
|
socket_base::message_flags flags, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
|
return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
|
||||||
error_handler);
|
ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start an asynchronous receive that will get the endpoint of the sender.
|
/// Start an asynchronous receive that will get the endpoint of the sender.
|
||||||
template <typename Mutable_Buffers, typename Handler>
|
template <typename MutableBufferSequence, typename ReadHandler>
|
||||||
void async_receive_from(implementation_type& impl,
|
void async_receive_from(implementation_type& impl,
|
||||||
const Mutable_Buffers& buffers, endpoint_type& sender_endpoint,
|
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
|
||||||
socket_base::message_flags flags, Handler handler)
|
socket_base::message_flags flags, ReadHandler handler)
|
||||||
{
|
{
|
||||||
service_impl_.async_receive_from(impl, buffers, sender_endpoint, flags,
|
service_impl_.async_receive_from(impl, buffers, sender_endpoint, flags,
|
||||||
handler);
|
handler);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// deadline_timer.hpp
|
// deadline_timer.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// deadline_timer_service.hpp
|
// deadline_timer_service.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -28,18 +28,29 @@
|
|||||||
#include "asio/detail/epoll_reactor.hpp"
|
#include "asio/detail/epoll_reactor.hpp"
|
||||||
#include "asio/detail/kqueue_reactor.hpp"
|
#include "asio/detail/kqueue_reactor.hpp"
|
||||||
#include "asio/detail/select_reactor.hpp"
|
#include "asio/detail/select_reactor.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
/// Default service implementation for a timer.
|
/// Default service implementation for a timer.
|
||||||
template <typename Time_Type,
|
template <typename TimeType,
|
||||||
typename Time_Traits = asio::time_traits<Time_Type> >
|
typename TimeTraits = asio::time_traits<TimeType> >
|
||||||
class deadline_timer_service
|
class deadline_timer_service
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
: public asio::io_service::service
|
: public asio::io_service::service
|
||||||
|
#else
|
||||||
|
: public asio::detail::service_base<
|
||||||
|
deadline_timer_service<TimeType, TimeTraits> >
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// The unique service identifier.
|
||||||
|
static asio::io_service::id id;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// The time traits type.
|
/// The time traits type.
|
||||||
typedef Time_Traits traits_type;
|
typedef TimeTraits traits_type;
|
||||||
|
|
||||||
/// The time type.
|
/// The time type.
|
||||||
typedef typename traits_type::time_type time_type;
|
typedef typename traits_type::time_type time_type;
|
||||||
@ -73,7 +84,8 @@ public:
|
|||||||
|
|
||||||
/// Construct a new timer service for the specified io_service.
|
/// Construct a new timer service for the specified io_service.
|
||||||
explicit deadline_timer_service(asio::io_service& io_service)
|
explicit deadline_timer_service(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<
|
||||||
|
deadline_timer_service<TimeType, TimeTraits> >(io_service),
|
||||||
service_impl_(asio::use_service<service_impl_type>(io_service))
|
service_impl_(asio::use_service<service_impl_type>(io_service))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -96,9 +108,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Cancel any asynchronous wait operations associated with the timer.
|
/// Cancel any asynchronous wait operations associated with the timer.
|
||||||
std::size_t cancel(implementation_type& impl)
|
std::size_t cancel(implementation_type& impl, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return service_impl_.cancel(impl);
|
return service_impl_.cancel(impl, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the expiry time for the timer as an absolute time.
|
/// Get the expiry time for the timer as an absolute time.
|
||||||
@ -109,9 +121,9 @@ public:
|
|||||||
|
|
||||||
/// Set the expiry time for the timer as an absolute time.
|
/// Set the expiry time for the timer as an absolute time.
|
||||||
std::size_t expires_at(implementation_type& impl,
|
std::size_t expires_at(implementation_type& impl,
|
||||||
const time_type& expiry_time)
|
const time_type& expiry_time, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return service_impl_.expires_at(impl, expiry_time);
|
return service_impl_.expires_at(impl, expiry_time, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the expiry time for the timer relative to now.
|
/// Get the expiry time for the timer relative to now.
|
||||||
@ -122,20 +134,20 @@ public:
|
|||||||
|
|
||||||
/// Set the expiry time for the timer relative to now.
|
/// Set the expiry time for the timer relative to now.
|
||||||
std::size_t expires_from_now(implementation_type& impl,
|
std::size_t expires_from_now(implementation_type& impl,
|
||||||
const duration_type& expiry_time)
|
const duration_type& expiry_time, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return service_impl_.expires_from_now(impl, expiry_time);
|
return service_impl_.expires_from_now(impl, expiry_time, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform a blocking wait on the timer.
|
// Perform a blocking wait on the timer.
|
||||||
void wait(implementation_type& impl)
|
void wait(implementation_type& impl, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
service_impl_.wait(impl);
|
service_impl_.wait(impl, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start an asynchronous wait on the timer.
|
// Start an asynchronous wait on the timer.
|
||||||
template <typename Handler>
|
template <typename WaitHandler>
|
||||||
void async_wait(implementation_type& impl, Handler handler)
|
void async_wait(implementation_type& impl, WaitHandler handler)
|
||||||
{
|
{
|
||||||
service_impl_.async_wait(impl, handler);
|
service_impl_.async_wait(impl, handler);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// bind_handler.hpp
|
// bind_handler.hpp
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// buffer_resize_guard.hpp
|
// buffer_resize_guard.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// buffered_stream_storage.hpp
|
// buffered_stream_storage.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// call_stack.hpp
|
// call_stack.hpp
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// const_buffers_iterator.hpp
|
// const_buffers_iterator.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -29,9 +29,9 @@ namespace asio {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
// A proxy iterator for a sub-range in a list of buffers.
|
// A proxy iterator for a sub-range in a list of buffers.
|
||||||
template <typename Const_Buffers>
|
template <typename ConstBufferSequence>
|
||||||
class const_buffers_iterator
|
class const_buffers_iterator
|
||||||
: public boost::iterator_facade<const_buffers_iterator<Const_Buffers>,
|
: public boost::iterator_facade<const_buffers_iterator<ConstBufferSequence>,
|
||||||
const char, boost::bidirectional_traversal_tag>
|
const char, boost::bidirectional_traversal_tag>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -41,7 +41,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create an iterator for the specified position.
|
// Create an iterator for the specified position.
|
||||||
const_buffers_iterator(const Const_Buffers& buffers, std::size_t position)
|
const_buffers_iterator(const ConstBufferSequence& buffers,
|
||||||
|
std::size_t position)
|
||||||
: begin_(buffers.begin()),
|
: begin_(buffers.begin()),
|
||||||
current_(buffers.begin()),
|
current_(buffers.begin()),
|
||||||
end_(buffers.end()),
|
end_(buffers.end()),
|
||||||
@ -107,7 +108,7 @@ private:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
typename Const_Buffers::const_iterator iter = current_;
|
typename ConstBufferSequence::const_iterator iter = current_;
|
||||||
while (iter != begin_)
|
while (iter != begin_)
|
||||||
{
|
{
|
||||||
--iter;
|
--iter;
|
||||||
@ -136,9 +137,9 @@ private:
|
|||||||
|
|
||||||
asio::const_buffer current_buffer_;
|
asio::const_buffer current_buffer_;
|
||||||
std::size_t current_buffer_position_;
|
std::size_t current_buffer_position_;
|
||||||
typename Const_Buffers::const_iterator begin_;
|
typename ConstBufferSequence::const_iterator begin_;
|
||||||
typename Const_Buffers::const_iterator current_;
|
typename ConstBufferSequence::const_iterator current_;
|
||||||
typename Const_Buffers::const_iterator end_;
|
typename ConstBufferSequence::const_iterator end_;
|
||||||
std::size_t position_;
|
std::size_t position_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// consuming_buffers.hpp
|
// consuming_buffers.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -32,8 +32,7 @@ template <typename Buffer, typename Buffer_Iterator>
|
|||||||
class consuming_buffers_iterator
|
class consuming_buffers_iterator
|
||||||
: public boost::iterator_facade<
|
: public boost::iterator_facade<
|
||||||
consuming_buffers_iterator<Buffer, Buffer_Iterator>,
|
consuming_buffers_iterator<Buffer, Buffer_Iterator>,
|
||||||
const Buffer,
|
const Buffer, boost::forward_traversal_tag>
|
||||||
boost::forward_traversal_tag>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Default constructor creates an end iterator.
|
// Default constructor creates an end iterator.
|
||||||
@ -47,23 +46,32 @@ public:
|
|||||||
consuming_buffers_iterator(bool at_end, const Buffer& first,
|
consuming_buffers_iterator(bool at_end, const Buffer& first,
|
||||||
Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder)
|
Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder)
|
||||||
: at_end_(at_end),
|
: at_end_(at_end),
|
||||||
first_(first),
|
first_(buffer(first, max_size)),
|
||||||
begin_remainder_(begin_remainder),
|
begin_remainder_(begin_remainder),
|
||||||
end_remainder_(end_remainder)
|
end_remainder_(end_remainder),
|
||||||
|
offset_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class boost::iterator_core_access;
|
friend class boost::iterator_core_access;
|
||||||
|
|
||||||
|
enum { max_size = 65536 };
|
||||||
|
|
||||||
void increment()
|
void increment()
|
||||||
{
|
{
|
||||||
if (!at_end_)
|
if (!at_end_)
|
||||||
{
|
{
|
||||||
if (begin_remainder_ == end_remainder_)
|
if (begin_remainder_ == end_remainder_
|
||||||
|
|| offset_ + buffer_size(first_) >= max_size)
|
||||||
|
{
|
||||||
at_end_ = true;
|
at_end_ = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
first_ = *begin_remainder_++;
|
{
|
||||||
|
offset_ += buffer_size(first_);
|
||||||
|
first_ = buffer(*begin_remainder_++, max_size - offset_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +96,7 @@ private:
|
|||||||
Buffer first_;
|
Buffer first_;
|
||||||
Buffer_Iterator begin_remainder_;
|
Buffer_Iterator begin_remainder_;
|
||||||
Buffer_Iterator end_remainder_;
|
Buffer_Iterator end_remainder_;
|
||||||
|
std::size_t offset_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A proxy for a sub-range in a list of buffers.
|
// A proxy for a sub-range in a list of buffers.
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// deadline_timer_service.hpp
|
// deadline_timer_service.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -27,6 +27,7 @@
|
|||||||
#include "asio/io_service.hpp"
|
#include "asio/io_service.hpp"
|
||||||
#include "asio/detail/bind_handler.hpp"
|
#include "asio/detail/bind_handler.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/socket_ops.hpp"
|
#include "asio/detail/socket_ops.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
#include "asio/detail/timer_queue.hpp"
|
#include "asio/detail/timer_queue.hpp"
|
||||||
@ -36,7 +37,8 @@ namespace detail {
|
|||||||
|
|
||||||
template <typename Time_Traits, typename Timer_Scheduler>
|
template <typename Time_Traits, typename Timer_Scheduler>
|
||||||
class deadline_timer_service
|
class deadline_timer_service
|
||||||
: public asio::io_service::service
|
: public asio::detail::service_base<
|
||||||
|
deadline_timer_service<Time_Traits, Timer_Scheduler> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// The time type.
|
// The time type.
|
||||||
@ -56,12 +58,19 @@ public:
|
|||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
deadline_timer_service(asio::io_service& io_service)
|
deadline_timer_service(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<
|
||||||
|
deadline_timer_service<Time_Traits, Timer_Scheduler> >(io_service),
|
||||||
scheduler_(asio::use_service<Timer_Scheduler>(io_service))
|
scheduler_(asio::use_service<Timer_Scheduler>(io_service))
|
||||||
{
|
{
|
||||||
scheduler_.add_timer_queue(timer_queue_);
|
scheduler_.add_timer_queue(timer_queue_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Destructor.
|
||||||
|
~deadline_timer_service()
|
||||||
|
{
|
||||||
|
scheduler_.remove_timer_queue(timer_queue_);
|
||||||
|
}
|
||||||
|
|
||||||
// Destroy all user-defined handler objects owned by the service.
|
// Destroy all user-defined handler objects owned by the service.
|
||||||
void shutdown_service()
|
void shutdown_service()
|
||||||
{
|
{
|
||||||
@ -77,16 +86,21 @@ public:
|
|||||||
// Destroy a timer implementation.
|
// Destroy a timer implementation.
|
||||||
void destroy(implementation_type& impl)
|
void destroy(implementation_type& impl)
|
||||||
{
|
{
|
||||||
cancel(impl);
|
asio::error_code ec;
|
||||||
|
cancel(impl, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel any asynchronous wait operations associated with the timer.
|
// Cancel any asynchronous wait operations associated with the timer.
|
||||||
std::size_t cancel(implementation_type& impl)
|
std::size_t cancel(implementation_type& impl, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (!impl.might_have_pending_waits)
|
if (!impl.might_have_pending_waits)
|
||||||
|
{
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl);
|
std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl);
|
||||||
impl.might_have_pending_waits = false;
|
impl.might_have_pending_waits = false;
|
||||||
|
ec = asio::error_code();
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,10 +112,11 @@ public:
|
|||||||
|
|
||||||
// Set the expiry time for the timer as an absolute time.
|
// Set the expiry time for the timer as an absolute time.
|
||||||
std::size_t expires_at(implementation_type& impl,
|
std::size_t expires_at(implementation_type& impl,
|
||||||
const time_type& expiry_time)
|
const time_type& expiry_time, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
std::size_t count = cancel(impl);
|
std::size_t count = cancel(impl, ec);
|
||||||
impl.expiry = expiry_time;
|
impl.expiry = expiry_time;
|
||||||
|
ec = asio::error_code();
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,13 +128,14 @@ public:
|
|||||||
|
|
||||||
// Set the expiry time for the timer relative to now.
|
// Set the expiry time for the timer relative to now.
|
||||||
std::size_t expires_from_now(implementation_type& impl,
|
std::size_t expires_from_now(implementation_type& impl,
|
||||||
const duration_type& expiry_time)
|
const duration_type& expiry_time, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
return expires_at(impl, Time_Traits::add(Time_Traits::now(), expiry_time));
|
return expires_at(impl,
|
||||||
|
Time_Traits::add(Time_Traits::now(), expiry_time), ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform a blocking wait on the timer.
|
// Perform a blocking wait on the timer.
|
||||||
void wait(implementation_type& impl)
|
void wait(implementation_type& impl, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
time_type now = Time_Traits::now();
|
time_type now = Time_Traits::now();
|
||||||
while (Time_Traits::less_than(now, impl.expiry))
|
while (Time_Traits::less_than(now, impl.expiry))
|
||||||
@ -129,9 +145,11 @@ public:
|
|||||||
::timeval tv;
|
::timeval tv;
|
||||||
tv.tv_sec = timeout.total_seconds();
|
tv.tv_sec = timeout.total_seconds();
|
||||||
tv.tv_usec = timeout.total_microseconds() % 1000000;
|
tv.tv_usec = timeout.total_microseconds() % 1000000;
|
||||||
socket_ops::select(0, 0, 0, 0, &tv);
|
asio::error_code ec;
|
||||||
|
socket_ops::select(0, 0, 0, 0, &tv, ec);
|
||||||
now = Time_Traits::now();
|
now = Time_Traits::now();
|
||||||
}
|
}
|
||||||
|
ec = asio::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
@ -145,10 +163,9 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(int result)
|
void operator()(const asio::error_code& result)
|
||||||
{
|
{
|
||||||
asio::error e(result);
|
io_service_.post(detail::bind_handler(handler_, result));
|
||||||
io_service_.post(detail::bind_handler(handler_, e));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -163,7 +180,7 @@ public:
|
|||||||
{
|
{
|
||||||
impl.might_have_pending_waits = true;
|
impl.might_have_pending_waits = true;
|
||||||
scheduler_.schedule_timer(timer_queue_, impl.expiry,
|
scheduler_.schedule_timer(timer_queue_, impl.expiry,
|
||||||
wait_handler<Handler>(io_service(), handler), &impl);
|
wait_handler<Handler>(this->io_service(), handler), &impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// epoll_reactor.hpp
|
// epoll_reactor.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -30,8 +30,9 @@
|
|||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/io_service.hpp"
|
#include "asio/io_service.hpp"
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/bind_handler.hpp"
|
#include "asio/detail/bind_handler.hpp"
|
||||||
#include "asio/detail/hash_map.hpp"
|
#include "asio/detail/hash_map.hpp"
|
||||||
#include "asio/detail/mutex.hpp"
|
#include "asio/detail/mutex.hpp"
|
||||||
@ -39,6 +40,7 @@
|
|||||||
#include "asio/detail/thread.hpp"
|
#include "asio/detail/thread.hpp"
|
||||||
#include "asio/detail/reactor_op_queue.hpp"
|
#include "asio/detail/reactor_op_queue.hpp"
|
||||||
#include "asio/detail/select_interrupter.hpp"
|
#include "asio/detail/select_interrupter.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/signal_blocker.hpp"
|
#include "asio/detail/signal_blocker.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
#include "asio/detail/timer_queue.hpp"
|
#include "asio/detail/timer_queue.hpp"
|
||||||
@ -48,12 +50,12 @@ namespace detail {
|
|||||||
|
|
||||||
template <bool Own_Thread>
|
template <bool Own_Thread>
|
||||||
class epoll_reactor
|
class epoll_reactor
|
||||||
: public asio::io_service::service
|
: public asio::detail::service_base<epoll_reactor<Own_Thread> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
epoll_reactor(asio::io_service& io_service)
|
epoll_reactor(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<epoll_reactor<Own_Thread> >(io_service),
|
||||||
mutex_(),
|
mutex_(),
|
||||||
epoll_fd_(do_epoll_create()),
|
epoll_fd_(do_epoll_create()),
|
||||||
wait_in_progress_(false),
|
wait_in_progress_(false),
|
||||||
@ -139,7 +141,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!read_op_queue_.has_operation(descriptor))
|
if (!read_op_queue_.has_operation(descriptor))
|
||||||
if (handler(0))
|
if (handler(asio::error_code()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (read_op_queue_.enqueue_operation(descriptor, handler))
|
if (read_op_queue_.enqueue_operation(descriptor, handler))
|
||||||
@ -155,8 +157,8 @@ public:
|
|||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code ec(errno, asio::native_ecat);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,7 +174,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!write_op_queue_.has_operation(descriptor))
|
if (!write_op_queue_.has_operation(descriptor))
|
||||||
if (handler(0))
|
if (handler(asio::error_code()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (write_op_queue_.enqueue_operation(descriptor, handler))
|
if (write_op_queue_.enqueue_operation(descriptor, handler))
|
||||||
@ -188,8 +190,8 @@ public:
|
|||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code ec(errno, asio::native_ecat);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,8 +219,8 @@ public:
|
|||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code ec(errno, asio::native_ecat);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,9 +250,9 @@ public:
|
|||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code ec(errno, asio::native_ecat);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,6 +298,21 @@ public:
|
|||||||
timer_queues_.push_back(&timer_queue);
|
timer_queues_.push_back(&timer_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove a timer queue from the reactor.
|
||||||
|
template <typename Time_Traits>
|
||||||
|
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
|
||||||
|
{
|
||||||
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||||
|
{
|
||||||
|
if (timer_queues_[i] == &timer_queue)
|
||||||
|
{
|
||||||
|
timer_queues_.erase(timer_queues_.begin() + i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Schedule a timer in the given timer queue to expire at the specified
|
// Schedule a timer in the given timer queue to expire at the specified
|
||||||
// absolute time. The handler object will be invoked when the timer expires.
|
// absolute time. The handler object will be invoked when the timer expires.
|
||||||
template <typename Time_Traits, typename Handler>
|
template <typename Time_Traits, typename Handler>
|
||||||
@ -383,9 +400,10 @@ private:
|
|||||||
{
|
{
|
||||||
if (events[i].events & (EPOLLERR | EPOLLHUP))
|
if (events[i].events & (EPOLLERR | EPOLLHUP))
|
||||||
{
|
{
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, 0);
|
asio::error_code ec;
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, 0);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, 0);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
|
|
||||||
epoll_event ev = { 0, { 0 } };
|
epoll_event ev = { 0, { 0 } };
|
||||||
ev.events = 0;
|
ev.events = 0;
|
||||||
@ -397,21 +415,22 @@ private:
|
|||||||
bool more_reads = false;
|
bool more_reads = false;
|
||||||
bool more_writes = false;
|
bool more_writes = false;
|
||||||
bool more_except = false;
|
bool more_except = false;
|
||||||
|
asio::error_code ec;
|
||||||
|
|
||||||
// Exception operations must be processed first to ensure that any
|
// Exception operations must be processed first to ensure that any
|
||||||
// out-of-band data is read before normal data.
|
// out-of-band data is read before normal data.
|
||||||
if (events[i].events & EPOLLPRI)
|
if (events[i].events & EPOLLPRI)
|
||||||
more_except = except_op_queue_.dispatch_operation(descriptor, 0);
|
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
|
||||||
else
|
else
|
||||||
more_except = except_op_queue_.has_operation(descriptor);
|
more_except = except_op_queue_.has_operation(descriptor);
|
||||||
|
|
||||||
if (events[i].events & EPOLLIN)
|
if (events[i].events & EPOLLIN)
|
||||||
more_reads = read_op_queue_.dispatch_operation(descriptor, 0);
|
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
|
||||||
else
|
else
|
||||||
more_reads = read_op_queue_.has_operation(descriptor);
|
more_reads = read_op_queue_.has_operation(descriptor);
|
||||||
|
|
||||||
if (events[i].events & EPOLLOUT)
|
if (events[i].events & EPOLLOUT)
|
||||||
more_writes = write_op_queue_.dispatch_operation(descriptor, 0);
|
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
|
||||||
else
|
else
|
||||||
more_writes = write_op_queue_.has_operation(descriptor);
|
more_writes = write_op_queue_.has_operation(descriptor);
|
||||||
|
|
||||||
@ -427,10 +446,10 @@ private:
|
|||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
int error = errno;
|
ec = asio::error_code(errno, asio::native_ecat);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,8 +507,9 @@ private:
|
|||||||
int fd = epoll_create(epoll_size);
|
int fd = epoll_create(epoll_size);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
system_exception e("epoll", errno);
|
boost::throw_exception(asio::system_error(
|
||||||
boost::throw_exception(e);
|
asio::error_code(errno, asio::native_ecat),
|
||||||
|
"epoll"));
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// epoll_reactor_fwd.hpp
|
// epoll_reactor_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// event.hpp
|
// event.hpp
|
||||||
// ~~~~~~~~~
|
// ~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// fd_set_adapter.hpp
|
// fd_set_adapter.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// handler_alloc_helpers.hpp
|
// handler_alloc_helpers.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// handler_invoke_helpers.hpp
|
// handler_invoke_helpers.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// hash_map.hpp
|
// hash_map.hpp
|
||||||
// ~~~~~~~~~~~~
|
// ~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -25,11 +25,23 @@
|
|||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
using boost::hash_value;
|
template <typename T>
|
||||||
|
inline std::size_t calculate_hash_value(const T& t)
|
||||||
|
{
|
||||||
|
return boost::hash_value(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
inline std::size_t calculate_hash_value(SOCKET s)
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(s);
|
||||||
|
}
|
||||||
|
#endif // defined(_WIN64)
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V>
|
||||||
class hash_map
|
class hash_map
|
||||||
@ -37,7 +49,7 @@ class hash_map
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// The type of a value in the map.
|
// The type of a value in the map.
|
||||||
typedef std::pair<const K, V> value_type;
|
typedef std::pair<K, V> value_type;
|
||||||
|
|
||||||
// The type of a non-const iterator over the hash map.
|
// The type of a non-const iterator over the hash map.
|
||||||
typedef typename std::list<value_type>::iterator iterator;
|
typedef typename std::list<value_type>::iterator iterator;
|
||||||
@ -86,7 +98,7 @@ public:
|
|||||||
// Find an entry in the map.
|
// Find an entry in the map.
|
||||||
iterator find(const K& k)
|
iterator find(const K& k)
|
||||||
{
|
{
|
||||||
size_t bucket = hash_value(k) % num_buckets;
|
size_t bucket = calculate_hash_value(k) % num_buckets;
|
||||||
iterator it = buckets_[bucket].first;
|
iterator it = buckets_[bucket].first;
|
||||||
if (it == values_.end())
|
if (it == values_.end())
|
||||||
return values_.end();
|
return values_.end();
|
||||||
@ -104,7 +116,7 @@ public:
|
|||||||
// Find an entry in the map.
|
// Find an entry in the map.
|
||||||
const_iterator find(const K& k) const
|
const_iterator find(const K& k) const
|
||||||
{
|
{
|
||||||
size_t bucket = hash_value(k) % num_buckets;
|
size_t bucket = calculate_hash_value(k) % num_buckets;
|
||||||
const_iterator it = buckets_[bucket].first;
|
const_iterator it = buckets_[bucket].first;
|
||||||
if (it == values_.end())
|
if (it == values_.end())
|
||||||
return it;
|
return it;
|
||||||
@ -122,7 +134,7 @@ public:
|
|||||||
// Insert a new entry into the map.
|
// Insert a new entry into the map.
|
||||||
std::pair<iterator, bool> insert(const value_type& v)
|
std::pair<iterator, bool> insert(const value_type& v)
|
||||||
{
|
{
|
||||||
size_t bucket = hash_value(v.first) % num_buckets;
|
size_t bucket = calculate_hash_value(v.first) % num_buckets;
|
||||||
iterator it = buckets_[bucket].first;
|
iterator it = buckets_[bucket].first;
|
||||||
if (it == values_.end())
|
if (it == values_.end())
|
||||||
{
|
{
|
||||||
@ -147,7 +159,7 @@ public:
|
|||||||
{
|
{
|
||||||
assert(it != values_.end());
|
assert(it != values_.end());
|
||||||
|
|
||||||
size_t bucket = hash_value(it->first) % num_buckets;
|
size_t bucket = calculate_hash_value(it->first) % num_buckets;
|
||||||
bool is_first = (it == buckets_[bucket].first);
|
bool is_first = (it == buckets_[bucket].first);
|
||||||
bool is_last = (it == buckets_[bucket].last);
|
bool is_last = (it == buckets_[bucket].last);
|
||||||
if (is_first && is_last)
|
if (is_first && is_last)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// io_control.hpp
|
// io_control.hpp
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -90,7 +90,7 @@ public:
|
|||||||
|
|
||||||
// Construct with a specific command value.
|
// Construct with a specific command value.
|
||||||
bytes_readable(std::size_t value)
|
bytes_readable(std::size_t value)
|
||||||
: value_(value)
|
: value_(static_cast<detail::ioctl_arg_type>(value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// kqueue_reactor.hpp
|
// kqueue_reactor.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
|
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
@ -33,14 +33,16 @@
|
|||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/io_service.hpp"
|
#include "asio/io_service.hpp"
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/bind_handler.hpp"
|
#include "asio/detail/bind_handler.hpp"
|
||||||
#include "asio/detail/mutex.hpp"
|
#include "asio/detail/mutex.hpp"
|
||||||
#include "asio/detail/task_io_service.hpp"
|
#include "asio/detail/task_io_service.hpp"
|
||||||
#include "asio/detail/thread.hpp"
|
#include "asio/detail/thread.hpp"
|
||||||
#include "asio/detail/reactor_op_queue.hpp"
|
#include "asio/detail/reactor_op_queue.hpp"
|
||||||
#include "asio/detail/select_interrupter.hpp"
|
#include "asio/detail/select_interrupter.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/signal_blocker.hpp"
|
#include "asio/detail/signal_blocker.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
#include "asio/detail/timer_queue.hpp"
|
#include "asio/detail/timer_queue.hpp"
|
||||||
@ -55,12 +57,13 @@ namespace detail {
|
|||||||
|
|
||||||
template <bool Own_Thread>
|
template <bool Own_Thread>
|
||||||
class kqueue_reactor
|
class kqueue_reactor
|
||||||
: public asio::io_service::service
|
: public asio::detail::service_base<kqueue_reactor<Own_Thread> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
kqueue_reactor(asio::io_service& io_service)
|
kqueue_reactor(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<
|
||||||
|
kqueue_reactor<Own_Thread> >(io_service),
|
||||||
mutex_(),
|
mutex_(),
|
||||||
kqueue_fd_(do_kqueue_create()),
|
kqueue_fd_(do_kqueue_create()),
|
||||||
wait_in_progress_(false),
|
wait_in_progress_(false),
|
||||||
@ -138,7 +141,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!read_op_queue_.has_operation(descriptor))
|
if (!read_op_queue_.has_operation(descriptor))
|
||||||
if (handler(0))
|
if (handler(asio::error_code()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (read_op_queue_.enqueue_operation(descriptor, handler))
|
if (read_op_queue_.enqueue_operation(descriptor, handler))
|
||||||
@ -147,8 +150,8 @@ public:
|
|||||||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code ec(errno, asio::native_ecat);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,7 +167,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!write_op_queue_.has_operation(descriptor))
|
if (!write_op_queue_.has_operation(descriptor))
|
||||||
if (handler(0))
|
if (handler(asio::error_code()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (write_op_queue_.enqueue_operation(descriptor, handler))
|
if (write_op_queue_.enqueue_operation(descriptor, handler))
|
||||||
@ -173,8 +176,8 @@ public:
|
|||||||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code ec(errno, asio::native_ecat);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,8 +201,8 @@ public:
|
|||||||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code ec(errno, asio::native_ecat);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,8 +224,8 @@ public:
|
|||||||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code ec(errno, asio::native_ecat);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,9 +238,9 @@ public:
|
|||||||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code ec(errno, asio::native_ecat);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,6 +288,21 @@ public:
|
|||||||
timer_queues_.push_back(&timer_queue);
|
timer_queues_.push_back(&timer_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove a timer queue from the reactor.
|
||||||
|
template <typename Time_Traits>
|
||||||
|
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
|
||||||
|
{
|
||||||
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||||
|
{
|
||||||
|
if (timer_queues_[i] == &timer_queue)
|
||||||
|
{
|
||||||
|
timer_queues_.erase(timer_queues_.begin() + i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Schedule a timer in the given timer queue to expire at the specified
|
// Schedule a timer in the given timer queue to expire at the specified
|
||||||
// absolute time. The handler object will be invoked when the timer expires.
|
// absolute time. The handler object will be invoked when the timer expires.
|
||||||
template <typename Time_Traits, typename Handler>
|
template <typename Time_Traits, typename Handler>
|
||||||
@ -378,21 +396,24 @@ private:
|
|||||||
bool more_except = false;
|
bool more_except = false;
|
||||||
if (events[i].flags & EV_ERROR)
|
if (events[i].flags & EV_ERROR)
|
||||||
{
|
{
|
||||||
int error = events[i].data;
|
asio::error_code error(
|
||||||
|
events[i].data, asio::native_ecat);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
read_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
else if (events[i].flags & EV_OOBAND)
|
else if (events[i].flags & EV_OOBAND)
|
||||||
{
|
{
|
||||||
more_except = except_op_queue_.dispatch_operation(descriptor, 0);
|
asio::error_code error;
|
||||||
|
more_except = except_op_queue_.dispatch_operation(descriptor, error);
|
||||||
if (events[i].data > 0)
|
if (events[i].data > 0)
|
||||||
more_reads = read_op_queue_.dispatch_operation(descriptor, 0);
|
more_reads = read_op_queue_.dispatch_operation(descriptor, error);
|
||||||
else
|
else
|
||||||
more_reads = read_op_queue_.has_operation(descriptor);
|
more_reads = read_op_queue_.has_operation(descriptor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
more_reads = read_op_queue_.dispatch_operation(descriptor, 0);
|
asio::error_code error;
|
||||||
|
more_reads = read_op_queue_.dispatch_operation(descriptor, error);
|
||||||
more_except = except_op_queue_.has_operation(descriptor);
|
more_except = except_op_queue_.has_operation(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,7 +427,7 @@ private:
|
|||||||
EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code error(errno, asio::native_ecat);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
read_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
@ -417,12 +438,14 @@ private:
|
|||||||
bool more_writes = false;
|
bool more_writes = false;
|
||||||
if (events[i].flags & EV_ERROR)
|
if (events[i].flags & EV_ERROR)
|
||||||
{
|
{
|
||||||
int error = events[i].data;
|
asio::error_code error(
|
||||||
|
events[i].data, asio::native_ecat);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
more_writes = write_op_queue_.dispatch_operation(descriptor, 0);
|
asio::error_code error;
|
||||||
|
more_writes = write_op_queue_.dispatch_operation(descriptor, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the descriptor in the kqueue.
|
// Update the descriptor in the kqueue.
|
||||||
@ -433,7 +456,7 @@ private:
|
|||||||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
int error = errno;
|
asio::error_code error(errno, asio::native_ecat);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -489,8 +512,9 @@ private:
|
|||||||
int fd = kqueue();
|
int fd = kqueue();
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
system_exception e("kqueue", errno);
|
boost::throw_exception(asio::system_error(
|
||||||
boost::throw_exception(e);
|
asio::error_code(errno, asio::native_ecat),
|
||||||
|
"kqueue"));
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -539,7 +563,7 @@ private:
|
|||||||
|
|
||||||
// Cancel all operations associated with the given descriptor. The do_cancel
|
// Cancel all operations associated with the given descriptor. The do_cancel
|
||||||
// function of the handler objects will be invoked. This function does not
|
// function of the handler objects will be invoked. This function does not
|
||||||
// acquire the epoll_reactor's mutex.
|
// acquire the kqueue_reactor's mutex.
|
||||||
void cancel_ops_unlocked(socket_type descriptor)
|
void cancel_ops_unlocked(socket_type descriptor)
|
||||||
{
|
{
|
||||||
bool interrupt = read_op_queue_.cancel_operations(descriptor);
|
bool interrupt = read_op_queue_.cancel_operations(descriptor);
|
||||||
@ -552,13 +576,13 @@ private:
|
|||||||
// Mutex to protect access to internal data.
|
// Mutex to protect access to internal data.
|
||||||
asio::detail::mutex mutex_;
|
asio::detail::mutex mutex_;
|
||||||
|
|
||||||
// The epoll file descriptor.
|
// The kqueue file descriptor.
|
||||||
int kqueue_fd_;
|
int kqueue_fd_;
|
||||||
|
|
||||||
// Whether the kqueue wait call is currently in progress
|
// Whether the kqueue wait call is currently in progress
|
||||||
bool wait_in_progress_;
|
bool wait_in_progress_;
|
||||||
|
|
||||||
// The interrupter is used to break a blocking epoll_wait call.
|
// The interrupter is used to break a blocking kevent call.
|
||||||
select_interrupter interrupter_;
|
select_interrupter interrupter_;
|
||||||
|
|
||||||
// The queue of read operations.
|
// The queue of read operations.
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// kqueue_reactor_fwd.hpp
|
// kqueue_reactor_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
|
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
|||||||
@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// local_free_on_block_exit.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP
|
||||||
|
#define ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
|
|
||||||
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
class local_free_on_block_exit
|
||||||
|
: private noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Constructor blocks all signals for the calling thread.
|
||||||
|
explicit local_free_on_block_exit(void* p)
|
||||||
|
: p_(p)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor restores the previous signal mask.
|
||||||
|
~local_free_on_block_exit()
|
||||||
|
{
|
||||||
|
::LocalFree(p_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* p_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace asio
|
||||||
|
|
||||||
|
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
|
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#endif // ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// mutex.hpp
|
// mutex.hpp
|
||||||
// ~~~~~~~~~
|
// ~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// noncopyable.hpp
|
// noncopyable.hpp
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// null_event.hpp
|
// null_event.hpp
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// null_mutex.hpp
|
// null_mutex.hpp
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// null_signal_blocker.hpp
|
// null_signal_blocker.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// null_thread.hpp
|
// null_thread.hpp
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/error.hpp"
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
@ -42,7 +42,8 @@ public:
|
|||||||
template <typename Function>
|
template <typename Function>
|
||||||
null_thread(Function f)
|
null_thread(Function f)
|
||||||
{
|
{
|
||||||
system_exception e("thread", asio::error::not_supported);
|
asio::system_error e(
|
||||||
|
asio::error::operation_not_supported, "thread");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// null_tss_ptr.hpp
|
// null_tss_ptr.hpp
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// old_win_sdk_compat.hpp
|
// old_win_sdk_compat.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -24,9 +24,9 @@
|
|||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
|
|
||||||
// Guess whether we are building against on old Platform SDK.
|
// Guess whether we are building against on old Platform SDK.
|
||||||
#if !defined(IPPROTO_IPV6)
|
#if !defined(IN6ADDR_ANY_INIT)
|
||||||
#define ASIO_HAS_OLD_WIN_SDK 1
|
#define ASIO_HAS_OLD_WIN_SDK 1
|
||||||
#endif // !defined(IPPROTO_IPV6)
|
#endif // !defined(IN6ADDR_ANY_INIT)
|
||||||
|
|
||||||
#if defined(ASIO_HAS_OLD_WIN_SDK)
|
#if defined(ASIO_HAS_OLD_WIN_SDK)
|
||||||
|
|
||||||
@ -305,6 +305,11 @@ inline int IN6_IS_ADDR_MC_GLOBAL(const in6_addr_emulation* a)
|
|||||||
|
|
||||||
#endif // defined(ASIO_HAS_OLD_WIN_SDK)
|
#endif // defined(ASIO_HAS_OLD_WIN_SDK)
|
||||||
|
|
||||||
|
// Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY.
|
||||||
|
#if !defined(IPV6_V6ONLY)
|
||||||
|
# define IPV6_V6ONLY 27
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
|
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// pipe_select_interrupter.hpp
|
// pipe_select_interrupter.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// pop_options.hpp
|
// pop_options.hpp
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// posix_event.hpp
|
// posix_event.hpp
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
@ -45,7 +45,9 @@ public:
|
|||||||
int error = ::pthread_mutex_init(&mutex_, 0);
|
int error = ::pthread_mutex_init(&mutex_, 0);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
system_exception e("event", error);
|
asio::system_error e(
|
||||||
|
asio::error_code(error, asio::native_ecat),
|
||||||
|
"event");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +55,9 @@ public:
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
::pthread_mutex_destroy(&mutex_);
|
::pthread_mutex_destroy(&mutex_);
|
||||||
system_exception e("event", error);
|
asio::system_error e(
|
||||||
|
asio::error_code(error, asio::native_ecat),
|
||||||
|
"event");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// posix_fd_set_adapter.hpp
|
// posix_fd_set_adapter.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -31,6 +31,7 @@ public:
|
|||||||
posix_fd_set_adapter()
|
posix_fd_set_adapter()
|
||||||
: max_descriptor_(invalid_socket)
|
: max_descriptor_(invalid_socket)
|
||||||
{
|
{
|
||||||
|
using namespace std; // Needed for memset on Solaris.
|
||||||
FD_ZERO(&fd_set_);
|
FD_ZERO(&fd_set_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// posix_mutex.hpp
|
// posix_mutex.hpp
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/scoped_lock.hpp"
|
#include "asio/detail/scoped_lock.hpp"
|
||||||
|
|
||||||
@ -47,7 +47,9 @@ public:
|
|||||||
int error = ::pthread_mutex_init(&mutex_, 0);
|
int error = ::pthread_mutex_init(&mutex_, 0);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
system_exception e("mutex", error);
|
asio::system_error e(
|
||||||
|
asio::error_code(error, asio::native_ecat),
|
||||||
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,7 +66,9 @@ public:
|
|||||||
int error = ::pthread_mutex_lock(&mutex_);
|
int error = ::pthread_mutex_lock(&mutex_);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
system_exception e("mutex", error);
|
asio::system_error e(
|
||||||
|
asio::error_code(error, asio::native_ecat),
|
||||||
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +79,9 @@ public:
|
|||||||
int error = ::pthread_mutex_unlock(&mutex_);
|
int error = ::pthread_mutex_unlock(&mutex_);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
system_exception e("mutex", error);
|
asio::system_error e(
|
||||||
|
asio::error_code(error, asio::native_ecat),
|
||||||
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// posix_signal_blocker.hpp
|
// posix_signal_blocker.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#include "asio/detail/push_options.hpp"
|
#include "asio/detail/push_options.hpp"
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// posix_thread.hpp
|
// posix_thread.hpp
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -29,7 +29,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
@ -51,7 +51,9 @@ public:
|
|||||||
asio_detail_posix_thread_function, arg.get());
|
asio_detail_posix_thread_function, arg.get());
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
system_exception e("thread", error);
|
asio::system_error e(
|
||||||
|
asio::error_code(error, asio::native_ecat),
|
||||||
|
"thread");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
arg.release();
|
arg.release();
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// posix_tss_ptr.hpp
|
// posix_tss_ptr.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
@ -45,7 +45,9 @@ public:
|
|||||||
int error = ::pthread_key_create(&tss_key_, 0);
|
int error = ::pthread_key_create(&tss_key_, 0);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
system_exception e("tss", error);
|
asio::system_error e(
|
||||||
|
asio::error_code(error, asio::native_ecat),
|
||||||
|
"tss");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// push_options.hpp
|
// push_options.hpp
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
|||||||
// reactor_op_queue.hpp
|
// reactor_op_queue.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -100,7 +100,8 @@ public:
|
|||||||
|
|
||||||
// Dispatch the first operation corresponding to the descriptor. Returns true
|
// Dispatch the first operation corresponding to the descriptor. Returns true
|
||||||
// if there are more operations queued for the descriptor.
|
// if there are more operations queued for the descriptor.
|
||||||
bool dispatch_operation(Descriptor descriptor, int result)
|
bool dispatch_operation(Descriptor descriptor,
|
||||||
|
const asio::error_code& result)
|
||||||
{
|
{
|
||||||
typename operation_map::iterator i = operations_.find(descriptor);
|
typename operation_map::iterator i = operations_.find(descriptor);
|
||||||
if (i != operations_.end())
|
if (i != operations_.end())
|
||||||
@ -137,7 +138,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch all operations corresponding to the descriptor.
|
// Dispatch all operations corresponding to the descriptor.
|
||||||
void dispatch_all_operations(Descriptor descriptor, int result)
|
void dispatch_all_operations(Descriptor descriptor,
|
||||||
|
const asio::error_code& result)
|
||||||
{
|
{
|
||||||
typename operation_map::iterator i = operations_.find(descriptor);
|
typename operation_map::iterator i = operations_.find(descriptor);
|
||||||
if (i != operations_.end())
|
if (i != operations_.end())
|
||||||
@ -158,8 +160,8 @@ public:
|
|||||||
i->second = this_op;
|
i->second = this_op;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
operations_.erase(i);
|
|
||||||
}
|
}
|
||||||
|
operations_.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +181,8 @@ public:
|
|||||||
// Dispatch the operations corresponding to the ready file descriptors
|
// Dispatch the operations corresponding to the ready file descriptors
|
||||||
// contained in the given descriptor set.
|
// contained in the given descriptor set.
|
||||||
template <typename Descriptor_Set>
|
template <typename Descriptor_Set>
|
||||||
void dispatch_descriptors(const Descriptor_Set& descriptors, int result)
|
void dispatch_descriptors(const Descriptor_Set& descriptors,
|
||||||
|
const asio::error_code& result)
|
||||||
{
|
{
|
||||||
typename operation_map::iterator i = operations_.begin();
|
typename operation_map::iterator i = operations_.begin();
|
||||||
while (i != operations_.end())
|
while (i != operations_.end())
|
||||||
@ -282,7 +285,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Perform the operation.
|
// Perform the operation.
|
||||||
bool invoke(int result)
|
bool invoke(const asio::error_code& result)
|
||||||
{
|
{
|
||||||
return invoke_func_(this, result);
|
return invoke_func_(this, result);
|
||||||
}
|
}
|
||||||
@ -294,7 +297,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef bool (*invoke_func_type)(op_base*, int);
|
typedef bool (*invoke_func_type)(op_base*,
|
||||||
|
const asio::error_code&);
|
||||||
typedef void (*destroy_func_type)(op_base*);
|
typedef void (*destroy_func_type)(op_base*);
|
||||||
|
|
||||||
// Construct an operation for the given descriptor.
|
// Construct an operation for the given descriptor.
|
||||||
@ -343,7 +347,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the handler.
|
// Invoke the handler.
|
||||||
static bool invoke_handler(op_base* base, int result)
|
static bool invoke_handler(op_base* base,
|
||||||
|
const asio::error_code& result)
|
||||||
{
|
{
|
||||||
return static_cast<op<Handler>*>(base)->handler_(result);
|
return static_cast<op<Handler>*>(base)->handler_(result);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// resolver_service.hpp
|
// resolver_service.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -29,6 +29,7 @@
|
|||||||
#include "asio/detail/bind_handler.hpp"
|
#include "asio/detail/bind_handler.hpp"
|
||||||
#include "asio/detail/mutex.hpp"
|
#include "asio/detail/mutex.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/socket_ops.hpp"
|
#include "asio/detail/socket_ops.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
#include "asio/detail/thread.hpp"
|
#include "asio/detail/thread.hpp"
|
||||||
@ -38,7 +39,7 @@ namespace detail {
|
|||||||
|
|
||||||
template <typename Protocol>
|
template <typename Protocol>
|
||||||
class resolver_service
|
class resolver_service
|
||||||
: public asio::io_service::service
|
: public asio::detail::service_base<resolver_service<Protocol> >
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Helper class to perform exception-safe cleanup of addrinfo objects.
|
// Helper class to perform exception-safe cleanup of addrinfo objects.
|
||||||
@ -84,7 +85,8 @@ public:
|
|||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
resolver_service(asio::io_service& io_service)
|
resolver_service(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<
|
||||||
|
resolver_service<Protocol> >(io_service),
|
||||||
mutex_(),
|
mutex_(),
|
||||||
work_io_service_(new asio::io_service),
|
work_io_service_(new asio::io_service),
|
||||||
work_(new asio::io_service::work(*work_io_service_)),
|
work_(new asio::io_service::work(*work_io_service_)),
|
||||||
@ -104,7 +106,7 @@ public:
|
|||||||
work_.reset();
|
work_.reset();
|
||||||
if (work_io_service_)
|
if (work_io_service_)
|
||||||
{
|
{
|
||||||
work_io_service_->interrupt();
|
work_io_service_->stop();
|
||||||
if (work_thread_)
|
if (work_thread_)
|
||||||
{
|
{
|
||||||
work_thread_->join();
|
work_thread_->join();
|
||||||
@ -132,23 +134,21 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Resolve a query to a list of entries.
|
// Resolve a query to a list of entries.
|
||||||
template <typename Error_Handler>
|
|
||||||
iterator_type resolve(implementation_type&, const query_type& query,
|
iterator_type resolve(implementation_type&, const query_type& query,
|
||||||
Error_Handler error_handler)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
asio::detail::addrinfo_type* address_info = 0;
|
asio::detail::addrinfo_type* address_info = 0;
|
||||||
std::string host_name = query.host_name();
|
std::string host_name = query.host_name();
|
||||||
std::string service_name = query.service_name();
|
std::string service_name = query.service_name();
|
||||||
asio::detail::addrinfo_type hints = query.hints();
|
asio::detail::addrinfo_type hints = query.hints();
|
||||||
|
|
||||||
int result = socket_ops::getaddrinfo(
|
socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0,
|
||||||
host_name.length() ? host_name.c_str() : 0,
|
service_name.c_str(), &hints, &address_info, ec);
|
||||||
service_name.c_str(), &hints, &address_info);
|
|
||||||
auto_addrinfo auto_address_info(address_info);
|
auto_addrinfo auto_address_info(address_info);
|
||||||
|
|
||||||
error_handler(asio::error(result));
|
if (ec)
|
||||||
if (result != 0)
|
|
||||||
return iterator_type();
|
return iterator_type();
|
||||||
|
|
||||||
return iterator_type::create(address_info, host_name, service_name);
|
return iterator_type::create(address_info, host_name, service_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,8 +173,7 @@ public:
|
|||||||
{
|
{
|
||||||
iterator_type iterator;
|
iterator_type iterator;
|
||||||
io_service_.post(asio::detail::bind_handler(handler_,
|
io_service_.post(asio::detail::bind_handler(handler_,
|
||||||
asio::error(asio::error::operation_aborted),
|
asio::error::operation_aborted, iterator));
|
||||||
iterator));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,18 +182,17 @@ public:
|
|||||||
std::string host_name = query_.host_name();
|
std::string host_name = query_.host_name();
|
||||||
std::string service_name = query_.service_name();
|
std::string service_name = query_.service_name();
|
||||||
asio::detail::addrinfo_type hints = query_.hints();
|
asio::detail::addrinfo_type hints = query_.hints();
|
||||||
int result = socket_ops::getaddrinfo(
|
asio::error_code ec;
|
||||||
host_name.length() ? host_name.c_str() : 0,
|
socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0,
|
||||||
service_name.c_str(), &hints, &address_info);
|
service_name.c_str(), &hints, &address_info, ec);
|
||||||
auto_addrinfo auto_address_info(address_info);
|
auto_addrinfo auto_address_info(address_info);
|
||||||
|
|
||||||
// Invoke the handler and pass the result.
|
// Invoke the handler and pass the result.
|
||||||
asio::error e(result);
|
|
||||||
iterator_type iterator;
|
iterator_type iterator;
|
||||||
if (result == 0)
|
if (!ec)
|
||||||
iterator = iterator_type::create(address_info, host_name, service_name);
|
iterator = iterator_type::create(address_info, host_name, service_name);
|
||||||
io_service_.post(asio::detail::bind_handler(
|
io_service_.post(asio::detail::bind_handler(
|
||||||
handler_, e, iterator));
|
handler_, ec, iterator));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -215,32 +213,31 @@ public:
|
|||||||
start_work_thread();
|
start_work_thread();
|
||||||
work_io_service_->post(
|
work_io_service_->post(
|
||||||
resolve_query_handler<Handler>(
|
resolve_query_handler<Handler>(
|
||||||
impl, query, io_service(), handler));
|
impl, query, this->io_service(), handler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve an endpoint to a list of entries.
|
// Resolve an endpoint to a list of entries.
|
||||||
template <typename Error_Handler>
|
|
||||||
iterator_type resolve(implementation_type&,
|
iterator_type resolve(implementation_type&,
|
||||||
const endpoint_type& endpoint, Error_Handler error_handler)
|
const endpoint_type& endpoint, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
// First try resolving with the service name. If that fails try resolving
|
// First try resolving with the service name. If that fails try resolving
|
||||||
// but allow the service to be returned as a number.
|
// but allow the service to be returned as a number.
|
||||||
char host_name[NI_MAXHOST];
|
char host_name[NI_MAXHOST];
|
||||||
char service_name[NI_MAXSERV];
|
char service_name[NI_MAXSERV];
|
||||||
int flags = endpoint.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0;
|
int flags = endpoint.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0;
|
||||||
int result = socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
|
socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
|
||||||
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags);
|
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
|
||||||
if (result)
|
if (ec)
|
||||||
{
|
{
|
||||||
flags |= NI_NUMERICSERV;
|
flags |= NI_NUMERICSERV;
|
||||||
result = socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
|
socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
|
||||||
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags);
|
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
error_handler(asio::error(result));
|
if (ec)
|
||||||
if (result != 0)
|
|
||||||
return iterator_type();
|
return iterator_type();
|
||||||
|
|
||||||
return iterator_type::create(endpoint, host_name, service_name);
|
return iterator_type::create(endpoint, host_name, service_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,8 +263,7 @@ public:
|
|||||||
{
|
{
|
||||||
iterator_type iterator;
|
iterator_type iterator;
|
||||||
io_service_.post(asio::detail::bind_handler(handler_,
|
io_service_.post(asio::detail::bind_handler(handler_,
|
||||||
asio::error(asio::error::operation_aborted),
|
asio::error::operation_aborted, iterator));
|
||||||
iterator));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,22 +273,22 @@ public:
|
|||||||
char host_name[NI_MAXHOST];
|
char host_name[NI_MAXHOST];
|
||||||
char service_name[NI_MAXSERV];
|
char service_name[NI_MAXSERV];
|
||||||
int flags = endpoint_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0;
|
int flags = endpoint_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0;
|
||||||
int result = socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
|
asio::error_code ec;
|
||||||
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags);
|
socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
|
||||||
if (result)
|
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
|
||||||
|
if (ec)
|
||||||
{
|
{
|
||||||
flags |= NI_NUMERICSERV;
|
flags |= NI_NUMERICSERV;
|
||||||
result = socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
|
socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
|
||||||
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags);
|
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the handler and pass the result.
|
// Invoke the handler and pass the result.
|
||||||
asio::error e(result);
|
|
||||||
iterator_type iterator;
|
iterator_type iterator;
|
||||||
if (result == 0)
|
if (!ec)
|
||||||
iterator = iterator_type::create(endpoint_, host_name, service_name);
|
iterator = iterator_type::create(endpoint_, host_name, service_name);
|
||||||
io_service_.post(asio::detail::bind_handler(
|
io_service_.post(asio::detail::bind_handler(
|
||||||
handler_, e, iterator));
|
handler_, ec, iterator));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -313,7 +309,7 @@ public:
|
|||||||
start_work_thread();
|
start_work_thread();
|
||||||
work_io_service_->post(
|
work_io_service_->post(
|
||||||
resolve_endpoint_handler<Handler>(
|
resolve_endpoint_handler<Handler>(
|
||||||
impl, endpoint, io_service(), handler));
|
impl, endpoint, this->io_service(), handler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// scoped_lock.hpp
|
// scoped_lock.hpp
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// select_interrupter.hpp
|
// select_interrupter.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// select_reactor.hpp
|
// select_reactor.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -31,14 +31,15 @@
|
|||||||
#include "asio/detail/fd_set_adapter.hpp"
|
#include "asio/detail/fd_set_adapter.hpp"
|
||||||
#include "asio/detail/mutex.hpp"
|
#include "asio/detail/mutex.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/task_io_service.hpp"
|
|
||||||
#include "asio/detail/thread.hpp"
|
|
||||||
#include "asio/detail/reactor_op_queue.hpp"
|
#include "asio/detail/reactor_op_queue.hpp"
|
||||||
#include "asio/detail/select_interrupter.hpp"
|
#include "asio/detail/select_interrupter.hpp"
|
||||||
#include "asio/detail/select_reactor_fwd.hpp"
|
#include "asio/detail/select_reactor_fwd.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/signal_blocker.hpp"
|
#include "asio/detail/signal_blocker.hpp"
|
||||||
#include "asio/detail/socket_ops.hpp"
|
#include "asio/detail/socket_ops.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
#include "asio/detail/task_io_service.hpp"
|
||||||
|
#include "asio/detail/thread.hpp"
|
||||||
#include "asio/detail/timer_queue.hpp"
|
#include "asio/detail/timer_queue.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
@ -46,12 +47,13 @@ namespace detail {
|
|||||||
|
|
||||||
template <bool Own_Thread>
|
template <bool Own_Thread>
|
||||||
class select_reactor
|
class select_reactor
|
||||||
: public asio::io_service::service
|
: public asio::detail::service_base<select_reactor<Own_Thread> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
select_reactor(asio::io_service& io_service)
|
select_reactor(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<
|
||||||
|
select_reactor<Own_Thread> >(io_service),
|
||||||
mutex_(),
|
mutex_(),
|
||||||
select_in_progress_(false),
|
select_in_progress_(false),
|
||||||
interrupter_(),
|
interrupter_(),
|
||||||
@ -194,6 +196,21 @@ public:
|
|||||||
timer_queues_.push_back(&timer_queue);
|
timer_queues_.push_back(&timer_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove a timer queue from the reactor.
|
||||||
|
template <typename Time_Traits>
|
||||||
|
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
|
||||||
|
{
|
||||||
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||||
|
{
|
||||||
|
if (timer_queues_[i] == &timer_queue)
|
||||||
|
{
|
||||||
|
timer_queues_.erase(timer_queues_.begin() + i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Schedule a timer in the given timer queue to expire at the specified
|
// Schedule a timer in the given timer queue to expire at the specified
|
||||||
// absolute time. The handler object will be invoked when the timer expires.
|
// absolute time. The handler object will be invoked when the timer expires.
|
||||||
template <typename Time_Traits, typename Handler>
|
template <typename Time_Traits, typename Handler>
|
||||||
@ -275,8 +292,9 @@ private:
|
|||||||
timeval* tv = block ? get_timeout(tv_buf) : &tv_buf;
|
timeval* tv = block ? get_timeout(tv_buf) : &tv_buf;
|
||||||
select_in_progress_ = true;
|
select_in_progress_ = true;
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
asio::error_code ec;
|
||||||
int retval = socket_ops::select(static_cast<int>(max_fd + 1),
|
int retval = socket_ops::select(static_cast<int>(max_fd + 1),
|
||||||
read_fds, write_fds, except_fds, tv);
|
read_fds, write_fds, except_fds, tv, ec);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
select_in_progress_ = false;
|
select_in_progress_ = false;
|
||||||
|
|
||||||
@ -292,9 +310,12 @@ private:
|
|||||||
{
|
{
|
||||||
// Exception operations must be processed first to ensure that any
|
// Exception operations must be processed first to ensure that any
|
||||||
// out-of-band data is read before normal data.
|
// out-of-band data is read before normal data.
|
||||||
except_op_queue_.dispatch_descriptors(except_fds, 0);
|
except_op_queue_.dispatch_descriptors(except_fds,
|
||||||
read_op_queue_.dispatch_descriptors(read_fds, 0);
|
asio::error_code());
|
||||||
write_op_queue_.dispatch_descriptors(write_fds, 0);
|
read_op_queue_.dispatch_descriptors(read_fds,
|
||||||
|
asio::error_code());
|
||||||
|
write_op_queue_.dispatch_descriptors(write_fds,
|
||||||
|
asio::error_code());
|
||||||
except_op_queue_.dispatch_cancellations();
|
except_op_queue_.dispatch_cancellations();
|
||||||
read_op_queue_.dispatch_cancellations();
|
read_op_queue_.dispatch_cancellations();
|
||||||
write_op_queue_.dispatch_cancellations();
|
write_op_queue_.dispatch_cancellations();
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// select_reactor_fwd.hpp
|
// select_reactor_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
49
libtorrent/include/libtorrent/asio/detail/service_base.hpp
Normal file
49
libtorrent/include/libtorrent/asio/detail/service_base.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// service_base.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASIO_DETAIL_SERVICE_BASE_HPP
|
||||||
|
#define ASIO_DETAIL_SERVICE_BASE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/io_service.hpp"
|
||||||
|
#include "asio/detail/service_id.hpp"
|
||||||
|
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
// Special service base class to keep classes header-file only.
|
||||||
|
template <typename Type>
|
||||||
|
class service_base
|
||||||
|
: public asio::io_service::service
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static asio::detail::service_id<Type> id;
|
||||||
|
|
||||||
|
// Constructor.
|
||||||
|
service_base(asio::io_service& io_service)
|
||||||
|
: asio::io_service::service(io_service)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
asio::detail::service_id<Type> service_base<Type>::id;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace asio
|
||||||
|
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#endif // ASIO_DETAIL_SERVICE_BASE_HPP
|
||||||
37
libtorrent/include/libtorrent/asio/detail/service_id.hpp
Normal file
37
libtorrent/include/libtorrent/asio/detail/service_id.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// service_id.hpp
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASIO_DETAIL_SERVICE_ID_HPP
|
||||||
|
#define ASIO_DETAIL_SERVICE_ID_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/io_service.hpp"
|
||||||
|
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
// Special derived service id type to keep classes header-file only.
|
||||||
|
template <typename Type>
|
||||||
|
class service_id
|
||||||
|
: public asio::io_service::id
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace asio
|
||||||
|
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#endif // ASIO_DETAIL_SERVICE_ID_HPP
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// service_registry.hpp
|
// service_registry.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -22,19 +22,20 @@
|
|||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/io_service.hpp"
|
||||||
#include "asio/detail/mutex.hpp"
|
#include "asio/detail/mutex.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
#include "asio/detail/service_id.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <typename Owner>
|
|
||||||
class service_registry
|
class service_registry
|
||||||
: private noncopyable
|
: private noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
service_registry(Owner& o)
|
service_registry(asio::io_service& o)
|
||||||
: owner_(o),
|
: owner_(o),
|
||||||
first_service_(0)
|
first_service_(0)
|
||||||
{
|
{
|
||||||
@ -46,7 +47,7 @@ public:
|
|||||||
// Shutdown all services. This must be done in a separate loop before the
|
// Shutdown all services. This must be done in a separate loop before the
|
||||||
// services are destroyed since the destructors of user-defined handler
|
// services are destroyed since the destructors of user-defined handler
|
||||||
// objects may try to access other service objects.
|
// objects may try to access other service objects.
|
||||||
typename Owner::service* service = first_service_;
|
asio::io_service::service* service = first_service_;
|
||||||
while (service)
|
while (service)
|
||||||
{
|
{
|
||||||
service->shutdown_service();
|
service->shutdown_service();
|
||||||
@ -56,7 +57,7 @@ public:
|
|||||||
// Destroy all services.
|
// Destroy all services.
|
||||||
while (first_service_)
|
while (first_service_)
|
||||||
{
|
{
|
||||||
typename Owner::service* next_service = first_service_->next_;
|
asio::io_service::service* next_service = first_service_->next_;
|
||||||
delete first_service_;
|
delete first_service_;
|
||||||
first_service_ = next_service;
|
first_service_ = next_service;
|
||||||
}
|
}
|
||||||
@ -71,10 +72,10 @@ public:
|
|||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
// First see if there is an existing service object for the given type.
|
// First see if there is an existing service object for the given type.
|
||||||
typename Owner::service* service = first_service_;
|
asio::io_service::service* service = first_service_;
|
||||||
while (service)
|
while (service)
|
||||||
{
|
{
|
||||||
if (*service->type_info_ == typeid(Service))
|
if (service_id_matches(*service, Service::id))
|
||||||
return *static_cast<Service*>(service);
|
return *static_cast<Service*>(service);
|
||||||
service = service->next_;
|
service = service->next_;
|
||||||
}
|
}
|
||||||
@ -84,7 +85,7 @@ public:
|
|||||||
// service's constructor.
|
// service's constructor.
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
std::auto_ptr<Service> new_service(new Service(owner_));
|
std::auto_ptr<Service> new_service(new Service(owner_));
|
||||||
new_service->type_info_ = &typeid(Service);
|
init_service_id(*new_service, Service::id);
|
||||||
Service& new_service_ref = *new_service;
|
Service& new_service_ref = *new_service;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
|
||||||
@ -93,7 +94,7 @@ public:
|
|||||||
service = first_service_;
|
service = first_service_;
|
||||||
while (service)
|
while (service)
|
||||||
{
|
{
|
||||||
if (*service->type_info_ == typeid(Service))
|
if (service_id_matches(*service, Service::id))
|
||||||
return *static_cast<Service*>(service);
|
return *static_cast<Service*>(service);
|
||||||
service = service->next_;
|
service = service->next_;
|
||||||
}
|
}
|
||||||
@ -113,18 +114,20 @@ public:
|
|||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
// Check if there is an existing service object for the given type.
|
// Check if there is an existing service object for the given type.
|
||||||
typename Owner::service* service = first_service_;
|
asio::io_service::service* service = first_service_;
|
||||||
while (service)
|
while (service)
|
||||||
{
|
{
|
||||||
if (*service->type_info_ == typeid(Service))
|
if (service_id_matches(*service, Service::id))
|
||||||
return false;
|
return false;
|
||||||
service = service->next_;
|
service = service->next_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take ownership of the service object.
|
// Take ownership of the service object.
|
||||||
new_service->type_info_ = &typeid(Service);
|
init_service_id(*new_service, Service::id);
|
||||||
new_service->next_ = first_service_;
|
new_service->next_ = first_service_;
|
||||||
first_service_ = new_service;
|
first_service_ = new_service;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether a service object of the specified type already exists.
|
// Check whether a service object of the specified type already exists.
|
||||||
@ -133,10 +136,10 @@ public:
|
|||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
typename Owner::service* service = first_service_;
|
asio::io_service::service* service = first_service_;
|
||||||
while (service)
|
while (service)
|
||||||
{
|
{
|
||||||
if (*service->type_info_ == typeid(Service))
|
if (service_id_matches(*service, Service::id))
|
||||||
return true;
|
return true;
|
||||||
service = service->next_;
|
service = service->next_;
|
||||||
}
|
}
|
||||||
@ -145,14 +148,46 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Set a service's id.
|
||||||
|
void init_service_id(asio::io_service::service& service,
|
||||||
|
const asio::io_service::id& id)
|
||||||
|
{
|
||||||
|
service.type_info_ = 0;
|
||||||
|
service.id_ = &id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set a service's id.
|
||||||
|
template <typename Service>
|
||||||
|
void init_service_id(asio::io_service::service& service,
|
||||||
|
const asio::detail::service_id<Service>& /*id*/)
|
||||||
|
{
|
||||||
|
service.type_info_ = &typeid(Service);
|
||||||
|
service.id_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a service matches the given id.
|
||||||
|
bool service_id_matches(const asio::io_service::service& service,
|
||||||
|
const asio::io_service::id& id)
|
||||||
|
{
|
||||||
|
return service.id_ == &id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a service matches the given id.
|
||||||
|
template <typename Service>
|
||||||
|
bool service_id_matches(const asio::io_service::service& service,
|
||||||
|
const asio::detail::service_id<Service>& /*id*/)
|
||||||
|
{
|
||||||
|
return service.type_info_ != 0 && *service.type_info_ == typeid(Service);
|
||||||
|
}
|
||||||
|
|
||||||
// Mutex to protect access to internal data.
|
// Mutex to protect access to internal data.
|
||||||
mutable asio::detail::mutex mutex_;
|
mutable asio::detail::mutex mutex_;
|
||||||
|
|
||||||
// The owner of this service registry and the services it contains.
|
// The owner of this service registry and the services it contains.
|
||||||
Owner& owner_;
|
asio::io_service& owner_;
|
||||||
|
|
||||||
// The first service in the list of contained services.
|
// The first service in the list of contained services.
|
||||||
typename Owner::service* first_service_;
|
asio::io_service::service* first_service_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// service_registry_fwd.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP
|
||||||
|
#define ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
class service_registry;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace asio
|
||||||
|
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#endif // ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// signal_blocker.hpp
|
// signal_blocker.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// signal_init.hpp
|
// signal_init.hpp
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// socket_holder.hpp
|
// socket_holder.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -44,7 +44,10 @@ public:
|
|||||||
~socket_holder()
|
~socket_holder()
|
||||||
{
|
{
|
||||||
if (socket_ != invalid_socket)
|
if (socket_ != invalid_socket)
|
||||||
socket_ops::close(socket_);
|
{
|
||||||
|
asio::error_code ec;
|
||||||
|
socket_ops::close(socket_, ec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the underlying socket.
|
// Get the underlying socket.
|
||||||
@ -58,7 +61,8 @@ public:
|
|||||||
{
|
{
|
||||||
if (socket_ != invalid_socket)
|
if (socket_ != invalid_socket)
|
||||||
{
|
{
|
||||||
socket_ops::close(socket_);
|
asio::error_code ec;
|
||||||
|
socket_ops::close(socket_, ec);
|
||||||
socket_ = invalid_socket;
|
socket_ = invalid_socket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
|||||||
// socket_option.hpp
|
// socket_option.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "asio/detail/push_options.hpp"
|
#include "asio/detail/push_options.hpp"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <stdexcept>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
@ -40,21 +41,34 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct with a specific option value.
|
// Construct with a specific option value.
|
||||||
boolean(bool value)
|
explicit boolean(bool v)
|
||||||
: value_(value ? 1 : 0)
|
: value_(v ? 1 : 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the value of the boolean.
|
// Set the current value of the boolean.
|
||||||
void set(bool value)
|
boolean& operator=(bool v)
|
||||||
{
|
{
|
||||||
value_ = value ? 1 : 0;
|
value_ = v ? 1 : 0;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the current value of the boolean.
|
// Get the current value of the boolean.
|
||||||
bool get() const
|
bool value() const
|
||||||
{
|
{
|
||||||
return value_;
|
return !!value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to bool.
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return !!value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for false.
|
||||||
|
bool operator!() const
|
||||||
|
{
|
||||||
|
return !value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the level of the socket option.
|
// Get the level of the socket option.
|
||||||
@ -92,6 +106,14 @@ public:
|
|||||||
return sizeof(value_);
|
return sizeof(value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the size of the boolean data.
|
||||||
|
template <typename Protocol>
|
||||||
|
void resize(const Protocol&, std::size_t s)
|
||||||
|
{
|
||||||
|
if (s != sizeof(value_))
|
||||||
|
throw std::length_error("boolean socket option resize");
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int value_;
|
int value_;
|
||||||
};
|
};
|
||||||
@ -108,19 +130,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct with a specific option value.
|
// Construct with a specific option value.
|
||||||
integer(int value)
|
explicit integer(int v)
|
||||||
: value_(value)
|
: value_(v)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the value of the int option.
|
// Set the value of the int option.
|
||||||
void set(int value)
|
integer& operator=(int v)
|
||||||
{
|
{
|
||||||
value_ = value;
|
value_ = v;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the current value of the int option.
|
// Get the current value of the int option.
|
||||||
int get() const
|
int value() const
|
||||||
{
|
{
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
@ -160,76 +183,16 @@ public:
|
|||||||
return sizeof(value_);
|
return sizeof(value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
// Set the size of the int data.
|
||||||
int value_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper template for implementing unsigned integer options.
|
|
||||||
template <int Level, int Name>
|
|
||||||
class unsigned_integer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Default constructor.
|
|
||||||
unsigned_integer()
|
|
||||||
: value_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct with a specific option value.
|
|
||||||
unsigned_integer(unsigned int value)
|
|
||||||
: value_(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the value of the int option.
|
|
||||||
void set(unsigned int value)
|
|
||||||
{
|
|
||||||
value_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the current value of the int option.
|
|
||||||
unsigned int get() const
|
|
||||||
{
|
|
||||||
return value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the level of the socket option.
|
|
||||||
template <typename Protocol>
|
template <typename Protocol>
|
||||||
int level(const Protocol&) const
|
void resize(const Protocol&, std::size_t s)
|
||||||
{
|
{
|
||||||
return Level;
|
if (s != sizeof(value_))
|
||||||
}
|
throw std::length_error("integer socket option resize");
|
||||||
|
|
||||||
// Get the name of the socket option.
|
|
||||||
template <typename Protocol>
|
|
||||||
int name(const Protocol&) const
|
|
||||||
{
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the address of the int data.
|
|
||||||
template <typename Protocol>
|
|
||||||
unsigned int* data(const Protocol&)
|
|
||||||
{
|
|
||||||
return &value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the address of the int data.
|
|
||||||
template <typename Protocol>
|
|
||||||
const unsigned int* data(const Protocol&) const
|
|
||||||
{
|
|
||||||
return &value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the size of the int data.
|
|
||||||
template <typename Protocol>
|
|
||||||
std::size_t size(const Protocol&) const
|
|
||||||
{
|
|
||||||
return sizeof(value_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int value_;
|
int value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper template for implementing linger options.
|
// Helper template for implementing linger options.
|
||||||
@ -245,10 +208,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct with specific option values.
|
// Construct with specific option values.
|
||||||
linger(bool value, unsigned short timeout)
|
linger(bool e, int t)
|
||||||
{
|
{
|
||||||
value_.l_onoff = value ? 1 : 0;
|
enabled(e);
|
||||||
value_.l_linger = timeout;
|
timeout(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the value for whether linger is enabled.
|
// Set the value for whether linger is enabled.
|
||||||
@ -264,15 +227,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the value for the linger timeout.
|
// Set the value for the linger timeout.
|
||||||
void timeout(unsigned short value)
|
void timeout(int value)
|
||||||
{
|
{
|
||||||
|
#if defined(WIN32)
|
||||||
|
value_.l_linger = static_cast<u_short>(value);
|
||||||
|
#else
|
||||||
value_.l_linger = value;
|
value_.l_linger = value;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the value for the linger timeout.
|
// Get the value for the linger timeout.
|
||||||
unsigned short timeout() const
|
int timeout() const
|
||||||
{
|
{
|
||||||
return value_.l_linger;
|
return static_cast<int>(value_.l_linger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the level of the socket option.
|
// Get the level of the socket option.
|
||||||
@ -310,6 +277,14 @@ public:
|
|||||||
return sizeof(value_);
|
return sizeof(value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the size of the int data.
|
||||||
|
template <typename Protocol>
|
||||||
|
void resize(const Protocol&, std::size_t s)
|
||||||
|
{
|
||||||
|
if (s != sizeof(value_))
|
||||||
|
throw std::length_error("linger socket option resize");
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::linger value_;
|
::linger value_;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// socket_select_interrupter.hpp
|
// socket_select_interrupter.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -22,6 +22,7 @@
|
|||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/error.hpp"
|
#include "asio/error.hpp"
|
||||||
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/socket_holder.hpp"
|
#include "asio/detail/socket_holder.hpp"
|
||||||
#include "asio/detail/socket_ops.hpp"
|
#include "asio/detail/socket_ops.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
@ -35,17 +36,18 @@ public:
|
|||||||
// Constructor.
|
// Constructor.
|
||||||
socket_select_interrupter()
|
socket_select_interrupter()
|
||||||
{
|
{
|
||||||
socket_holder acceptor(socket_ops::socket(AF_INET, SOCK_STREAM,
|
asio::error_code ec;
|
||||||
IPPROTO_TCP));
|
socket_holder acceptor(socket_ops::socket(
|
||||||
|
AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
|
||||||
if (acceptor.get() == invalid_socket)
|
if (acceptor.get() == invalid_socket)
|
||||||
{
|
{
|
||||||
asio::error e(socket_ops::get_error());
|
asio::system_error e(ec, "socket_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
int opt = 1;
|
int opt = 1;
|
||||||
socket_ops::setsockopt(acceptor.get(),
|
socket_ops::setsockopt(acceptor.get(),
|
||||||
SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec);
|
||||||
|
|
||||||
sockaddr_in4_type addr;
|
sockaddr_in4_type addr;
|
||||||
socket_addr_len_type addr_len = sizeof(addr);
|
socket_addr_len_type addr_len = sizeof(addr);
|
||||||
@ -53,67 +55,69 @@ public:
|
|||||||
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
addr.sin_port = 0;
|
addr.sin_port = 0;
|
||||||
if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr,
|
if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr,
|
||||||
addr_len) == socket_error_retval)
|
addr_len, ec) == socket_error_retval)
|
||||||
{
|
{
|
||||||
asio::error e(socket_ops::get_error());
|
asio::system_error e(ec, "socket_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getsockname(acceptor.get(), (socket_addr_type*)&addr, &addr_len)
|
if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr,
|
||||||
== socket_error_retval)
|
&addr_len, ec) == socket_error_retval)
|
||||||
{
|
{
|
||||||
asio::error e(socket_ops::get_error());
|
asio::system_error e(ec, "socket_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket_ops::listen(acceptor.get(), SOMAXCONN) == socket_error_retval)
|
if (socket_ops::listen(acceptor.get(),
|
||||||
|
SOMAXCONN, ec) == socket_error_retval)
|
||||||
{
|
{
|
||||||
asio::error e(socket_ops::get_error());
|
asio::system_error e(ec, "socket_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_holder client(socket_ops::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
socket_holder client(socket_ops::socket(
|
||||||
|
AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
|
||||||
if (client.get() == invalid_socket)
|
if (client.get() == invalid_socket)
|
||||||
{
|
{
|
||||||
asio::error e(socket_ops::get_error());
|
asio::system_error e(ec, "socket_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr,
|
if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr,
|
||||||
addr_len) == socket_error_retval)
|
addr_len, ec) == socket_error_retval)
|
||||||
{
|
{
|
||||||
asio::error e(socket_ops::get_error());
|
asio::system_error e(ec, "socket_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_holder server(socket_ops::accept(acceptor.get(), 0, 0));
|
socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec));
|
||||||
if (server.get() == invalid_socket)
|
if (server.get() == invalid_socket)
|
||||||
{
|
{
|
||||||
asio::error e(socket_ops::get_error());
|
asio::system_error e(ec, "socket_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
ioctl_arg_type non_blocking = 1;
|
ioctl_arg_type non_blocking = 1;
|
||||||
if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking))
|
if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking, ec))
|
||||||
{
|
{
|
||||||
asio::error e(socket_ops::get_error());
|
asio::system_error e(ec, "socket_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
socket_ops::setsockopt(client.get(),
|
socket_ops::setsockopt(client.get(),
|
||||||
IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
|
IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
|
||||||
|
|
||||||
non_blocking = 1;
|
non_blocking = 1;
|
||||||
if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking))
|
if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking, ec))
|
||||||
{
|
{
|
||||||
asio::error e(socket_ops::get_error());
|
asio::system_error e(ec, "socket_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
socket_ops::setsockopt(server.get(),
|
socket_ops::setsockopt(server.get(),
|
||||||
IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
|
IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
|
||||||
|
|
||||||
read_descriptor_ = server.release();
|
read_descriptor_ = server.release();
|
||||||
write_descriptor_ = client.release();
|
write_descriptor_ = client.release();
|
||||||
@ -122,10 +126,11 @@ public:
|
|||||||
// Destructor.
|
// Destructor.
|
||||||
~socket_select_interrupter()
|
~socket_select_interrupter()
|
||||||
{
|
{
|
||||||
|
asio::error_code ec;
|
||||||
if (read_descriptor_ != invalid_socket)
|
if (read_descriptor_ != invalid_socket)
|
||||||
socket_ops::close(read_descriptor_);
|
socket_ops::close(read_descriptor_, ec);
|
||||||
if (write_descriptor_ != invalid_socket)
|
if (write_descriptor_ != invalid_socket)
|
||||||
socket_ops::close(write_descriptor_);
|
socket_ops::close(write_descriptor_, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interrupt the select call.
|
// Interrupt the select call.
|
||||||
@ -134,7 +139,8 @@ public:
|
|||||||
char byte = 0;
|
char byte = 0;
|
||||||
socket_ops::buf b;
|
socket_ops::buf b;
|
||||||
socket_ops::init_buf(b, &byte, 1);
|
socket_ops::init_buf(b, &byte, 1);
|
||||||
socket_ops::send(write_descriptor_, &b, 1, 0);
|
asio::error_code ec;
|
||||||
|
socket_ops::send(write_descriptor_, &b, 1, 0, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the select interrupt. Returns true if the call was interrupted.
|
// Reset the select interrupt. Returns true if the call was interrupted.
|
||||||
@ -143,10 +149,11 @@ public:
|
|||||||
char data[1024];
|
char data[1024];
|
||||||
socket_ops::buf b;
|
socket_ops::buf b;
|
||||||
socket_ops::init_buf(b, data, sizeof(data));
|
socket_ops::init_buf(b, data, sizeof(data));
|
||||||
int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0);
|
asio::error_code ec;
|
||||||
|
int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
|
||||||
bool was_interrupted = (bytes_read > 0);
|
bool was_interrupted = (bytes_read > 0);
|
||||||
while (bytes_read == sizeof(data))
|
while (bytes_read == sizeof(data))
|
||||||
bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0);
|
bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
|
||||||
return was_interrupted;
|
return was_interrupted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// socket_types.hpp
|
// socket_types.hpp
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -100,6 +100,7 @@
|
|||||||
# include <net/if.h>
|
# include <net/if.h>
|
||||||
# if defined(__sun)
|
# if defined(__sun)
|
||||||
# include <sys/filio.h>
|
# include <sys/filio.h>
|
||||||
|
# include <sys/sockio.h>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
@ -169,13 +170,6 @@ const int message_do_not_route = MSG_DONTROUTE;
|
|||||||
const int custom_socket_option_level = 0xA5100000;
|
const int custom_socket_option_level = 0xA5100000;
|
||||||
const int enable_connection_aborted_option = 1;
|
const int enable_connection_aborted_option = 1;
|
||||||
|
|
||||||
#if defined(_WIN64)
|
|
||||||
std::size_t hash_value(SOCKET s)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(s);
|
|
||||||
}
|
|
||||||
#endif // defined(_WIN64)
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// strand_service.hpp
|
// strand_service.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -30,13 +30,14 @@
|
|||||||
#include "asio/detail/handler_invoke_helpers.hpp"
|
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||||
#include "asio/detail/mutex.hpp"
|
#include "asio/detail/mutex.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
// Default service implementation for a strand.
|
// Default service implementation for a strand.
|
||||||
class strand_service
|
class strand_service
|
||||||
: public asio::io_service::service
|
: public asio::detail::service_base<strand_service>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class handler_base;
|
class handler_base;
|
||||||
@ -241,12 +242,9 @@ public:
|
|||||||
return impl_->handler_storage_.address();
|
return impl_->handler_storage_.address();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Function>
|
// The asio_handler_invoke hook is not defined here since the default one
|
||||||
friend void asio_handler_invoke(Function function,
|
// provides the correct behaviour, and including it here breaks MSVC 7.1
|
||||||
invoke_current_handler*)
|
// in some situations.
|
||||||
{
|
|
||||||
function();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
strand_service& service_impl_;
|
strand_service& service_impl_;
|
||||||
@ -354,7 +352,7 @@ public:
|
|||||||
|
|
||||||
// Construct a new strand service for the specified io_service.
|
// Construct a new strand service for the specified io_service.
|
||||||
explicit strand_service(asio::io_service& io_service)
|
explicit strand_service(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<strand_service>(io_service),
|
||||||
mutex_(),
|
mutex_(),
|
||||||
impl_list_(0)
|
impl_list_(0)
|
||||||
{
|
{
|
||||||
@ -430,7 +428,7 @@ public:
|
|||||||
// This handler now has the lock, so can be dispatched immediately.
|
// This handler now has the lock, so can be dispatched immediately.
|
||||||
impl->current_handler_ = ptr.get();
|
impl->current_handler_ = ptr.get();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
io_service().dispatch(invoke_current_handler(*this, impl));
|
this->io_service().dispatch(invoke_current_handler(*this, impl));
|
||||||
ptr.release();
|
ptr.release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -470,7 +468,7 @@ public:
|
|||||||
// This handler now has the lock, so can be dispatched immediately.
|
// This handler now has the lock, so can be dispatched immediately.
|
||||||
impl->current_handler_ = ptr.get();
|
impl->current_handler_ = ptr.get();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
io_service().post(invoke_current_handler(*this, impl));
|
this->io_service().post(invoke_current_handler(*this, impl));
|
||||||
ptr.release();
|
ptr.release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// task_io_service.hpp
|
// task_io_service.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -17,12 +17,14 @@
|
|||||||
|
|
||||||
#include "asio/detail/push_options.hpp"
|
#include "asio/detail/push_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error_code.hpp"
|
||||||
#include "asio/io_service.hpp"
|
#include "asio/io_service.hpp"
|
||||||
#include "asio/detail/call_stack.hpp"
|
#include "asio/detail/call_stack.hpp"
|
||||||
#include "asio/detail/event.hpp"
|
#include "asio/detail/event.hpp"
|
||||||
#include "asio/detail/handler_alloc_helpers.hpp"
|
#include "asio/detail/handler_alloc_helpers.hpp"
|
||||||
#include "asio/detail/handler_invoke_helpers.hpp"
|
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||||
#include "asio/detail/mutex.hpp"
|
#include "asio/detail/mutex.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/task_io_service_fwd.hpp"
|
#include "asio/detail/task_io_service_fwd.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
@ -30,23 +32,27 @@ namespace detail {
|
|||||||
|
|
||||||
template <typename Task>
|
template <typename Task>
|
||||||
class task_io_service
|
class task_io_service
|
||||||
: public asio::io_service::service
|
: public asio::detail::service_base<task_io_service<Task> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
task_io_service(asio::io_service& io_service)
|
task_io_service(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<task_io_service<Task> >(io_service),
|
||||||
mutex_(),
|
mutex_(),
|
||||||
task_(use_service<Task>(io_service)),
|
task_(use_service<Task>(io_service)),
|
||||||
outstanding_work_(0),
|
outstanding_work_(0),
|
||||||
handler_queue_(&task_handler_),
|
handler_queue_(&task_handler_),
|
||||||
handler_queue_end_(&task_handler_),
|
handler_queue_end_(&task_handler_),
|
||||||
interrupted_(false),
|
stopped_(false),
|
||||||
shutdown_(false),
|
shutdown_(false),
|
||||||
first_idle_thread_(0)
|
first_idle_thread_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(size_t /*concurrency_hint*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Destroy all user-defined handler objects owned by the service.
|
// Destroy all user-defined handler objects owned by the service.
|
||||||
void shutdown_service()
|
void shutdown_service()
|
||||||
{
|
{
|
||||||
@ -69,7 +75,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the event loop until interrupted or no more work.
|
// Run the event loop until interrupted or no more work.
|
||||||
size_t run()
|
size_t run(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
typename call_stack<task_io_service>::context ctx(this);
|
typename call_stack<task_io_service>::context ctx(this);
|
||||||
|
|
||||||
@ -80,14 +86,14 @@ public:
|
|||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
while (do_one(lock, &this_idle_thread))
|
while (do_one(lock, &this_idle_thread, ec))
|
||||||
if (n != (std::numeric_limits<size_t>::max)())
|
if (n != (std::numeric_limits<size_t>::max)())
|
||||||
++n;
|
++n;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run until interrupted or one operation is performed.
|
// Run until interrupted or one operation is performed.
|
||||||
size_t run_one()
|
size_t run_one(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
typename call_stack<task_io_service>::context ctx(this);
|
typename call_stack<task_io_service>::context ctx(this);
|
||||||
|
|
||||||
@ -97,45 +103,45 @@ public:
|
|||||||
|
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
return do_one(lock, &this_idle_thread);
|
return do_one(lock, &this_idle_thread, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poll for operations without blocking.
|
// Poll for operations without blocking.
|
||||||
size_t poll()
|
size_t poll(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
typename call_stack<task_io_service>::context ctx(this);
|
typename call_stack<task_io_service>::context ctx(this);
|
||||||
|
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
while (do_one(lock, 0))
|
while (do_one(lock, 0, ec))
|
||||||
if (n != (std::numeric_limits<size_t>::max)())
|
if (n != (std::numeric_limits<size_t>::max)())
|
||||||
++n;
|
++n;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poll for one operation without blocking.
|
// Poll for one operation without blocking.
|
||||||
size_t poll_one()
|
size_t poll_one(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
typename call_stack<task_io_service>::context ctx(this);
|
typename call_stack<task_io_service>::context ctx(this);
|
||||||
|
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
return do_one(lock, 0);
|
return do_one(lock, 0, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interrupt the event processing loop.
|
// Interrupt the event processing loop.
|
||||||
void interrupt()
|
void stop()
|
||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
interrupt_all_threads();
|
stop_all_threads();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset in preparation for a subsequent run invocation.
|
// Reset in preparation for a subsequent run invocation.
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
interrupted_ = false;
|
stopped_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify that some work has started.
|
// Notify that some work has started.
|
||||||
@ -150,7 +156,7 @@ public:
|
|||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
if (--outstanding_work_ == 0)
|
if (--outstanding_work_ == 0)
|
||||||
interrupt_all_threads();
|
stop_all_threads();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request invocation of the given handler.
|
// Request invocation of the given handler.
|
||||||
@ -204,17 +210,18 @@ private:
|
|||||||
struct idle_thread_info;
|
struct idle_thread_info;
|
||||||
|
|
||||||
size_t do_one(asio::detail::mutex::scoped_lock& lock,
|
size_t do_one(asio::detail::mutex::scoped_lock& lock,
|
||||||
idle_thread_info* this_idle_thread)
|
idle_thread_info* this_idle_thread, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (outstanding_work_ == 0 && !interrupted_)
|
if (outstanding_work_ == 0 && !stopped_)
|
||||||
{
|
{
|
||||||
interrupt_all_threads();
|
stop_all_threads();
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool polling = !this_idle_thread;
|
bool polling = !this_idle_thread;
|
||||||
bool task_has_run = false;
|
bool task_has_run = false;
|
||||||
while (!interrupted_)
|
while (!stopped_)
|
||||||
{
|
{
|
||||||
if (handler_queue_)
|
if (handler_queue_)
|
||||||
{
|
{
|
||||||
@ -230,7 +237,10 @@ private:
|
|||||||
{
|
{
|
||||||
// If the task has already run and we're polling then we're done.
|
// If the task has already run and we're polling then we're done.
|
||||||
if (task_has_run && polling)
|
if (task_has_run && polling)
|
||||||
|
{
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
task_has_run = true;
|
task_has_run = true;
|
||||||
|
|
||||||
task_cleanup c(lock, *this);
|
task_cleanup c(lock, *this);
|
||||||
@ -247,6 +257,7 @@ private:
|
|||||||
// Invoke the handler. May throw an exception.
|
// Invoke the handler. May throw an exception.
|
||||||
h->call(); // call() deletes the handler object
|
h->call(); // call() deletes the handler object
|
||||||
|
|
||||||
|
ec = asio::error_code();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,17 +292,19 @@ private:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interrupt the task and all idle threads.
|
// Stop the task and all idle threads.
|
||||||
void interrupt_all_threads()
|
void stop_all_threads()
|
||||||
{
|
{
|
||||||
interrupted_ = true;
|
stopped_ = true;
|
||||||
interrupt_all_idle_threads();
|
interrupt_all_idle_threads();
|
||||||
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
|
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
|
||||||
task_.interrupt();
|
task_.interrupt();
|
||||||
@ -326,6 +339,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
class task_cleanup;
|
class task_cleanup;
|
||||||
|
friend class task_cleanup;
|
||||||
|
|
||||||
// The base class for all handler wrappers. A function pointer is used
|
// The base class for all handler wrappers. A function pointer is used
|
||||||
// instead of virtual functions to avoid the associated overhead.
|
// instead of virtual functions to avoid the associated overhead.
|
||||||
@ -412,8 +426,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Helper class to perform task-related operations on block exit.
|
// Helper class to perform task-related operations on block exit.
|
||||||
class task_cleanup;
|
|
||||||
friend class task_cleanup;
|
|
||||||
class task_cleanup
|
class task_cleanup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -466,7 +478,7 @@ private:
|
|||||||
{
|
{
|
||||||
lock_.lock();
|
lock_.lock();
|
||||||
if (--task_io_service_.outstanding_work_ == 0)
|
if (--task_io_service_.outstanding_work_ == 0)
|
||||||
task_io_service_.interrupt_all_threads();
|
task_io_service_.stop_all_threads();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -500,8 +512,8 @@ private:
|
|||||||
// The end of a linked list of handlers that are ready to be delivered.
|
// The end of a linked list of handlers that are ready to be delivered.
|
||||||
handler_base* handler_queue_end_;
|
handler_base* handler_queue_end_;
|
||||||
|
|
||||||
// Flag to indicate that the dispatcher has been interrupted.
|
// Flag to indicate that the dispatcher has been stopped.
|
||||||
bool interrupted_;
|
bool stopped_;
|
||||||
|
|
||||||
// Flag to indicate that the dispatcher has been shut down.
|
// Flag to indicate that the dispatcher has been shut down.
|
||||||
bool shutdown_;
|
bool shutdown_;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// task_io_service_fwd.hpp
|
// task_io_service_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// thread.hpp
|
// thread.hpp
|
||||||
// ~~~~~~~~~~
|
// ~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
44
libtorrent/include/libtorrent/asio/detail/throw_error.hpp
Normal file
44
libtorrent/include/libtorrent/asio/detail/throw_error.hpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// throw_error.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASIO_DETAIL_THROW_ERROR_HPP
|
||||||
|
#define ASIO_DETAIL_THROW_ERROR_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
#include <boost/throw_exception.hpp>
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error_code.hpp"
|
||||||
|
#include "asio/system_error.hpp"
|
||||||
|
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
inline void throw_error(const asio::error_code& err)
|
||||||
|
{
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
asio::system_error e(err);
|
||||||
|
boost::throw_exception(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace asio
|
||||||
|
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#endif // ASIO_DETAIL_THROW_ERROR_HPP
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// timer_queue.hpp
|
// timer_queue.hpp
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -111,7 +111,7 @@ public:
|
|||||||
{
|
{
|
||||||
timer_base* t = heap_[0];
|
timer_base* t = heap_[0];
|
||||||
remove_timer(t);
|
remove_timer(t);
|
||||||
t->invoke(0);
|
t->invoke(asio::error_code());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Perform the timer operation and then destroy.
|
// Perform the timer operation and then destroy.
|
||||||
void invoke(int result)
|
void invoke(const asio::error_code& result)
|
||||||
{
|
{
|
||||||
invoke_func_(this, result);
|
invoke_func_(this, result);
|
||||||
}
|
}
|
||||||
@ -172,7 +172,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef void (*invoke_func_type)(timer_base*, int);
|
typedef void (*invoke_func_type)(timer_base*,
|
||||||
|
const asio::error_code&);
|
||||||
typedef void (*destroy_func_type)(timer_base*);
|
typedef void (*destroy_func_type)(timer_base*);
|
||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
@ -234,7 +235,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the handler and then destroy it.
|
// Invoke the handler and then destroy it.
|
||||||
static void invoke_handler(timer_base* base, int result)
|
static void invoke_handler(timer_base* base,
|
||||||
|
const asio::error_code& result)
|
||||||
{
|
{
|
||||||
std::auto_ptr<timer<Handler> > t(static_cast<timer<Handler>*>(base));
|
std::auto_ptr<timer<Handler> > t(static_cast<timer<Handler>*>(base));
|
||||||
t->handler_(result);
|
t->handler_(result);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// timer_queue_base.hpp
|
// timer_queue_base.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// tss_ptr.hpp
|
// tss_ptr.hpp
|
||||||
// ~~~~~~~~~~~
|
// ~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// win_event.hpp
|
// win_event.hpp
|
||||||
// ~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#if defined(BOOST_WINDOWS)
|
#if defined(BOOST_WINDOWS)
|
||||||
|
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
|
||||||
@ -45,7 +45,9 @@ public:
|
|||||||
if (!event_)
|
if (!event_)
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
system_exception e("event", last_error);
|
asio::system_error e(
|
||||||
|
asio::error_code(last_error, asio::native_ecat),
|
||||||
|
"event");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// win_fd_set_adapter.hpp
|
// win_fd_set_adapter.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -28,6 +28,8 @@ namespace detail {
|
|||||||
class win_fd_set_adapter
|
class win_fd_set_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum { win_fd_set_size = 1024 };
|
||||||
|
|
||||||
win_fd_set_adapter()
|
win_fd_set_adapter()
|
||||||
: max_descriptor_(invalid_socket)
|
: max_descriptor_(invalid_socket)
|
||||||
{
|
{
|
||||||
@ -62,7 +64,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
// This structure is defined to be compatible with the Windows API fd_set
|
// This structure is defined to be compatible with the Windows API fd_set
|
||||||
// structure, but without being dependent on the value of FD_SETSIZE.
|
// structure, but without being dependent on the value of FD_SETSIZE.
|
||||||
enum { win_fd_set_size = 1024 };
|
|
||||||
struct win_fd_set
|
struct win_fd_set
|
||||||
{
|
{
|
||||||
u_int fd_count;
|
u_int fd_count;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// win_iocp_io_service.hpp
|
// win_iocp_io_service.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -27,10 +27,11 @@
|
|||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/io_service.hpp"
|
#include "asio/io_service.hpp"
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/call_stack.hpp"
|
#include "asio/detail/call_stack.hpp"
|
||||||
#include "asio/detail/handler_alloc_helpers.hpp"
|
#include "asio/detail/handler_alloc_helpers.hpp"
|
||||||
#include "asio/detail/handler_invoke_helpers.hpp"
|
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||||
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
#include "asio/detail/win_iocp_operation.hpp"
|
#include "asio/detail/win_iocp_operation.hpp"
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ namespace asio {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
class win_iocp_io_service
|
class win_iocp_io_service
|
||||||
: public asio::io_service::service
|
: public asio::detail::service_base<win_iocp_io_service>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Base class for all operations.
|
// Base class for all operations.
|
||||||
@ -46,16 +47,24 @@ public:
|
|||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
win_iocp_io_service(asio::io_service& io_service)
|
win_iocp_io_service(asio::io_service& io_service)
|
||||||
: asio::io_service::service(io_service),
|
: asio::detail::service_base<win_iocp_io_service>(io_service),
|
||||||
iocp_(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0)),
|
iocp_(),
|
||||||
outstanding_work_(0),
|
outstanding_work_(0),
|
||||||
interrupted_(0),
|
stopped_(0),
|
||||||
shutdown_(0)
|
shutdown_(0)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(size_t concurrency_hint)
|
||||||
|
{
|
||||||
|
iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,
|
||||||
|
static_cast<DWORD>((std::min<size_t>)(concurrency_hint, DWORD(~0))));
|
||||||
if (!iocp_.handle)
|
if (!iocp_.handle)
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
system_exception e("iocp", last_error);
|
asio::system_error e(
|
||||||
|
asio::error_code(last_error, asio::native_ecat),
|
||||||
|
"iocp");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,84 +83,98 @@ public:
|
|||||||
DWORD_PTR completion_key = 0;
|
DWORD_PTR completion_key = 0;
|
||||||
#endif
|
#endif
|
||||||
LPOVERLAPPED overlapped = 0;
|
LPOVERLAPPED overlapped = 0;
|
||||||
::GetQueuedCompletionStatus(iocp_.handle,
|
::SetLastError(0);
|
||||||
|
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle,
|
||||||
&bytes_transferred, &completion_key, &overlapped, 0);
|
&bytes_transferred, &completion_key, &overlapped, 0);
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
if (last_error == WAIT_TIMEOUT)
|
if (!ok && overlapped == 0 && last_error == WAIT_TIMEOUT)
|
||||||
break;
|
break;
|
||||||
if (overlapped)
|
if (overlapped)
|
||||||
static_cast<operation*>(overlapped)->destroy();
|
static_cast<operation*>(overlapped)->destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register a socket with the IO completion port.
|
// Register a handle with the IO completion port.
|
||||||
void register_socket(socket_type sock)
|
void register_handle(HANDLE handle)
|
||||||
{
|
{
|
||||||
HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);
|
::CreateIoCompletionPort(handle, iocp_.handle, 0, 0);
|
||||||
::CreateIoCompletionPort(sock_as_handle, iocp_.handle, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the event loop until interrupted or no more work.
|
// Run the event loop until stopped or no more work.
|
||||||
size_t run()
|
size_t run(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
|
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
|
||||||
|
{
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
call_stack<win_iocp_io_service>::context ctx(this);
|
call_stack<win_iocp_io_service>::context ctx(this);
|
||||||
|
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
while (do_one(true))
|
while (do_one(true, ec))
|
||||||
if (n != (std::numeric_limits<size_t>::max)())
|
if (n != (std::numeric_limits<size_t>::max)())
|
||||||
++n;
|
++n;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run until interrupted or one operation is performed.
|
// Run until stopped or one operation is performed.
|
||||||
size_t run_one()
|
size_t run_one(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
|
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
|
||||||
|
{
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
call_stack<win_iocp_io_service>::context ctx(this);
|
call_stack<win_iocp_io_service>::context ctx(this);
|
||||||
|
|
||||||
return do_one(true);
|
return do_one(true, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poll for operations without blocking.
|
// Poll for operations without blocking.
|
||||||
size_t poll()
|
size_t poll(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
|
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
|
||||||
|
{
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
call_stack<win_iocp_io_service>::context ctx(this);
|
call_stack<win_iocp_io_service>::context ctx(this);
|
||||||
|
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
while (do_one(false))
|
while (do_one(false, ec))
|
||||||
if (n != (std::numeric_limits<size_t>::max)())
|
if (n != (std::numeric_limits<size_t>::max)())
|
||||||
++n;
|
++n;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poll for one operation without blocking.
|
// Poll for one operation without blocking.
|
||||||
size_t poll_one()
|
size_t poll_one(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
|
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
|
||||||
|
{
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
call_stack<win_iocp_io_service>::context ctx(this);
|
call_stack<win_iocp_io_service>::context ctx(this);
|
||||||
|
|
||||||
return do_one(false);
|
return do_one(false, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interrupt the event processing loop.
|
// Stop the event processing loop.
|
||||||
void interrupt()
|
void stop()
|
||||||
{
|
{
|
||||||
if (::InterlockedExchange(&interrupted_, 1) == 0)
|
if (::InterlockedExchange(&stopped_, 1) == 0)
|
||||||
{
|
{
|
||||||
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
|
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
system_exception e("pqcs", last_error);
|
asio::system_error e(
|
||||||
|
asio::error_code(last_error, asio::native_ecat),
|
||||||
|
"pqcs");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +183,7 @@ public:
|
|||||||
// Reset in preparation for a subsequent run invocation.
|
// Reset in preparation for a subsequent run invocation.
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
::InterlockedExchange(&interrupted_, 0);
|
::InterlockedExchange(&stopped_, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify that some work has started.
|
// Notify that some work has started.
|
||||||
@ -173,7 +196,7 @@ public:
|
|||||||
void work_finished()
|
void work_finished()
|
||||||
{
|
{
|
||||||
if (::InterlockedDecrement(&outstanding_work_) == 0)
|
if (::InterlockedDecrement(&outstanding_work_) == 0)
|
||||||
interrupt();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request invocation of the given handler.
|
// Request invocation of the given handler.
|
||||||
@ -204,7 +227,9 @@ public:
|
|||||||
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, ptr.get()))
|
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, ptr.get()))
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
system_exception e("pqcs", last_error);
|
asio::system_error e(
|
||||||
|
asio::error_code(last_error, asio::native_ecat),
|
||||||
|
"pqcs");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +246,9 @@ public:
|
|||||||
bytes_transferred, op_last_error, op))
|
bytes_transferred, op_last_error, op))
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
system_exception e("pqcs", last_error);
|
asio::system_error e(
|
||||||
|
asio::error_code(last_error, asio::native_ecat),
|
||||||
|
"pqcs");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,7 +257,7 @@ private:
|
|||||||
// Dequeues at most one operation from the I/O completion port, and then
|
// Dequeues at most one operation from the I/O completion port, and then
|
||||||
// executes it. Returns the number of operations that were dequeued (i.e.
|
// executes it. Returns the number of operations that were dequeued (i.e.
|
||||||
// either 0 or 1).
|
// either 0 or 1).
|
||||||
size_t do_one(bool block)
|
size_t do_one(bool block, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@ -244,11 +271,16 @@ private:
|
|||||||
LPOVERLAPPED overlapped = 0;
|
LPOVERLAPPED overlapped = 0;
|
||||||
::SetLastError(0);
|
::SetLastError(0);
|
||||||
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
|
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
|
||||||
&completion_key, &overlapped, block ? INFINITE : 0);
|
&completion_key, &overlapped, block ? 1000 : 0);
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
|
|
||||||
if (!ok && overlapped == 0)
|
if (!ok && overlapped == 0)
|
||||||
|
{
|
||||||
|
if (block && last_error == WAIT_TIMEOUT)
|
||||||
|
continue;
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (overlapped)
|
if (overlapped)
|
||||||
{
|
{
|
||||||
@ -266,22 +298,25 @@ private:
|
|||||||
operation* op = static_cast<operation*>(overlapped);
|
operation* op = static_cast<operation*>(overlapped);
|
||||||
op->do_completion(last_error, bytes_transferred);
|
op->do_completion(last_error, bytes_transferred);
|
||||||
|
|
||||||
|
ec = asio::error_code();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The interrupted_ flag is always checked to ensure that any leftover
|
// The stopped_ flag is always checked to ensure that any leftover
|
||||||
// interrupts from a previous run invocation are ignored.
|
// interrupts from a previous run invocation are ignored.
|
||||||
if (::InterlockedExchangeAdd(&interrupted_, 0) != 0)
|
if (::InterlockedExchangeAdd(&stopped_, 0) != 0)
|
||||||
{
|
{
|
||||||
// Wake up next thread that is blocked on GetQueuedCompletionStatus.
|
// Wake up next thread that is blocked on GetQueuedCompletionStatus.
|
||||||
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
|
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
system_exception e("pqcs", last_error);
|
ec = asio::error_code(last_error,
|
||||||
boost::throw_exception(e);
|
asio::native_ecat);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,15 +400,15 @@ private:
|
|||||||
struct iocp_holder
|
struct iocp_holder
|
||||||
{
|
{
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
iocp_holder(HANDLE h) : handle(h) {}
|
iocp_holder() : handle(0) {}
|
||||||
~iocp_holder() { ::CloseHandle(handle); }
|
~iocp_holder() { if (handle) ::CloseHandle(handle); }
|
||||||
} iocp_;
|
} iocp_;
|
||||||
|
|
||||||
// The count of unfinished work.
|
// The count of unfinished work.
|
||||||
long outstanding_work_;
|
long outstanding_work_;
|
||||||
|
|
||||||
// Flag to indicate whether the event loop has been interrupted.
|
// Flag to indicate whether the event loop has been stopped.
|
||||||
long interrupted_;
|
long stopped_;
|
||||||
|
|
||||||
// Flag to indicate whether the service has been shut down.
|
// Flag to indicate whether the service has been shut down.
|
||||||
long shutdown_;
|
long shutdown_;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// win_iocp_io_service_fwd.hpp
|
// win_iocp_io_service_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// win_iocp_operation.hpp
|
// win_iocp_operation.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
|||||||
// win_mutex.hpp
|
// win_mutex.hpp
|
||||||
// ~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#if defined(BOOST_WINDOWS)
|
#if defined(BOOST_WINDOWS)
|
||||||
|
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
#include "asio/detail/scoped_lock.hpp"
|
#include "asio/detail/scoped_lock.hpp"
|
||||||
@ -47,7 +47,9 @@ public:
|
|||||||
int error = do_init();
|
int error = do_init();
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
system_exception e("mutex", error);
|
asio::system_error e(
|
||||||
|
asio::error_code(error, asio::native_ecat),
|
||||||
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,7 +66,9 @@ public:
|
|||||||
int error = do_lock();
|
int error = do_lock();
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
system_exception e("mutex", error);
|
asio::system_error e(
|
||||||
|
asio::error_code(error, asio::native_ecat),
|
||||||
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// win_signal_blocker.hpp
|
// win_signal_blocker.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// win_thread.hpp
|
// win_thread.hpp
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#if defined(BOOST_WINDOWS)
|
#if defined(BOOST_WINDOWS)
|
||||||
|
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
|
||||||
@ -53,7 +53,9 @@ public:
|
|||||||
if (!thread_)
|
if (!thread_)
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
system_exception e("thread", last_error);
|
asio::system_error e(
|
||||||
|
asio::error_code(last_error, asio::native_ecat),
|
||||||
|
"thread");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
arg.release();
|
arg.release();
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// win_tss_ptr.hpp
|
// win_tss_ptr.hpp
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#if defined(BOOST_WINDOWS)
|
#if defined(BOOST_WINDOWS)
|
||||||
|
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
|
||||||
@ -46,7 +46,9 @@ public:
|
|||||||
if (tss_key_ == TLS_OUT_OF_INDEXES)
|
if (tss_key_ == TLS_OUT_OF_INDEXES)
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
system_exception e("tss", last_error);
|
asio::system_error e(
|
||||||
|
asio::error_code(last_error, asio::native_ecat),
|
||||||
|
"tss");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// winsock_init.hpp
|
// winsock_init.hpp
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/system_exception.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
|
||||||
@ -84,7 +84,9 @@ public:
|
|||||||
// catch the exception.
|
// catch the exception.
|
||||||
if (this != &instance_ && ref_->result() != 0)
|
if (this != &instance_ && ref_->result() != 0)
|
||||||
{
|
{
|
||||||
system_exception e("winsock", ref_->result());
|
asio::system_error e(
|
||||||
|
asio::error_code(ref_->result(), asio::native_ecat),
|
||||||
|
"winsock");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// wrapped_handler.hpp
|
// wrapped_handler.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// error.hpp
|
// error.hpp
|
||||||
// ~~~~~~~~~
|
// ~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -18,369 +18,349 @@
|
|||||||
#include "asio/detail/push_options.hpp"
|
#include "asio/detail/push_options.hpp"
|
||||||
|
|
||||||
#include "asio/detail/push_options.hpp"
|
#include "asio/detail/push_options.hpp"
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/scoped_ptr.hpp>
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstring>
|
#include <boost/config.hpp>
|
||||||
#include <exception>
|
|
||||||
#include <string>
|
|
||||||
#include <boost/detail/workaround.hpp>
|
|
||||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
|
||||||
# include <iostream>
|
|
||||||
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error_code.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
#include "asio/detail/win_local_free_on_block_exit.hpp"
|
|
||||||
|
|
||||||
namespace asio {
|
|
||||||
|
|
||||||
#if defined(GENERATING_DOCUMENTATION)
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
/// INTERNAL ONLY.
|
/// INTERNAL ONLY.
|
||||||
|
# define ASIO_NATIVE_ERROR(e) implementation_defined
|
||||||
|
/// INTERNAL ONLY.
|
||||||
# define ASIO_SOCKET_ERROR(e) implementation_defined
|
# define ASIO_SOCKET_ERROR(e) implementation_defined
|
||||||
/// INTERNAL ONLY.
|
/// INTERNAL ONLY.
|
||||||
# define ASIO_NETDB_ERROR(e) implementation_defined
|
# define ASIO_NETDB_ERROR(e) implementation_defined
|
||||||
/// INTERNAL ONLY.
|
/// INTERNAL ONLY.
|
||||||
# define ASIO_GETADDRINFO_ERROR(e) implementation_defined
|
# define ASIO_GETADDRINFO_ERROR(e) implementation_defined
|
||||||
/// INTERNAL ONLY.
|
/// INTERNAL ONLY.
|
||||||
# define ASIO_OS_ERROR(e_win, e_posix) implementation_defined
|
# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined
|
||||||
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
# define ASIO_SOCKET_ERROR(e) WSA ## e
|
# define ASIO_NATIVE_ERROR(e) \
|
||||||
# define ASIO_NETDB_ERROR(e) WSA ## e
|
asio::error_code(e, \
|
||||||
# define ASIO_GETADDRINFO_ERROR(e) e
|
asio::native_ecat)
|
||||||
# define ASIO_OS_ERROR(e_win, e_posix) e_win
|
# define ASIO_SOCKET_ERROR(e) \
|
||||||
|
asio::error_code(WSA ## e, \
|
||||||
|
asio::native_ecat)
|
||||||
|
# define ASIO_NETDB_ERROR(e) \
|
||||||
|
asio::error_code(WSA ## e, \
|
||||||
|
asio::native_ecat)
|
||||||
|
# define ASIO_GETADDRINFO_ERROR(e) \
|
||||||
|
asio::error_code(WSA ## e, \
|
||||||
|
asio::native_ecat)
|
||||||
|
# define ASIO_MISC_ERROR(e) \
|
||||||
|
asio::error_code(e, \
|
||||||
|
asio::misc_ecat)
|
||||||
|
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win
|
||||||
#else
|
#else
|
||||||
# define ASIO_SOCKET_ERROR(e) e
|
# define ASIO_NATIVE_ERROR(e) \
|
||||||
# define ASIO_NETDB_ERROR(e) 16384 + e
|
asio::error_code(e, \
|
||||||
# define ASIO_GETADDRINFO_ERROR(e) 32768 + e
|
asio::native_ecat)
|
||||||
# define ASIO_OS_ERROR(e_win, e_posix) e_posix
|
# define ASIO_SOCKET_ERROR(e) \
|
||||||
|
asio::error_code(e, \
|
||||||
|
asio::native_ecat)
|
||||||
|
# define ASIO_NETDB_ERROR(e) \
|
||||||
|
asio::error_code(e, \
|
||||||
|
asio::netdb_ecat)
|
||||||
|
# define ASIO_GETADDRINFO_ERROR(e) \
|
||||||
|
asio::error_code(e, \
|
||||||
|
asio::addrinfo_ecat)
|
||||||
|
# define ASIO_MISC_ERROR(e) \
|
||||||
|
asio::error_code(e, \
|
||||||
|
asio::misc_ecat)
|
||||||
|
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// The error class is used to encapsulate system error codes.
|
namespace asio {
|
||||||
class error
|
|
||||||
: public std::exception
|
namespace detail {
|
||||||
|
|
||||||
|
/// Hack to keep asio library header-file-only.
|
||||||
|
template <typename T>
|
||||||
|
class error_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Error codes.
|
// boostify: error category declarations go here.
|
||||||
enum code_type
|
|
||||||
{
|
|
||||||
/// Permission denied.
|
/// Permission denied.
|
||||||
access_denied = ASIO_SOCKET_ERROR(EACCES),
|
static const asio::error_code access_denied;
|
||||||
|
|
||||||
/// Address family not supported by protocol.
|
/// Address family not supported by protocol.
|
||||||
address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT),
|
static const asio::error_code address_family_not_supported;
|
||||||
|
|
||||||
/// Address already in use.
|
/// Address already in use.
|
||||||
address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE),
|
static const asio::error_code address_in_use;
|
||||||
|
|
||||||
/// Transport endpoint is already connected.
|
/// Transport endpoint is already connected.
|
||||||
already_connected = ASIO_SOCKET_ERROR(EISCONN),
|
static const asio::error_code already_connected;
|
||||||
|
|
||||||
|
/// Already open.
|
||||||
|
static const asio::error_code already_open;
|
||||||
|
|
||||||
/// Operation already in progress.
|
/// Operation already in progress.
|
||||||
already_started = ASIO_SOCKET_ERROR(EALREADY),
|
static const asio::error_code already_started;
|
||||||
|
|
||||||
/// A connection has been aborted.
|
/// A connection has been aborted.
|
||||||
connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED),
|
static const asio::error_code connection_aborted;
|
||||||
|
|
||||||
/// Connection refused.
|
/// Connection refused.
|
||||||
connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED),
|
static const asio::error_code connection_refused;
|
||||||
|
|
||||||
/// Connection reset by peer.
|
/// Connection reset by peer.
|
||||||
connection_reset = ASIO_SOCKET_ERROR(ECONNRESET),
|
static const asio::error_code connection_reset;
|
||||||
|
|
||||||
/// Bad file descriptor.
|
/// Bad file descriptor.
|
||||||
bad_descriptor = ASIO_SOCKET_ERROR(EBADF),
|
static const asio::error_code bad_descriptor;
|
||||||
|
|
||||||
/// End of file or stream.
|
/// End of file or stream.
|
||||||
eof = ASIO_OS_ERROR(ERROR_HANDLE_EOF, -1),
|
static const asio::error_code eof;
|
||||||
|
|
||||||
/// Bad address.
|
/// Bad address.
|
||||||
fault = ASIO_SOCKET_ERROR(EFAULT),
|
static const asio::error_code fault;
|
||||||
|
|
||||||
/// Host not found (authoritative).
|
/// Host not found (authoritative).
|
||||||
host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND),
|
static const asio::error_code host_not_found;
|
||||||
|
|
||||||
/// Host not found (non-authoritative).
|
/// Host not found (non-authoritative).
|
||||||
host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN),
|
static const asio::error_code host_not_found_try_again;
|
||||||
|
|
||||||
/// No route to host.
|
/// No route to host.
|
||||||
host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH),
|
static const asio::error_code host_unreachable;
|
||||||
|
|
||||||
/// Operation now in progress.
|
/// Operation now in progress.
|
||||||
in_progress = ASIO_SOCKET_ERROR(EINPROGRESS),
|
static const asio::error_code in_progress;
|
||||||
|
|
||||||
/// Interrupted system call.
|
/// Interrupted system call.
|
||||||
interrupted = ASIO_SOCKET_ERROR(EINTR),
|
static const asio::error_code interrupted;
|
||||||
|
|
||||||
/// Invalid argument.
|
/// Invalid argument.
|
||||||
invalid_argument = ASIO_SOCKET_ERROR(EINVAL),
|
static const asio::error_code invalid_argument;
|
||||||
|
|
||||||
/// Message too long.
|
/// Message too long.
|
||||||
message_size = ASIO_SOCKET_ERROR(EMSGSIZE),
|
static const asio::error_code message_size;
|
||||||
|
|
||||||
/// Network is down.
|
/// Network is down.
|
||||||
network_down = ASIO_SOCKET_ERROR(ENETDOWN),
|
static const asio::error_code network_down;
|
||||||
|
|
||||||
/// Network dropped connection on reset.
|
/// Network dropped connection on reset.
|
||||||
network_reset = ASIO_SOCKET_ERROR(ENETRESET),
|
static const asio::error_code network_reset;
|
||||||
|
|
||||||
/// Network is unreachable.
|
/// Network is unreachable.
|
||||||
network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH),
|
static const asio::error_code network_unreachable;
|
||||||
|
|
||||||
/// Too many open files.
|
/// Too many open files.
|
||||||
no_descriptors = ASIO_SOCKET_ERROR(EMFILE),
|
static const asio::error_code no_descriptors;
|
||||||
|
|
||||||
/// No buffer space available.
|
/// No buffer space available.
|
||||||
no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS),
|
static const asio::error_code no_buffer_space;
|
||||||
|
|
||||||
/// The query is valid but does not have associated address data.
|
/// The query is valid but does not have associated address data.
|
||||||
no_data = ASIO_NETDB_ERROR(NO_DATA),
|
static const asio::error_code no_data;
|
||||||
|
|
||||||
/// Cannot allocate memory.
|
/// Cannot allocate memory.
|
||||||
no_memory = ASIO_OS_ERROR(ERROR_OUTOFMEMORY, ENOMEM),
|
static const asio::error_code no_memory;
|
||||||
|
|
||||||
/// Operation not permitted.
|
/// Operation not permitted.
|
||||||
no_permission = ASIO_OS_ERROR(ERROR_ACCESS_DENIED, EPERM),
|
static const asio::error_code no_permission;
|
||||||
|
|
||||||
/// Protocol not available.
|
/// Protocol not available.
|
||||||
no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT),
|
static const asio::error_code no_protocol_option;
|
||||||
|
|
||||||
/// A non-recoverable error occurred.
|
/// A non-recoverable error occurred.
|
||||||
no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY),
|
static const asio::error_code no_recovery;
|
||||||
|
|
||||||
/// Transport endpoint is not connected.
|
/// Transport endpoint is not connected.
|
||||||
not_connected = ASIO_SOCKET_ERROR(ENOTCONN),
|
static const asio::error_code not_connected;
|
||||||
|
|
||||||
|
/// Element not found.
|
||||||
|
static const asio::error_code not_found;
|
||||||
|
|
||||||
/// Socket operation on non-socket.
|
/// Socket operation on non-socket.
|
||||||
not_socket = ASIO_SOCKET_ERROR(ENOTSOCK),
|
static const asio::error_code not_socket;
|
||||||
|
|
||||||
/// Operation not supported.
|
|
||||||
not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP),
|
|
||||||
|
|
||||||
/// Operation cancelled.
|
/// Operation cancelled.
|
||||||
operation_aborted = ASIO_OS_ERROR(ERROR_OPERATION_ABORTED, ECANCELED),
|
static const asio::error_code operation_aborted;
|
||||||
|
|
||||||
|
/// Operation not supported.
|
||||||
|
static const asio::error_code operation_not_supported;
|
||||||
|
|
||||||
/// The service is not supported for the given socket type.
|
/// The service is not supported for the given socket type.
|
||||||
service_not_found = ASIO_OS_ERROR(
|
static const asio::error_code service_not_found;
|
||||||
WSATYPE_NOT_FOUND,
|
|
||||||
ASIO_GETADDRINFO_ERROR(EAI_SERVICE)),
|
|
||||||
|
|
||||||
/// The socket type is not supported.
|
/// The socket type is not supported.
|
||||||
socket_type_not_supported = ASIO_OS_ERROR(
|
static const asio::error_code socket_type_not_supported;
|
||||||
WSAESOCKTNOSUPPORT,
|
|
||||||
ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE)),
|
|
||||||
|
|
||||||
/// Cannot send after transport endpoint shutdown.
|
/// Cannot send after transport endpoint shutdown.
|
||||||
shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN),
|
static const asio::error_code shut_down;
|
||||||
|
|
||||||
/// Success.
|
|
||||||
success = 0,
|
|
||||||
|
|
||||||
/// Connection timed out.
|
/// Connection timed out.
|
||||||
timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT),
|
static const asio::error_code timed_out;
|
||||||
|
|
||||||
/// Resource temporarily unavailable.
|
/// Resource temporarily unavailable.
|
||||||
try_again = ASIO_OS_ERROR(ERROR_RETRY, EAGAIN),
|
static const asio::error_code try_again;
|
||||||
|
|
||||||
/// The socket is marked non-blocking and the requested operation would
|
/// The socket is marked non-blocking and the requested operation would block.
|
||||||
/// block.
|
static const asio::error_code would_block;
|
||||||
would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK)
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Default constructor.
|
|
||||||
error()
|
|
||||||
: code_(success)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct with a specific error code.
|
|
||||||
error(int code)
|
|
||||||
: code_(code)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy constructor.
|
|
||||||
error(const error& e)
|
|
||||||
: std::exception(e),
|
|
||||||
code_(e.code_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Destructor.
|
|
||||||
virtual ~error() throw ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Assignment operator.
|
|
||||||
error& operator=(const error& e)
|
|
||||||
{
|
|
||||||
code_ = e.code_;
|
|
||||||
what_.reset();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a string representation of the exception.
|
|
||||||
virtual const char* what() const throw ()
|
|
||||||
{
|
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!what_)
|
|
||||||
{
|
|
||||||
char* msg = 0;
|
|
||||||
DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
|
||||||
| FORMAT_MESSAGE_FROM_SYSTEM
|
|
||||||
| FORMAT_MESSAGE_IGNORE_INSERTS, 0, code_,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
||||||
detail::win_local_free_on_block_exit local_free_obj(msg);
|
|
||||||
if (length && msg[length - 1] == '\n')
|
|
||||||
msg[--length] = '\0';
|
|
||||||
if (length && msg[length - 1] == '\r')
|
|
||||||
msg[--length] = '\0';
|
|
||||||
if (length)
|
|
||||||
what_.reset(new std::string(msg));
|
|
||||||
else
|
|
||||||
return "asio error";
|
|
||||||
}
|
|
||||||
return what_->c_str();
|
|
||||||
}
|
|
||||||
catch (std::exception&)
|
|
||||||
{
|
|
||||||
return "asio error";
|
|
||||||
}
|
|
||||||
#else // defined(BOOST_WINDOWS)
|
|
||||||
switch (code_)
|
|
||||||
{
|
|
||||||
case error::eof:
|
|
||||||
return "End of file.";
|
|
||||||
case error::host_not_found:
|
|
||||||
return "Host not found (authoritative).";
|
|
||||||
case error::host_not_found_try_again:
|
|
||||||
return "Host not found (non-authoritative), try again later.";
|
|
||||||
case error::no_recovery:
|
|
||||||
return "A non-recoverable error occurred during database lookup.";
|
|
||||||
case error::no_data:
|
|
||||||
return "The query is valid, but it does not have associated data.";
|
|
||||||
#if !defined(__sun)
|
|
||||||
case error::operation_aborted:
|
|
||||||
return "Operation aborted.";
|
|
||||||
#endif // !defined(__sun)
|
|
||||||
case error::service_not_found:
|
|
||||||
return "Service not found.";
|
|
||||||
case error::socket_type_not_supported:
|
|
||||||
return "Socket type not supported.";
|
|
||||||
default:
|
|
||||||
#if defined(__sun) || defined(__QNX__)
|
|
||||||
return strerror(code_);
|
|
||||||
#elif defined(__MACH__) && defined(__APPLE__) \
|
|
||||||
|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
char buf[256] = "";
|
|
||||||
strerror_r(code_, buf, sizeof(buf));
|
|
||||||
what_.reset(new std::string(buf));
|
|
||||||
return what_->c_str();
|
|
||||||
}
|
|
||||||
catch (std::exception&)
|
|
||||||
{
|
|
||||||
return "asio error";
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
try
|
|
||||||
{
|
|
||||||
char buf[256] = "";
|
|
||||||
what_.reset(new std::string(strerror_r(code_, buf, sizeof(buf))));
|
|
||||||
return what_->c_str();
|
|
||||||
}
|
|
||||||
catch (std::exception&)
|
|
||||||
{
|
|
||||||
return "asio error";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif // defined(BOOST_WINDOWS)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the code associated with the error.
|
|
||||||
int code() const
|
|
||||||
{
|
|
||||||
return code_;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct unspecified_bool_type_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef unspecified_bool_type_t* unspecified_bool_type;
|
|
||||||
|
|
||||||
/// Operator returns non-null if there is a non-success error code.
|
|
||||||
operator unspecified_bool_type() const
|
|
||||||
{
|
|
||||||
if (code_ == success)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return reinterpret_cast<unspecified_bool_type>(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Operator to test if the error represents success.
|
|
||||||
bool operator!() const
|
|
||||||
{
|
|
||||||
return code_ == success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Equality operator to compare two error objects.
|
|
||||||
friend bool operator==(const error& e1, const error& e2)
|
|
||||||
{
|
|
||||||
return e1.code_ == e2.code_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inequality operator to compare two error objects.
|
|
||||||
friend bool operator!=(const error& e1, const error& e2)
|
|
||||||
{
|
|
||||||
return e1.code_ != e2.code_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The code associated with the error.
|
error_base();
|
||||||
int code_;
|
|
||||||
|
|
||||||
// The string representation of the error.
|
|
||||||
mutable boost::scoped_ptr<std::string> what_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Output the string associated with an error.
|
// boostify: error category definitions go here.
|
||||||
/**
|
|
||||||
* Used to output a human-readable string that is associated with an error.
|
template <typename T> const asio::error_code
|
||||||
*
|
error_base<T>::access_denied = ASIO_SOCKET_ERROR(EACCES);
|
||||||
* @param os The output stream to which the string will be written.
|
|
||||||
*
|
template <typename T> const asio::error_code
|
||||||
* @param e The error to be written.
|
error_base<T>::address_family_not_supported = ASIO_SOCKET_ERROR(
|
||||||
*
|
EAFNOSUPPORT);
|
||||||
* @return The output stream.
|
|
||||||
*
|
template <typename T> const asio::error_code
|
||||||
* @relates asio::error
|
error_base<T>::address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE);
|
||||||
*/
|
|
||||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
template <typename T> const asio::error_code
|
||||||
std::ostream& operator<<(std::ostream& os, const error& e)
|
error_base<T>::already_connected = ASIO_SOCKET_ERROR(EISCONN);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::already_open = ASIO_MISC_ERROR(1);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::already_started = ASIO_SOCKET_ERROR(EALREADY);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::connection_reset = ASIO_SOCKET_ERROR(ECONNRESET);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::bad_descriptor = ASIO_SOCKET_ERROR(EBADF);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::eof = ASIO_MISC_ERROR(2);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::fault = ASIO_SOCKET_ERROR(EFAULT);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::in_progress = ASIO_SOCKET_ERROR(EINPROGRESS);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::interrupted = ASIO_SOCKET_ERROR(EINTR);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::invalid_argument = ASIO_SOCKET_ERROR(EINVAL);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::message_size = ASIO_SOCKET_ERROR(EMSGSIZE);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::network_down = ASIO_SOCKET_ERROR(ENETDOWN);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::network_reset = ASIO_SOCKET_ERROR(ENETRESET);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::no_descriptors = ASIO_SOCKET_ERROR(EMFILE);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::no_data = ASIO_NETDB_ERROR(NO_DATA);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::no_memory = ASIO_WIN_OR_POSIX(
|
||||||
|
ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY),
|
||||||
|
ASIO_NATIVE_ERROR(ENOMEM));
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::no_permission = ASIO_WIN_OR_POSIX(
|
||||||
|
ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED),
|
||||||
|
ASIO_NATIVE_ERROR(EPERM));
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::not_connected = ASIO_SOCKET_ERROR(ENOTCONN);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::not_found = ASIO_MISC_ERROR(3);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::not_socket = ASIO_SOCKET_ERROR(ENOTSOCK);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::operation_aborted = ASIO_WIN_OR_POSIX(
|
||||||
|
ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED),
|
||||||
|
ASIO_NATIVE_ERROR(ECANCELED));
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::service_not_found = ASIO_WIN_OR_POSIX(
|
||||||
|
ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND),
|
||||||
|
ASIO_GETADDRINFO_ERROR(EAI_SERVICE));
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::socket_type_not_supported = ASIO_WIN_OR_POSIX(
|
||||||
|
ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT),
|
||||||
|
ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE));
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT);
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::try_again = ASIO_WIN_OR_POSIX(
|
||||||
|
ASIO_NATIVE_ERROR(ERROR_RETRY),
|
||||||
|
ASIO_NATIVE_ERROR(EAGAIN));
|
||||||
|
|
||||||
|
template <typename T> const asio::error_code
|
||||||
|
error_base<T>::would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK);
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Contains error constants.
|
||||||
|
class error : public asio::detail::error_base<error>
|
||||||
{
|
{
|
||||||
os << e.what();
|
private:
|
||||||
return os;
|
error();
|
||||||
}
|
};
|
||||||
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
|
||||||
template <typename Ostream>
|
|
||||||
Ostream& operator<<(Ostream& os, const error& e)
|
|
||||||
{
|
|
||||||
os << e.what();
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
||||||
|
#undef ASIO_NATIVE_ERROR
|
||||||
#undef ASIO_SOCKET_ERROR
|
#undef ASIO_SOCKET_ERROR
|
||||||
#undef ASIO_NETDB_ERROR
|
#undef ASIO_NETDB_ERROR
|
||||||
#undef ASIO_GETADDRINFO_ERROR
|
#undef ASIO_GETADDRINFO_ERROR
|
||||||
#undef ASIO_OS_ERROR
|
#undef ASIO_MISC_ERROR
|
||||||
|
#undef ASIO_WIN_OR_POSIX
|
||||||
|
|
||||||
|
#include "asio/impl/error_code.ipp"
|
||||||
|
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
|||||||
139
libtorrent/include/libtorrent/asio/error_code.hpp
Normal file
139
libtorrent/include/libtorrent/asio/error_code.hpp
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
//
|
||||||
|
// error_code.hpp
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASIO_ERROR_CODE_HPP
|
||||||
|
#define ASIO_ERROR_CODE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined
|
||||||
|
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
|
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win
|
||||||
|
#else
|
||||||
|
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
/// Available error code categories.
|
||||||
|
enum error_category
|
||||||
|
{
|
||||||
|
/// Native error codes.
|
||||||
|
native_ecat = ASIO_WIN_OR_POSIX(0, 0),
|
||||||
|
|
||||||
|
/// Error codes from NetDB functions.
|
||||||
|
netdb_ecat = ASIO_WIN_OR_POSIX(native_ecat, 1),
|
||||||
|
|
||||||
|
/// Error codes from getaddrinfo.
|
||||||
|
addrinfo_ecat = ASIO_WIN_OR_POSIX(native_ecat, 2),
|
||||||
|
|
||||||
|
/// Miscellaneous error codes.
|
||||||
|
misc_ecat = ASIO_WIN_OR_POSIX(3, 3),
|
||||||
|
|
||||||
|
/// SSL error codes.
|
||||||
|
ssl_ecat = ASIO_WIN_OR_POSIX(4, 4)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Class to represent an error code value.
|
||||||
|
class error_code
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The underlying representation of an error code.
|
||||||
|
typedef int value_type;
|
||||||
|
|
||||||
|
/// Default constructor.
|
||||||
|
error_code()
|
||||||
|
: value_(0),
|
||||||
|
category_(native_ecat)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct with specific error code and category.
|
||||||
|
error_code(value_type v, error_category c)
|
||||||
|
: value_(v),
|
||||||
|
category_(c)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the error value.
|
||||||
|
value_type value() const
|
||||||
|
{
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the error category.
|
||||||
|
error_category category() const
|
||||||
|
{
|
||||||
|
return category_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the message associated with the error.
|
||||||
|
std::string message() const;
|
||||||
|
|
||||||
|
struct unspecified_bool_type_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef unspecified_bool_type_t* unspecified_bool_type;
|
||||||
|
|
||||||
|
/// Operator returns non-null if there is a non-success error code.
|
||||||
|
operator unspecified_bool_type() const
|
||||||
|
{
|
||||||
|
if (value_ == 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return reinterpret_cast<unspecified_bool_type>(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Operator to test if the error represents success.
|
||||||
|
bool operator!() const
|
||||||
|
{
|
||||||
|
return value_ == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Equality operator to compare two error objects.
|
||||||
|
friend bool operator==(const error_code& e1, const error_code& e2)
|
||||||
|
{
|
||||||
|
return e1.value_ == e2.value_ && e1.category_ == e2.category_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inequality operator to compare two error objects.
|
||||||
|
friend bool operator!=(const error_code& e1, const error_code& e2)
|
||||||
|
{
|
||||||
|
return e1.value_ != e2.value_ || e1.category_ != e2.category_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The value associated with the error code.
|
||||||
|
value_type value_;
|
||||||
|
|
||||||
|
// The category associated with the error code.
|
||||||
|
error_category category_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
|
||||||
|
#undef ASIO_WIN_OR_POSIX
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
|
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#endif // ASIO_ERROR_CODE_HPP
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// handler_alloc_hook.hpp
|
// handler_alloc_hook.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -42,7 +42,7 @@ namespace asio {
|
|||||||
* before the upcall to the handler is performed. This allows the same memory to
|
* before the upcall to the handler is performed. This allows the same memory to
|
||||||
* be reused for a subsequent asynchronous operation initiated by the handler.
|
* be reused for a subsequent asynchronous operation initiated by the handler.
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* class my_handler;
|
* class my_handler;
|
||||||
*
|
*
|
||||||
@ -78,7 +78,7 @@ inline void* asio_handler_allocate(std::size_t size, ...)
|
|||||||
inline void asio_handler_deallocate(void* pointer, std::size_t size, ...)
|
inline void asio_handler_deallocate(void* pointer, std::size_t size, ...)
|
||||||
{
|
{
|
||||||
(void)(size);
|
(void)(size);
|
||||||
return ::operator delete(pointer);
|
::operator delete(pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// handler_invoke_hook.hpp
|
// handler_invoke_hook.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2007 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 http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -45,7 +45,7 @@ namespace asio {
|
|||||||
* function();
|
* function();
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* @par Example:
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* class my_handler;
|
* class my_handler;
|
||||||
*
|
*
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user