Work in progress commit of template-based socket classes.

This commit is contained in:
chris 2003-09-16 03:04:26 +00:00
parent 71e19d2881
commit 0fb12226fc
33 changed files with 798 additions and 672 deletions

View File

@ -11,8 +11,6 @@ ___lib_libasio_a_SOURCES = \
asio/demuxer.cpp \
asio/demuxer_service.cpp \
asio/demuxer_task.cpp \
asio/dgram_socket.cpp \
asio/dgram_socket_service.cpp \
asio/generic_address.cpp \
asio/inet_address_v4.cpp \
asio/service.cpp \
@ -20,17 +18,13 @@ ___lib_libasio_a_SOURCES = \
asio/service_provider_factory.cpp \
asio/service_unavailable.cpp \
asio/socket_acceptor.cpp \
asio/socket_acceptor_service.cpp \
asio/socket_address.cpp \
asio/socket_connector.cpp \
asio/socket_connector_service.cpp \
asio/socket_error.cpp \
asio/stream_socket.cpp \
asio/stream_socket_service.cpp \
asio/timer_queue.cpp \
asio/timer_queue_service.cpp \
asio/detail/default_service_provider_factory.cpp \
asio/detail/demuxer_thread_pool.cpp \
asio/detail/dgram_socket_service.cpp \
asio/detail/selector.cpp \
asio/detail/select_interrupter.cpp \
asio/detail/select_op.cpp \
@ -38,12 +32,18 @@ ___lib_libasio_a_SOURCES = \
asio/detail/select_provider.cpp \
asio/detail/service_registry.cpp \
asio/detail/shared_thread_demuxer_provider.cpp \
asio/detail/socket_acceptor_service.cpp \
asio/detail/socket_connector_impl.cpp \
asio/detail/socket_connector_service.cpp \
asio/detail/stream_socket_service.cpp \
asio/detail/timer_queue_provider.cpp \
asio/detail/timer_queue_service.cpp \
asio/detail/win_iocp_provider.cpp
nobase_include_HEADERS = \
asio.hpp \
asio/basic_dgram_socket.hpp \
asio/basic_timer_queue.hpp \
asio/buffered_recv_stream.hpp \
asio/buffered_send_stream.hpp \
asio/buffered_stream.hpp \
@ -54,7 +54,6 @@ nobase_include_HEADERS = \
asio/demuxer_service.hpp \
asio/demuxer_task.hpp \
asio/dgram_socket.hpp \
asio/dgram_socket_service.hpp \
asio/generic_address.hpp \
asio/inet_address_v4.hpp \
asio/service.hpp \
@ -63,18 +62,19 @@ nobase_include_HEADERS = \
asio/service_type_id.hpp \
asio/service_unavailable.hpp \
asio/socket_acceptor.hpp \
asio/socket_acceptor_service.hpp \
asio/socket_address.hpp \
asio/socket_connector.hpp \
asio/socket_connector_service.hpp \
asio/socket_error.hpp \
asio/stream_socket.hpp \
asio/stream_socket_service.hpp \
asio/timer_queue.hpp \
asio/timer_queue_service.hpp \
asio/detail/dgram_socket_service.hpp \
asio/detail/pop_options.hpp \
asio/detail/push_options.hpp \
asio/detail/socket_types.hpp
asio/detail/socket_acceptor_service.hpp \
asio/detail/socket_connector_service.hpp \
asio/detail/stream_socket_service.hpp \
asio/detail/socket_types.hpp \
asio/detail/timer_queue_service.hpp
noinst_HEADERS = \
asio/detail/default_service_provider_factory.hpp \

View File

@ -15,6 +15,8 @@
#ifndef ASIO_HPP
#define ASIO_HPP
#include "asio/basic_dgram_socket.hpp"
#include "asio/basic_timer_queue.hpp"
#include "asio/buffered_recv_stream.hpp"
#include "asio/buffered_send_stream.hpp"
#include "asio/buffered_stream.hpp"
@ -25,7 +27,6 @@
#include "asio/demuxer_service.hpp"
#include "asio/demuxer_task.hpp"
#include "asio/dgram_socket.hpp"
#include "asio/dgram_socket_service.hpp"
#include "asio/generic_address.hpp"
#include "asio/inet_address_v4.hpp"
#include "asio/service.hpp"
@ -34,12 +35,9 @@
#include "asio/service_type_id.hpp"
#include "asio/service_unavailable.hpp"
#include "asio/socket_acceptor.hpp"
#include "asio/socket_acceptor_service.hpp"
#include "asio/socket_address.hpp"
#include "asio/socket_connector.hpp"
#include "asio/socket_connector_service.hpp"
#include "asio/socket_error.hpp"
#include "asio/timer_queue.hpp"
#include "asio/timer_queue_service.hpp"
#endif // ASIO_HPP

View File

@ -0,0 +1,145 @@
//
// basic_dgram_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_BASIC_DGRAM_SOCKET_HPP
#define ASIO_BASIC_DGRAM_SOCKET_HPP
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/noncopyable.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/completion_context.hpp"
#include "asio/demuxer.hpp"
namespace asio {
class socket_address;
class socket_error;
/// The basic_dgram_socket class template provides asynchronous and blocking
/// datagram-oriented socket functionality. Most applications will simply use
/// the dgram_socket typedef.
template <typename Service>
class basic_dgram_socket
: private boost::noncopyable
{
public:
/// The native implementation type of the dgram socket.
typedef typename Service::impl_type impl_type;
/// Construct a dgram_socket without opening it. The socket needs to be
/// opened before data can be sent or received on it.
explicit basic_dgram_socket(demuxer& d)
: service_(dynamic_cast<Service&>(d.get_service(Service::id)))
{
service_.nullify(impl_);
}
/// Construct a dgram_socket opened on the given address.
basic_dgram_socket(demuxer& d, const socket_address& address)
: service_(dynamic_cast<Service&>(d.get_service(Service::id)))
{
service_.create(impl_, address);
}
/// Destructor.
~basic_dgram_socket()
{
service_.destroy(impl_);
}
/// Open the socket on the given address.
void open(const socket_address& address)
{
service_.create(impl_, address);
}
/// Close the socket.
void close()
{
service_.destroy(impl_);
}
/// Get the underlying implementation in the native type.
impl_type impl() const
{
return impl_;
}
/// Attach an existing implementation to the dgram socket. The dgram_socket
/// object takes ownership of the implementation.
void attach_impl(impl_type impl)
{
service_.attach(impl_, impl);
}
/// Send a datagram to the specified address. Returns the number of bytes
/// sent. Throws a socket_error exception on failure.
size_t sendto(const void* data, size_t length,
const socket_address& destination)
{
return service_.sendto(impl_, data, length, destination);
}
/// The handler when a sendto operation is completed. The first argument is
/// the error code, the second is the number of bytes sent.
typedef typename Service::sendto_handler sendto_handler;
/// Start an asynchronous send. The data being sent must be valid for the
/// lifetime of the asynchronous operation.
void async_sendto(const void* data, size_t length,
const socket_address& destination, const sendto_handler& handler,
completion_context& context = completion_context::null())
{
service_.async_sendto(impl_, data, length, destination, handler, context);
}
/// Receive a datagram with the address of the sender. Returns the number of
/// bytes received. Throws a socket_error exception on failure.
size_t recvfrom(void* data, size_t max_length,
socket_address& sender_address)
{
return service_.recvfrom(impl_, data, max_length, sender_address);
}
/// The handler when a recvfrom operation is completed. The first argument is
/// the error code, the second is the number of bytes received.
typedef typename Service::recvfrom_handler recvfrom_handler;
/// Start an asynchronous receive. The buffer for the data being received and
/// the sender_address obejct must both be valid for the lifetime of the
/// asynchronous operation.
void async_recvfrom(void* data, size_t max_length,
socket_address& sender_address, const recvfrom_handler& handler,
completion_context& context = completion_context::null())
{
service_.async_recvfrom(impl_, data, max_length, sender_address, handler,
context);
}
private:
/// The backend service implementation.
Service& service_;
/// The underlying native implementation.
impl_type impl_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_BASIC_DGRAM_SOCKET_HPP

View File

@ -0,0 +1,82 @@
//
// basic_timer_queue.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_BASIC_TIMER_QUEUE_HPP
#define ASIO_BASIC_TIMER_QUEUE_HPP
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread/xtime.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/completion_context.hpp"
#include "asio/demuxer.hpp"
namespace asio {
/// The basic_timer_queue class template provides asynchronous timer
/// functionality. Most applications will simply use the timer_queue typedef.
template <typename Service>
class basic_timer_queue
: private boost::noncopyable
{
public:
/// Constructor.
explicit basic_timer_queue(demuxer& d)
: service_(dynamic_cast<Service&>(d.get_service(Service::id)))
{
}
/// The handler for when a timer expires.
typedef typename Service::timer_handler timer_handler;
/// Schedule a timer to fire once at the given start_time. The id of the new
/// timer is returned so that it may be cancelled.
int schedule_timer(const boost::xtime& start_time,
const timer_handler& handler,
completion_context& context = completion_context::null())
{
return service_.schedule_timer(this, start_time, handler, context);
}
/// Schedule a timer to fire first after at the start time, and then every
/// interval until the timer is cancelled. The id of the new timer is
/// returned so that it may be cancelled.
int schedule_timer(const boost::xtime& start_time,
const boost::xtime& interval, const timer_handler& handler,
completion_context& context = completion_context::null())
{
return service_.schedule_timer(this, start_time, interval, handler,
context);
}
/// Cancel the timer with the given id.
void cancel_timer(int timer_id)
{
service_.cancel_timer(this, timer_id);
}
private:
/// The backend service implementation.
Service& service_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_BASIC_TIMER_QUEUE_HPP

View File

@ -0,0 +1,138 @@
//
// dgram_socket_service.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#include "asio/detail/dgram_socket_service.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/socket_address.hpp"
#include "asio/socket_error.hpp"
#include "asio/detail/socket_holder.hpp"
#include "asio/detail/socket_ops.hpp"
namespace asio {
namespace detail {
const service_type_id dgram_socket_service::id;
void
dgram_socket_service::
nullify(
impl_type& impl)
{
impl = invalid_socket;
}
void
dgram_socket_service::
create(
impl_type& impl,
const socket_address& address)
{
socket_holder sock(socket_ops::socket(address.family(), SOCK_DGRAM,
IPPROTO_UDP));
if (sock.get() == invalid_socket)
boost::throw_exception(socket_error(socket_ops::get_error()));
int reuse = 1;
socket_ops::setsockopt(sock.get(), SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse));
if (socket_ops::bind(sock.get(), address.native_address(),
address.native_size()) == socket_error_retval)
boost::throw_exception(socket_error(socket_ops::get_error()));
impl = sock.release();
}
void
attach(
impl_type& impl,
impl_type new_impl)
{
impl = new_impl;
}
void
dgram_socket_service::
destroy(
impl_type& impl)
{
do_dgram_socket_destroy(impl);
}
size_t
dgram_socket_service::
sendto(
impl_type& impl,
const void* data,
size_t length,
const socket_address& destination)
{
int bytes_sent = socket_ops::sendto(impl, data, length, 0,
destination.native_address(), destination.native_size());
if (bytes_sent < 0)
boost::throw_exception(socket_error(socket_ops::get_error()));
return bytes_sent;
}
void
dgram_socket_service::
async_sendto(
impl_type& impl,
const void* data,
size_t length,
const socket_address& destination,
const sendto_handler& handler,
completion_context& context)
{
do_dgram_socket_async_sendto(impl, data, length, destination, handler,
context);
}
size_t
dgram_socket_service::
recvfrom(
impl_type& impl,
void* data,
size_t max_length,
socket_address& sender_address)
{
socket_addr_len_type addr_len = sender_address.native_size();
int bytes_recvd = socket_ops::recvfrom(impl, data, max_length, 0,
sender_address.native_address(), &addr_len);
if (bytes_recvd < 0)
boost::throw_exception(socket_error(socket_ops::get_error()));
sender_address.native_size(addr_len);
return bytes_recvd;
}
void
dgram_socket_service::
async_recvfrom(
impl_type& impl,
void* data,
size_t max_length,
socket_address& sender_address,
const recvfrom_handler& handler,
completion_context& context)
{
do_dgram_socket_async_recvfrom(impl, data, max_length, sender_address,
handler, context);
}
} // namespace detail
} // namespace asio

View File

@ -0,0 +1,109 @@
//
// dgram_socket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_DETAIL_DGRAM_SOCKET_SERVICE_HPP
#define ASIO_DETAIL_DGRAM_SOCKET_SERVICE_HPP
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/function.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/completion_context.hpp"
#include "asio/service.hpp"
#include "asio/service_type_id.hpp"
#include "asio/detail/socket_types.hpp"
namespace asio { class socket_address; }
namespace asio { class socket_error; }
namespace asio {
namespace detail {
class dgram_socket_service
: public virtual service
{
public:
// The service type id.
static const service_type_id id;
/// The native type of the dgram socket. This type is dependent on the
/// underlying implementation of the socket layer.
typedef socket_type impl_type;
// Initialise a dgram socket to a null implementation.
void nullify(impl_type& impl);
// Create a new dgram socket implementation.
void create(impl_type& impl, const socket_address& address);
// Attach an existing dgram socket implementation to the service.
void attach(impl_type& impl, impl_type new_impl);
// Destroy a dgram socket implementation.
void destroy(impl_type& impl);
/// Send a datagram to the specified address. Returns the number of bytes
/// sent. Throws a socket_error exception on failure.
size_t sendto(impl_type& impl, const void* data, size_t length,
const socket_address& destination);
/// The handler when a sendto operation is completed. The first argument is
/// the error code, the second is the number of bytes sent.
typedef boost::function2<void, const socket_error&, size_t> sendto_handler;
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
void async_sendto(impl_type& impl, const void* data, size_t length,
const socket_address& destination, const sendto_handler& handler,
completion_context& context);
/// Receive a datagram with the address of the sender. Returns the number of
/// bytes received. Throws a socket_error exception on failure.
size_t recvfrom(impl_type& impl, void* data, size_t max_length,
socket_address& sender_address);
/// The handler when a recvfrom operation is completed. The first argument is
/// the error code, the second is the number of bytes received.
typedef boost::function2<void, const socket_error&, size_t> recvfrom_handler;
// Start an asynchronous receive. The buffer for the data being received and
// the sender_address obejct must both be valid for the lifetime of the
// asynchronous operation.
void async_recvfrom(impl_type& impl, void* data, size_t max_length,
socket_address& sender_address, const recvfrom_handler& handler,
completion_context& context);
private:
// Destroy a dgram socket implementation.
virtual void do_dgram_socket_destroy(impl_type& impl) = 0;
// Start an asynchronous sendto.
virtual void do_dgram_socket_async_sendto(impl_type& impl, const void* data,
size_t length, const socket_address& destination,
const sendto_handler& handler, completion_context& context) = 0;
// Start an asynchronous recvfrom.
virtual void do_dgram_socket_async_recvfrom(impl_type& impl, void* data,
size_t max_length, socket_address& sender_address,
const recvfrom_handler& handler, completion_context& context) = 0;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_DGRAM_SOCKET_SERVICE_HPP

View File

@ -57,19 +57,15 @@ do_get_service(
void
select_provider::
register_dgram_socket(
dgram_socket&)
do_dgram_socket_destroy(
dgram_socket_service::impl_type& impl)
{
// Registration is not required with the select_provider since each operation
// is handled individually.
}
void
select_provider::
deregister_dgram_socket(
dgram_socket& socket)
{
selector_.close_descriptor(socket.native_handle());
if (impl != invalid_socket)
{
selector_.close_descriptor(impl);
socket_ops::close(impl);
impl = invalid_socket;
}
}
namespace
@ -80,7 +76,7 @@ namespace
const void* data_;
size_t length_;
generic_address destination_;
dgram_socket::sendto_handler handler_;
dgram_socket_service::sendto_handler handler_;
completion_context* context_;
sendto_op(int d) : select_op(d) {}
@ -104,7 +100,7 @@ namespace
delete this;
}
static void do_upcall(const dgram_socket::sendto_handler& handler,
static void do_upcall(const dgram_socket_service::sendto_handler& handler,
const socket_error& error, size_t bytes_transferred)
{
handler(error, bytes_transferred);
@ -114,15 +110,15 @@ namespace
void
select_provider::
async_dgram_socket_sendto(
dgram_socket& socket,
do_dgram_socket_async_sendto(
dgram_socket_service::impl_type& impl,
const void* data,
size_t length,
const socket_address& destination,
const sendto_handler& handler,
completion_context& context)
{
sendto_op* op = new sendto_op(socket.native_handle());
sendto_op* op = new sendto_op(impl);
op->demuxer_ = &demuxer_;
op->data_ = data;
op->length_ = length;
@ -143,7 +139,7 @@ namespace
void* data_;
size_t max_length_;
socket_address* sender_address_;
dgram_socket::recvfrom_handler handler_;
dgram_socket_service::recvfrom_handler handler_;
completion_context* context_;
recvfrom_op(int d) : select_op(d) {}
@ -169,7 +165,8 @@ namespace
delete this;
}
static void do_upcall(const dgram_socket::recvfrom_handler& handler,
static void do_upcall(
const dgram_socket_service::recvfrom_handler& handler,
const socket_error& error, size_t bytes_transferred)
{
handler(error, bytes_transferred);
@ -179,15 +176,15 @@ namespace
void
select_provider::
async_dgram_socket_recvfrom(
dgram_socket& socket,
do_dgram_socket_async_recvfrom(
dgram_socket_service::impl_type& impl,
void* data,
size_t max_length,
socket_address& sender_address,
const recvfrom_handler& handler,
completion_context& context)
{
recvfrom_op* op = new recvfrom_op(socket.native_handle());
recvfrom_op* op = new recvfrom_op(impl);
op->demuxer_ = &demuxer_;
op->data_ = data;
op->max_length_ = max_length;
@ -265,7 +262,7 @@ async_socket_accept(
const accept_handler& handler,
completion_context& context)
{
if (peer_socket.native_handle() != detail::invalid_socket)
if (peer_socket.native_handle() != invalid_socket)
{
socket_error error(socket_error::already_connected);
demuxer_.operation_immediate(
@ -338,7 +335,7 @@ async_socket_accept(
const accept_handler& handler,
completion_context& context)
{
if (peer_socket.native_handle() != detail::invalid_socket)
if (peer_socket.native_handle() != invalid_socket)
{
socket_error error(socket_error::already_connected);
demuxer_.operation_immediate(
@ -483,7 +480,7 @@ async_socket_connect(
const connect_handler& handler,
completion_context& context)
{
if (peer_socket.native_handle() != detail::invalid_socket)
if (peer_socket.native_handle() != invalid_socket)
{
socket_error error(socket_error::already_connected);
demuxer_.operation_immediate(

View File

@ -17,12 +17,12 @@
#include "asio/detail/push_options.hpp"
#include "asio/dgram_socket_service.hpp"
#include "asio/service_provider.hpp"
#include "asio/socket_acceptor_service.hpp"
#include "asio/socket_connector_service.hpp"
#include "asio/stream_socket_service.hpp"
#include "asio/detail/dgram_socket_service.hpp"
#include "asio/detail/selector.hpp"
#include "asio/detail/socket_acceptor_service.hpp"
#include "asio/detail/socket_connector_service.hpp"
#include "asio/detail/stream_socket_service.hpp"
namespace asio {
namespace detail {
@ -44,26 +44,20 @@ public:
// Return the service interface corresponding to the given type.
virtual service* do_get_service(const service_type_id& service_type);
// Register a new dgram socket with the service. This should be called only
// after the socket has been opened.
virtual void register_dgram_socket(dgram_socket& socket);
// Destroy a dgram socket implementation.
virtual void do_dgram_socket_destroy(dgram_socket_service::impl_type& impl);
// Remove a dgram socket registration from the service. This should be
// called immediately before the socket is closed.
virtual void deregister_dgram_socket(dgram_socket& socket);
// Start an asynchronous sendto.
virtual void do_dgram_socket_async_sendto(
dgram_socket_service::impl_type& impl, const void* data, size_t length,
const socket_address& destination, const sendto_handler& handler,
completion_context& context);
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
virtual void async_dgram_socket_sendto(dgram_socket& socket,
const void* data, size_t length, const socket_address& destination,
const sendto_handler& handler, completion_context& context);
// Start an asynchronous receive. The buffer for the data being received and
// the sender_address obejct must both be valid for the lifetime of the
// asynchronous operation.
virtual void async_dgram_socket_recvfrom(dgram_socket& socket, void* data,
size_t max_length, socket_address& sender_address,
const recvfrom_handler& handler, completion_context& context);
// Start an asynchronous recvfrom.
virtual void do_dgram_socket_async_recvfrom(
dgram_socket_service::impl_type& impl, void* data, size_t max_length,
socket_address& sender_address, const recvfrom_handler& handler,
completion_context& context);
// Register a new socket_acceptor with the service. This should be called
// only after the socket acceptor has been opened.

View File

@ -12,9 +12,10 @@
// no claim as to its suitability for any purpose.
//
#include "asio/socket_acceptor_service.hpp"
#include "asio/detail/socket_acceptor_service.hpp"
namespace asio {
namespace detail {
const service_type_id socket_acceptor_service::id;
@ -28,4 +29,5 @@ associate_accepted_stream_socket(
acceptor.associate(peer_socket, handle);
}
} // namespace detail
} // namespace asio

View File

@ -12,8 +12,8 @@
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_SOCKET_ACCEPTOR_SERVICE_HPP
#define ASIO_SOCKET_ACCEPTOR_SERVICE_HPP
#ifndef ASIO_DETAIL_SOCKET_ACCEPTOR_SERVICE_HPP
#define ASIO_DETAIL_SOCKET_ACCEPTOR_SERVICE_HPP
#include "asio/detail/push_options.hpp"
@ -23,49 +23,48 @@
#include "asio/stream_socket.hpp"
namespace asio {
namespace detail {
/// The socket_acceptor_service class is a base class for service
/// implementations that provide the functionality required by the
/// socket_acceptor class.
class socket_acceptor_service
: public virtual service
{
public:
typedef socket_acceptor::accept_handler accept_handler;
/// The service type id.
// The service type id.
static const service_type_id id;
/// Register a new socket_acceptor with the service. This should be called
/// only after the socket acceptor has been opened.
// Register a new socket_acceptor with the service. This should be called
// only after the socket acceptor has been opened.
virtual void register_socket_acceptor(socket_acceptor& acceptor) = 0;
/// Remove a socket acceptor registration from the service. This should be
/// called immediately before the socket acceptor is closed.
// Remove a socket acceptor registration from the service. This should be
// called immediately before the socket acceptor is closed.
virtual void deregister_socket_acceptor(socket_acceptor& acceptor) = 0;
/// Start an asynchronous accept on the given socket. The peer_socket object
/// must be valid until the accept's completion handler is invoked.
// Start an asynchronous accept on the given socket. The peer_socket object
// must be valid until the accept's completion handler is invoked.
virtual void async_socket_accept(socket_acceptor& acceptor,
stream_socket& peer_socket, const accept_handler& handler,
completion_context& context) = 0;
/// Start an asynchronous accept on the given socket. The peer_socket and
/// peer_address objects must be valid until the accept's completion handler
/// is invoked.
// Start an asynchronous accept on the given socket. The peer_socket and
// peer_address objects must be valid until the accept's completion handler
// is invoked.
virtual void async_socket_accept(socket_acceptor& acceptor,
stream_socket& peer_socket, socket_address& peer_address,
const accept_handler& handler, completion_context& context) = 0;
protected:
/// Associate the given stream_socket with the underlying native handle that
/// was obtained by the acceptor.
// Associate the given stream_socket with the underlying native handle that
// was obtained by the acceptor.
static void associate_accepted_stream_socket(socket_acceptor& acceptor,
stream_socket& peer_socket, stream_socket::native_type handle);
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_SOCKET_ACCEPTOR_SERVICE_HPP
#endif // ASIO_DETAIL_SOCKET_ACCEPTOR_SERVICE_HPP

View File

@ -12,9 +12,10 @@
// no claim as to its suitability for any purpose.
//
#include "asio/socket_connector_service.hpp"
#include "asio/detail/socket_connector_service.hpp"
namespace asio {
namespace detail {
const service_type_id socket_connector_service::id;
@ -28,4 +29,5 @@ associate_connected_stream_socket(
connector.associate(peer_socket, handle);
}
} // namespace detail
} // namespace asio

View File

@ -0,0 +1,88 @@
//
// socket_connector_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_DETAIL_SOCKET_CONNECTOR_SERVICE_HPP
#define ASIO_DETAIL_SOCKET_CONNECTOR_SERVICE_HPP
#include "asio/detail/push_options.hpp"
#include "asio/service.hpp"
#include "asio/service_type_id.hpp"
namespace asio {
namespace detail {
class socket_connector_impl;
class socket_connector_service
: public virtual service
{
public:
typedef socket_connector::connect_handler connect_handler;
// The service type id.
static const service_type_id id;
/// The native type of the socket connector. This type is dependent on the
/// underlying implementation of the socket layer.
typedef socket_connector_impl* impl_type;
// Initialise a socket connector to a null implementation.
void nullify(impl_type& impl);
// Create a new socket connector implementation.
void create(impl_type& impl);
// Destroy a socket connector implementation.
void destroy(impl_type& impl);
// Connect the given socket to the peer at the specified address. Throws a
// socket_error exception on failure.
void connect(socket_type& peer_socket, const socket_address& peer_address);
// Start an asynchronous connect. The peer_socket object must be valid until
// the connect's completion handler is invoked.
void async_connect(peer_socket& peer_socket,
const socket_address& peer_address, const connect_handler& handler,
completion_context& context = completion_context::null());
// Register a new socket_connector with the service. This should be called
// only after the socket connector has been opened.
virtual void register_socket_connector(socket_connector& connector) = 0;
// Remove a socket connector registration from the service. This should be
// called immediately before the socket connector is closed.
virtual void deregister_socket_connector(socket_connector& connector) = 0;
// Start an asynchronous connect on the given socket. The peer_socket object
// be valid until the connect's completion handler is invoked.
virtual void async_socket_connect(socket_connector& connector,
stream_socket& peer_socket, const socket_address& peer_address,
const connect_handler& handler, completion_context& context) = 0;
protected:
// Associate the given stream_socket with the underlying native handle that
// was obtained by the connector.
static void associate_connected_stream_socket(socket_connector& connector,
stream_socket& peer_socket, stream_socket::native_type handle);
private:
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_SOCKET_CONNECTOR_SERVICE_HPP

View File

@ -12,10 +12,12 @@
// no claim as to its suitability for any purpose.
//
#include "asio/stream_socket_service.hpp"
#include "asio/detail/stream_socket_service.hpp"
namespace asio {
namespace detail {
const service_type_id stream_socket_service::id;
} // namespace detail
} // namespace asio

View File

@ -12,8 +12,8 @@
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_STREAM_SOCKET_SERVICE_HPP
#define ASIO_STREAM_SOCKET_SERVICE_HPP
#ifndef ASIO_DETAIL_STREAM_SOCKET_SERVICE_HPP
#define ASIO_DETAIL_STREAM_SOCKET_SERVICE_HPP
#include "asio/detail/push_options.hpp"
@ -22,9 +22,8 @@
#include "asio/stream_socket.hpp"
namespace asio {
namespace detail {
/// The stream_socket_service class is a base class for service implementations
/// that provide the functionality required by the stream_socket class.
class stream_socket_service
: public virtual service
{
@ -34,48 +33,49 @@ public:
typedef stream_socket::recv_handler recv_handler;
typedef stream_socket::recv_n_handler recv_n_handler;
/// The service type id.
// The service type id.
static const service_type_id id;
/// Register a new stream socket with the service. This should be called only
/// after the socket has been opened, i.e. after an accept or just before a
/// connect.
// Register a new stream socket with the service. This should be called only
// after the socket has been opened, i.e. after an accept or just before a
// connect.
virtual void register_stream_socket(stream_socket& socket) = 0;
/// Remove a stream socket registration from the service. This should be
/// called immediately before the socket is closed.
// Remove a stream socket registration from the service. This should be
// called immediately before the socket is closed.
virtual void deregister_stream_socket(stream_socket& socket) = 0;
/// Start an asynchronous send. The data being sent must be valid for the
/// lifetime of the asynchronous operation.
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
virtual void async_stream_socket_send(stream_socket& socket,
const void* data, size_t length, const send_handler& handler,
completion_context& context) = 0;
/// Start an asynchronous send that will not return until all of the data has
/// been sent or an error occurs. The data being sent must be valid for the
/// lifetime of the asynchronous operation.
// Start an asynchronous send that will not return until all of the data has
// been sent or an error occurs. The data being sent must be valid for the
// lifetime of the asynchronous operation.
virtual void async_stream_socket_send_n(stream_socket& socket,
const void* data, size_t length, const send_n_handler& handler,
completion_context& context) = 0;
/// Start an asynchronous receive. The buffer for the data being received
/// must be valid for the lifetime of the asynchronous operation.
// Start an asynchronous receive. The buffer for the data being received
// must be valid for the lifetime of the asynchronous operation.
virtual void async_stream_socket_recv(stream_socket& socket, void* data,
size_t max_length, const recv_handler& handler,
completion_context& context) = 0;
/// Start an asynchronous receive that will not return until the specified
/// number of bytes has been received or an error occurs. The buffer for the
/// data being received must be valid for the lifetime of the asynchronous
/// operation.
// Start an asynchronous receive that will not return until the specified
// number of bytes has been received or an error occurs. The buffer for the
// data being received must be valid for the lifetime of the asynchronous
// operation.
virtual void async_stream_socket_recv_n(stream_socket& socket, void* data,
size_t length, const recv_n_handler& handler,
completion_context& context) = 0;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_STREAM_SOCKET_SERVICE_HPP
#endif // ASIO_DETAIL_STREAM_SOCKET_SERVICE_HPP

View File

@ -18,10 +18,6 @@
#include <boost/bind.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/completion_context.hpp"
#include "asio/demuxer.hpp"
#include "asio/service_unavailable.hpp"
namespace asio {
namespace detail {
@ -64,8 +60,8 @@ do_get_service(
int
timer_queue_provider::
schedule_timer(
timer_queue& queue,
do_schedule_timer(
void* owner,
const boost::xtime& start_time,
const boost::xtime& interval,
const timer_handler& handler,
@ -77,7 +73,7 @@ schedule_timer(
new_event.handler = handler;
new_event.interval = interval;
new_event.context = &context;
new_event.owner = &queue;
new_event.owner = owner;
new_event.id = next_timer_id_++;
id_to_timer_.insert(std::make_pair(new_event.id,
timer_queue_.insert(std::make_pair(start_time, new_event))));
@ -98,14 +94,14 @@ namespace
void
timer_queue_provider::
cancel_timer(
timer_queue& queue,
do_cancel_timer(
void* owner,
int timer_id)
{
boost::mutex::scoped_lock lock(mutex_);
id_to_timer_map::iterator iter = id_to_timer_.find(timer_id);
if (iter != id_to_timer_.end() && iter->second->second.owner == &queue)
if (iter != id_to_timer_.end() && iter->second->second.owner == owner)
{
timer_queue_.erase(iter->second);
id_to_timer_.erase(iter);

View File

@ -23,9 +23,10 @@
#include <boost/scoped_ptr.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/demuxer.hpp"
#include "asio/completion_context.hpp"
#include "asio/service_provider.hpp"
#include "asio/timer_queue_service.hpp"
#include "asio/detail/timer_queue_service.hpp"
namespace asio {
namespace detail {
@ -41,6 +42,7 @@ public:
// Destructor.
virtual ~timer_queue_provider();
private:
// Return the service interface corresponding to the given type.
virtual service* do_get_service(const service_type_id& service_type);
@ -48,18 +50,16 @@ public:
// interval until the timer is cancelled. A zero interval means that the
// timer will fire once only. The id of the new timer is returned so that it
// may be cancelled.
virtual int schedule_timer(timer_queue& queue,
virtual int do_schedule_timer(void* owner,
const boost::xtime& start_time, const boost::xtime& interval,
const timer_handler& handler, completion_context& context);
// Cancel the timer with the given id.
virtual void cancel_timer(timer_queue& queue, int timer_id);
virtual void do_cancel_timer(void* owner, int timer_id);
private:
// Loop for expiring timers until it is time to shut down.
void expire_timers();
private:
// The demuxer that owns this provider.
demuxer& demuxer_;
@ -90,7 +90,7 @@ private:
boost::function0<void> handler;
boost::xtime interval;
completion_context* context;
timer_queue* owner;
void* owner;
int id;
};

View File

@ -1,6 +1,6 @@
//
// timer_queue.cpp
// ~~~~~~~~~~~~~~~
// timer_queue_service.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
@ -12,28 +12,17 @@
// no claim as to its suitability for any purpose.
//
#include "asio/timer_queue.hpp"
#include "asio/timer_queue_service.hpp"
#include "asio/demuxer.hpp"
#include "asio/detail/timer_queue_service.hpp"
namespace asio {
namespace detail {
timer_queue::
timer_queue(
demuxer& d)
: service_(dynamic_cast<timer_queue_service&>(
d.get_service(timer_queue_service::id)))
{
}
timer_queue::
~timer_queue()
{
}
const service_type_id timer_queue_service::id;
int
timer_queue::
timer_queue_service::
schedule_timer(
void* owner,
const boost::xtime& start_time,
const timer_handler& handler,
completion_context& context)
@ -41,28 +30,29 @@ schedule_timer(
boost::xtime interval;
interval.sec = 0;
interval.nsec = 0;
return service_.schedule_timer(*this, start_time, interval, handler,
context);
do_schedule_timer(owner, start_time, interval, handler, context);
}
int
timer_queue::
timer_queue_service::
schedule_timer(
void* owner,
const boost::xtime& start_time,
const boost::xtime& interval,
const timer_handler& handler,
completion_context& context)
{
return service_.schedule_timer(*this, start_time, interval, handler,
context);
do_schedule_timer(owner, start_time, interval, handler, context);
}
void
timer_queue::
timer_queue_service::
cancel_timer(
void* owner,
int timer_id)
{
service_.cancel_timer(*this, timer_id);
do_cancel_timer(owner, timer_id);
}
} // namespace detail
} // namespace asio

View File

@ -0,0 +1,76 @@
//
// timer_queue_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_DETAIL_TIMER_QUEUE_SERVICE_HPP
#define ASIO_DETAIL_TIMER_QUEUE_SERVICE_HPP
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/function.hpp>
#include <boost/thread/xtime.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/completion_context.hpp"
#include "asio/service.hpp"
#include "asio/service_type_id.hpp"
namespace asio {
namespace detail {
class timer_queue_service
: public virtual service
{
public:
// The service type id.
static const service_type_id id;
/// The handler for when a timer expires.
typedef boost::function0<void> timer_handler;
/// Schedule a timer to fire once at the given start_time. The id of the new
/// timer is returned so that it may be cancelled.
int schedule_timer(void* owner, const boost::xtime& start_time,
const timer_handler& handler,
completion_context& context = completion_context::null());
/// Schedule a timer to fire first after at the start time, and then every
/// interval until the timer is cancelled. The id of the new timer is
/// returned so that it may be cancelled.
int schedule_timer(void* owner, const boost::xtime& start_time,
const boost::xtime& interval, const timer_handler& handler,
completion_context& context = completion_context::null());
/// Cancel the timer with the given id.
void cancel_timer(void* owner, int timer_id);
private:
// Schedule a timer to fire first after at the start time, and then every
// interval until the timer is cancelled. A zero interval means that the
// timer will fire once only. The id of the new timer is returned so that it
// may be cancelled.
virtual int do_schedule_timer(void* owner, const boost::xtime& start_time,
const boost::xtime& interval, const timer_handler& handler,
completion_context& context) = 0;
// Cancel the timer with the given id.
virtual void do_cancel_timer(void* owner, int timer_id) = 0;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_TIMER_QUEUE_SERVICE_HPP

View File

@ -21,10 +21,10 @@
#include "asio/completion_context_locker.hpp"
#include "asio/demuxer_service.hpp"
#include "asio/dgram_socket_service.hpp"
#include "asio/service_provider.hpp"
#include "asio/stream_socket_service.hpp"
#include "asio/detail/demuxer_thread_pool.hpp"
#include "asio/detail/dgram_socket_service.hpp"
#include "asio/detail/stream_socket_service.hpp"
namespace asio {
namespace detail {

View File

@ -1,157 +0,0 @@
//
// dgram_socket.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#include "asio/dgram_socket.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/throw_exception.hpp>
#include <cassert>
#include "asio/detail/pop_options.hpp"
#include "asio/demuxer.hpp"
#include "asio/dgram_socket_service.hpp"
#include "asio/socket_address.hpp"
#include "asio/socket_error.hpp"
#include "asio/detail/socket_holder.hpp"
#include "asio/detail/socket_ops.hpp"
namespace asio {
dgram_socket::
dgram_socket(
demuxer& d)
: service_(dynamic_cast<dgram_socket_service&>(
d.get_service(dgram_socket_service::id))),
handle_(detail::invalid_socket)
{
}
dgram_socket::
dgram_socket(
demuxer& d,
const socket_address& addr)
: service_(dynamic_cast<dgram_socket_service&>(
d.get_service(dgram_socket_service::id))),
handle_(detail::invalid_socket)
{
open(addr);
}
dgram_socket::
~dgram_socket()
{
close();
}
void
dgram_socket::
open(
const socket_address& addr)
{
assert(handle_ == detail::invalid_socket);
detail::socket_holder sock(detail::socket_ops::socket(addr.family(),
SOCK_DGRAM, IPPROTO_UDP));
if (sock.get() == detail::invalid_socket)
boost::throw_exception(socket_error(detail::socket_ops::get_error()));
int reuse = 1;
detail::socket_ops::setsockopt(sock.get(), SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse));
if (detail::socket_ops::bind(sock.get(), addr.native_address(),
addr.native_size()) == detail::socket_error_retval)
boost::throw_exception(socket_error(detail::socket_ops::get_error()));
handle_ = sock.release();
service_.register_dgram_socket(*this);
}
void
dgram_socket::
close()
{
if (handle_ != detail::invalid_socket)
{
service_.deregister_dgram_socket(*this);
detail::socket_ops::close(handle_);
handle_ = detail::invalid_socket;
}
}
dgram_socket::native_type
dgram_socket::
native_handle() const
{
return handle_;
}
size_t
dgram_socket::
sendto(
const void* data,
size_t length,
const socket_address& destination)
{
int bytes_sent = detail::socket_ops::sendto(handle_, data, length, 0,
destination.native_address(), destination.native_size());
if (bytes_sent < 0)
boost::throw_exception(socket_error(detail::socket_ops::get_error()));
return bytes_sent;
}
void
dgram_socket::
async_sendto(
const void* data,
size_t length,
const socket_address& destination,
const sendto_handler& handler,
completion_context& context)
{
service_.async_dgram_socket_sendto(*this, data, length, destination, handler,
context);
}
size_t
dgram_socket::
recvfrom(
void* data,
size_t max_length,
socket_address& sender_address)
{
detail::socket_addr_len_type addr_len = sender_address.native_size();
int bytes_recvd = detail::socket_ops::recvfrom(handle_, data, max_length, 0,
sender_address.native_address(), &addr_len);
if (bytes_recvd < 0)
boost::throw_exception(socket_error(detail::socket_ops::get_error()));
sender_address.native_size(addr_len);
return bytes_recvd;
}
void
dgram_socket::
async_recvfrom(
void* data,
size_t max_length,
socket_address& sender_address,
const recvfrom_handler& handler,
completion_context& context)
{
service_.async_dgram_socket_recvfrom(*this, data, max_length, sender_address,
handler, context);
}
} // namespace asio

View File

@ -17,88 +17,13 @@
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/completion_context.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/dgram_socket.hpp"
#include "asio/detail/dgram_socket_service.hpp"
namespace asio {
class demuxer;
class dgram_socket_service;
class socket_address;
class socket_error;
/// The dgram_socket class provides asynchronous and blocking datagram-oriented
/// socket functionality.
class dgram_socket
: private boost::noncopyable
{
public:
/// The native type of the socket acceptor. This type is dependent on the
/// underlying implementation of the socket layer.
typedef detail::socket_type native_type;
/// Construct a dgram_socket without opening it. The socket needs to be
/// opened before data can be sent or received on it.
explicit dgram_socket(demuxer& d);
/// Construct a dgram_socket opened on the given address.
dgram_socket(demuxer& d, const socket_address& address);
/// Destructor.
~dgram_socket();
/// Open the socket on the given address.
void open(const socket_address& address);
/// Close the socket.
void close();
/// Get the underlying handle in the native type.
native_type native_handle() const;
/// Send a datagram to the specified address. Returns the number of bytes
/// sent. Throws a socket_error exception on failure.
size_t sendto(const void* data, size_t length,
const socket_address& destination);
/// The handler when a sendto operation is completed. The first argument is
/// the error code, the second is the number of bytes sent.
typedef boost::function2<void, const socket_error&, size_t> sendto_handler;
/// Start an asynchronous send. The data being sent must be valid for the
/// lifetime of the asynchronous operation.
void async_sendto(const void* data, size_t length,
const socket_address& destination, const sendto_handler& handler,
completion_context& context = completion_context::null());
/// Receive a datagram with the address of the sender. Returns the number of
/// bytes received. Throws a socket_error exception on failure.
size_t recvfrom(void* data, size_t max_length,
socket_address& sender_address);
/// The handler when a recvfrom operation is completed. The first argument is
/// the error code, the second is the number of bytes received.
typedef boost::function2<void, const socket_error&, size_t> recvfrom_handler;
/// Start an asynchronous receive. The buffer for the data being received and
/// the sender_address obejct must both be valid for the lifetime of the
/// asynchronous operation.
void async_recvfrom(void* data, size_t max_length,
socket_address& sender_address, const recvfrom_handler& handler,
completion_context& context = completion_context::null());
private:
/// The backend service implementation.
dgram_socket_service& service_;
/// The underlying native handle.
native_type handle_;
};
/// Typedef for the typical usage of dgram_socket.
typedef basic_dgram_socket<detail::dgram_socket_service> dgram_socket;
} // namespace asio

View File

@ -1,21 +0,0 @@
//
// dgram_socket_service.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#include "asio/dgram_socket_service.hpp"
namespace asio {
const service_type_id dgram_socket_service::id;
} // namespace asio

View File

@ -1,64 +0,0 @@
//
// dgram_socket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_DGRAM_SOCKET_SERVICE_HPP
#define ASIO_DGRAM_SOCKET_SERVICE_HPP
#include "asio/detail/push_options.hpp"
#include "asio/service.hpp"
#include "asio/service_type_id.hpp"
#include "asio/dgram_socket.hpp"
namespace asio {
/// The dgram_socket_service class is a base class for service implementations
/// that provide the functionality required by the dgram_socket class.
class dgram_socket_service
: public virtual service
{
public:
typedef dgram_socket::sendto_handler sendto_handler;
typedef dgram_socket::recvfrom_handler recvfrom_handler;
/// The service type id.
static const service_type_id id;
/// Register a new dgram socket with the service. This should be called only
/// after the socket has been opened.
virtual void register_dgram_socket(dgram_socket& socket) = 0;
/// Remove a dgram socket registration from the service. This should be
/// called immediately before the socket is closed.
virtual void deregister_dgram_socket(dgram_socket& socket) = 0;
/// Start an asynchronous send. The data being sent must be valid for the
/// lifetime of the asynchronous operation.
virtual void async_dgram_socket_sendto(dgram_socket& socket,
const void* data, size_t length, const socket_address& destination,
const sendto_handler& handler, completion_context& context) = 0;
/// Start an asynchronous receive. The buffer for the data being received and
/// the sender_address obejct must both be valid for the lifetime of the
/// asynchronous operation.
virtual void async_dgram_socket_recvfrom(dgram_socket& socket, void* data,
size_t max_length, socket_address& sender_address,
const recvfrom_handler& handler, completion_context& context) = 0;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DGRAM_SOCKET_SERVICE_HPP

View File

@ -20,9 +20,9 @@
#include "asio/detail/pop_options.hpp"
#include "asio/demuxer.hpp"
#include "asio/socket_acceptor_service.hpp"
#include "asio/socket_address.hpp"
#include "asio/socket_error.hpp"
#include "asio/detail/socket_acceptor_service.hpp"
#include "asio/detail/socket_holder.hpp"
#include "asio/detail/socket_ops.hpp"
@ -31,8 +31,8 @@ namespace asio {
socket_acceptor::
socket_acceptor(
demuxer& d)
: service_(dynamic_cast<socket_acceptor_service&>(
d.get_service(socket_acceptor_service::id))),
: service_(dynamic_cast<detail::socket_acceptor_service&>(
d.get_service(detail::socket_acceptor_service::id))),
handle_(detail::invalid_socket)
{
}
@ -42,8 +42,8 @@ socket_acceptor(
demuxer& d,
const socket_address& addr,
int listen_queue)
: service_(dynamic_cast<socket_acceptor_service&>(
d.get_service(socket_acceptor_service::id))),
: service_(dynamic_cast<detail::socket_acceptor_service&>(
d.get_service(detail::socket_acceptor_service::id))),
handle_(detail::invalid_socket)
{
open(addr, listen_queue);

View File

@ -29,9 +29,9 @@
namespace asio {
class demuxer;
class socket_acceptor_service;
class socket_address;
class socket_error;
namespace detail { class socket_acceptor_service; }
/// The socket_acceptor class is used for accepting new socket connections.
class socket_acceptor
@ -119,7 +119,7 @@ public:
private:
/// The socket_acceptor_service class is permitted to call the associate()
/// function.
friend class socket_acceptor_service;
friend class detail::socket_acceptor_service;
// Accept a new connection. Throws a socket_error exception on failure.
void accept_i(stream_socket& peer_socket);
@ -144,7 +144,7 @@ private:
stream_socket::native_type handle);
/// The backend service implementation.
socket_acceptor_service& service_;
detail::socket_acceptor_service& service_;
/// The underlying native handle.
native_type handle_;

View File

@ -20,10 +20,10 @@
#include "asio/detail/pop_options.hpp"
#include "asio/demuxer.hpp"
#include "asio/socket_connector_service.hpp"
#include "asio/socket_address.hpp"
#include "asio/socket_error.hpp"
#include "asio/detail/socket_connector_impl.hpp"
#include "asio/detail/socket_connector_service.hpp"
#include "asio/detail/socket_holder.hpp"
#include "asio/detail/socket_ops.hpp"
@ -32,8 +32,8 @@ namespace asio {
socket_connector::
socket_connector(
demuxer& d)
: service_(dynamic_cast<socket_connector_service&>(
d.get_service(socket_connector_service::id))),
: service_(dynamic_cast<detail::socket_connector_service&>(
d.get_service(detail::socket_connector_service::id))),
impl_(new detail::socket_connector_impl)
{
service_.register_socket_connector(*this);

View File

@ -29,9 +29,9 @@
namespace asio {
class demuxer;
class socket_connector_service;
class socket_address;
class socket_error;
namespace detail { class socket_connector_service; }
namespace detail { class socket_connector_impl; }
/// The socket_connector class is used to connect a socket to a remote
@ -94,7 +94,7 @@ public:
private:
/// The socket_connector_service is permitted to call the associate()
/// function.
friend class socket_connector_service;
friend class detail::socket_connector_service;
// Connect the given socket to the peer at the specified address. Throws a
// socket_error exception on failure.
@ -112,7 +112,7 @@ private:
stream_socket::native_type handle);
/// The backend service implementation.
socket_connector_service& service_;
detail::socket_connector_service& service_;
/// The underlying implementation.
detail::socket_connector_impl* impl_;

View File

@ -1,64 +0,0 @@
//
// socket_connector_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_SOCKET_CONNECTOR_SERVICE_HPP
#define ASIO_SOCKET_CONNECTOR_SERVICE_HPP
#include "asio/detail/push_options.hpp"
#include "asio/service.hpp"
#include "asio/service_type_id.hpp"
#include "asio/socket_connector.hpp"
#include "asio/stream_socket.hpp"
namespace asio {
/// The socket_connector_service class is a base class for service
/// implementations that provide the functionality required by the
/// socket_connector class.
class socket_connector_service
: public virtual service
{
public:
typedef socket_connector::connect_handler connect_handler;
/// The service type id.
static const service_type_id id;
/// Register a new socket_connector with the service. This should be called
/// only after the socket connector has been opened.
virtual void register_socket_connector(socket_connector& connector) = 0;
/// Remove a socket connector registration from the service. This should be
/// called immediately before the socket connector is closed.
virtual void deregister_socket_connector(socket_connector& connector) = 0;
/// Start an asynchronous connect on the given socket. The peer_socket object
/// be valid until the connect's completion handler is invoked.
virtual void async_socket_connect(socket_connector& connector,
stream_socket& peer_socket, const socket_address& peer_address,
const connect_handler& handler, completion_context& context) = 0;
protected:
/// Associate the given stream_socket with the underlying native handle that
/// was obtained by the connector.
static void associate_connected_stream_socket(socket_connector& connector,
stream_socket& peer_socket, stream_socket::native_type handle);
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_SOCKET_CONNECTOR_SERVICE_HPP

View File

@ -21,16 +21,16 @@
#include "asio/demuxer.hpp"
#include "asio/socket_error.hpp"
#include "asio/stream_socket_service.hpp"
#include "asio/detail/socket_ops.hpp"
#include "asio/detail/stream_socket_service.hpp"
namespace asio {
stream_socket::
stream_socket(
demuxer& d)
: service_(dynamic_cast<stream_socket_service&>(
d.get_service(stream_socket_service::id))),
: service_(dynamic_cast<detail::stream_socket_service&>(
d.get_service(detail::stream_socket_service::id))),
handle_(detail::invalid_socket)
{
}

View File

@ -31,7 +31,7 @@ class demuxer;
class socket_acceptor;
class socket_connector;
class socket_error;
class stream_socket_service;
namespace detail { class stream_socket_service; }
/// The stream_socket class provides asynchronous and blocking stream-oriented
/// socket functionality.
@ -62,6 +62,9 @@ public:
/// Get the underlying handle in the native type.
native_type native_handle() const;
/// Attach a new socket implementation.
void set_impl(native_type impl);
/// Send the given data to the peer. Returns the number of bytes sent or
/// 0 if the connection was closed cleanly. Throws a socket_error exception
/// on failure.
@ -139,7 +142,7 @@ private:
void associate(native_type handle);
/// The backend service implementation.
stream_socket_service& service_;
detail::stream_socket_service& service_;
/// The underlying native handle.
native_type handle_;

View File

@ -17,53 +17,13 @@
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread/xtime.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/completion_context.hpp"
#include "asio/basic_timer_queue.hpp"
#include "asio/detail/timer_queue_service.hpp"
namespace asio {
class demuxer;
class timer_queue_service;
/// The timer_queue class provides asynchronous timer functionality.
class timer_queue
: private boost::noncopyable
{
public:
/// Constructor.
explicit timer_queue(demuxer& d);
/// Destructor.
~timer_queue();
/// The handler for when a timer expires.
typedef boost::function0<void> timer_handler;
/// Schedule a timer to fire once at the given start_time. The id of the new
/// timer is returned so that it may be cancelled.
int schedule_timer(const boost::xtime& start_time,
const timer_handler& handler,
completion_context& context = completion_context::null());
/// Schedule a timer to fire first after at the start time, and then every
/// interval until the timer is cancelled. The id of the new timer is
/// returned so that it may be cancelled.
int schedule_timer(const boost::xtime& start_time,
const boost::xtime& interval, const timer_handler& handler,
completion_context& context = completion_context::null());
/// Cancel the timer with the given id.
void cancel_timer(int timer_id);
private:
/// The backend service implementation.
timer_queue_service& service_;
};
/// Typedef for the typical usage of timer_queue.
typedef basic_timer_queue<detail::timer_queue_service> timer_queue;
} // namespace asio

View File

@ -1,21 +0,0 @@
//
// timer_queue_service.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#include "asio/timer_queue_service.hpp"
namespace asio {
const service_type_id timer_queue_service::id;
} // namespace asio

View File

@ -1,53 +0,0 @@
//
// timer_queue_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appears in all copies and that both the copyright
// notice and this permission notice appear in supporting documentation. This
// software is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_TIMER_QUEUE_SERVICE_HPP
#define ASIO_TIMER_QUEUE_SERVICE_HPP
#include "asio/detail/push_options.hpp"
#include "asio/service.hpp"
#include "asio/service_type_id.hpp"
#include "asio/timer_queue.hpp"
namespace asio {
/// The timer_queue_service class is a base class for service implementations
/// that provide the functionality required by the timer_queue class.
class timer_queue_service
: public virtual service
{
public:
typedef timer_queue::timer_handler timer_handler;
/// The service type id.
static const service_type_id id;
/// Schedule a timer to fire first after at the start time, and then every
/// interval until the timer is cancelled. A zero interval means that the
/// timer will fire once only. The id of the new timer is returned so that it
/// may be cancelled.
virtual int schedule_timer(timer_queue& queue,
const boost::xtime& start_time, const boost::xtime& interval,
const timer_handler& handler, completion_context& context) = 0;
/// Cancel the timer with the given id.
virtual void cancel_timer(timer_queue& queue, int timer_id) = 0;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_TIMER_QUEUE_SERVICE_HPP