Added initial locking_dispatcher implementation.
This commit is contained in:
parent
271db66458
commit
24e0725efa
@ -2,6 +2,7 @@ nobase_include_HEADERS = \
|
||||
asio.hpp \
|
||||
asio/basic_demuxer.hpp \
|
||||
asio/basic_dgram_socket.hpp \
|
||||
asio/basic_locking_dispatcher.hpp \
|
||||
asio/basic_socket_acceptor.hpp \
|
||||
asio/basic_socket_connector.hpp \
|
||||
asio/basic_stream_socket.hpp \
|
||||
@ -13,6 +14,7 @@ nobase_include_HEADERS = \
|
||||
asio/detail/bind_handler.hpp \
|
||||
asio/detail/buffer_resize_guard.hpp \
|
||||
asio/detail/event.hpp \
|
||||
asio/detail/locking_dispatcher_service.hpp \
|
||||
asio/detail/mutex.hpp \
|
||||
asio/detail/pipe_select_interrupter.hpp \
|
||||
asio/detail/pop_options.hpp \
|
||||
@ -57,6 +59,7 @@ nobase_include_HEADERS = \
|
||||
asio/ipv4/address.hpp \
|
||||
asio/ipv4/tcp.hpp \
|
||||
asio/ipv4/udp.hpp \
|
||||
asio/locking_dispatcher.hpp \
|
||||
asio/recv.hpp \
|
||||
asio/send.hpp \
|
||||
asio/service_factory.hpp \
|
||||
@ -66,7 +69,8 @@ nobase_include_HEADERS = \
|
||||
asio/socket_option.hpp \
|
||||
asio/stream_socket.hpp \
|
||||
asio/timer.hpp \
|
||||
asio/timer_base.hpp
|
||||
asio/timer_base.hpp \
|
||||
asio/wrapped_handler.hpp
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "asio/basic_demuxer.hpp"
|
||||
#include "asio/basic_dgram_socket.hpp"
|
||||
#include "asio/basic_locking_dispatcher.hpp"
|
||||
#include "asio/basic_socket_acceptor.hpp"
|
||||
#include "asio/basic_socket_connector.hpp"
|
||||
#include "asio/basic_stream_socket.hpp"
|
||||
@ -31,6 +32,7 @@
|
||||
#include "asio/ipv4/address.hpp"
|
||||
#include "asio/ipv4/tcp.hpp"
|
||||
#include "asio/ipv4/udp.hpp"
|
||||
#include "asio/locking_dispatcher.hpp"
|
||||
#include "asio/recv.hpp"
|
||||
#include "asio/send.hpp"
|
||||
#include "asio/service_factory.hpp"
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/service_factory.hpp"
|
||||
#include "asio/wrapped_handler.hpp"
|
||||
#include "asio/detail/bind_handler.hpp"
|
||||
#include "asio/detail/service_registry.hpp"
|
||||
#include "asio/detail/signal_init.hpp"
|
||||
#include "asio/detail/winsock_init.hpp"
|
||||
@ -162,31 +164,6 @@ public:
|
||||
service_.post(handler);
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
class wrapped_handler
|
||||
{
|
||||
public:
|
||||
wrapped_handler(basic_demuxer<Demuxer_Service>& demuxer, Handler handler)
|
||||
: demuxer_(demuxer),
|
||||
handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
demuxer_.dispatch(handler_);
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
demuxer_.dispatch(handler_);
|
||||
}
|
||||
|
||||
private:
|
||||
basic_demuxer<Demuxer_Service>& demuxer_;
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
/// Create a new handler that automatically dispatches the wrapped handler
|
||||
/// on the demuxer.
|
||||
/**
|
||||
@ -199,9 +176,11 @@ public:
|
||||
* the handler must be: @code void handler(); @endcode
|
||||
*/
|
||||
template <typename Handler>
|
||||
wrapped_handler<Handler> wrap(Handler handler)
|
||||
wrapped_handler<basic_demuxer<Demuxer_Service>, Handler> wrap(
|
||||
Handler handler)
|
||||
{
|
||||
return wrapped_handler<Handler>(*this, handler);
|
||||
return wrapped_handler<basic_demuxer<Demuxer_Service>, Handler>(*this,
|
||||
handler);
|
||||
}
|
||||
|
||||
/// Obtain the service interface corresponding to the given type.
|
||||
|
139
asio/include/asio/basic_locking_dispatcher.hpp
Normal file
139
asio/include/asio/basic_locking_dispatcher.hpp
Normal file
@ -0,0 +1,139 @@
|
||||
//
|
||||
// basic_locking_dispatcher.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003, 2004 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_LOCKING_DISPATCHER_HPP
|
||||
#define ASIO_BASIC_LOCKING_DISPATCHER_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/wrapped_handler.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// The basic_locking_dispatcher class template provides the ability to post
|
||||
/// and dispatch handlers with the guarantee that none of those handlers will
|
||||
/// execute concurrently. Most applications will use the locking_dispatcher
|
||||
/// typedef.
|
||||
template <typename Service>
|
||||
class basic_locking_dispatcher
|
||||
{
|
||||
public:
|
||||
/// The type of the service that will be used to provide locking dispatcher
|
||||
/// operations.
|
||||
typedef Service service_type;
|
||||
|
||||
/// The native implementation type of the locking dispatcher.
|
||||
typedef typename service_type::impl_type impl_type;
|
||||
|
||||
/// The demuxer type for this dispatcher.
|
||||
typedef typename service_type::demuxer_type demuxer_type;
|
||||
|
||||
/// Constructor.
|
||||
/**
|
||||
* Constructs the locking dispatcher.
|
||||
*
|
||||
* @param d The demuxer object that the locking dispatcher will use to
|
||||
* dispatch handlers that are ready to be run.
|
||||
*/
|
||||
explicit basic_locking_dispatcher(demuxer_type& d)
|
||||
: service_(d.get_service(service_factory<Service>())),
|
||||
impl_(service_.null())
|
||||
{
|
||||
service_.create(impl_);
|
||||
}
|
||||
|
||||
/// Destructor.
|
||||
~basic_locking_dispatcher()
|
||||
{
|
||||
service_.destroy(impl_);
|
||||
}
|
||||
|
||||
/// Request the dispatcher to invoke the given handler.
|
||||
/**
|
||||
* This function is used to ask the dispatcher to execute the given handler.
|
||||
*
|
||||
* The dispatcher guarantees that the handler will only be called in a thread
|
||||
* in which the underlying demuxer's run member function is currently being
|
||||
* invoked. It also guarantees that only one handler executed through this
|
||||
* dispatcher will be invoked at a time. The handler may be executed inside
|
||||
* this function if the guarantee can be met.
|
||||
*
|
||||
* @param handler The handler to be called. The dispatcher will make
|
||||
* a copy of the handler object as required. The equivalent function
|
||||
* signature of the handler must be: @code void handler(); @endcode
|
||||
*/
|
||||
template <typename Handler>
|
||||
void dispatch(Handler handler)
|
||||
{
|
||||
service_.dispatch(impl_, handler);
|
||||
}
|
||||
|
||||
/// Request the dispatcher to invoke the given handler and return
|
||||
/// immediately.
|
||||
/**
|
||||
* This function is used to ask the dispatcher to execute the given handler,
|
||||
* but without allowing the dispatcher to call the handler from inside this
|
||||
* function.
|
||||
*
|
||||
* The dispatcher guarantees that the handler will only be called in a thread
|
||||
* in which the underlying demuxer's run member function is currently being
|
||||
* invoked. It also guarantees that only one handler executed through this
|
||||
* dispatcher will be invoked at a time.
|
||||
*
|
||||
* @param handler The handler to be called. The dispatcher will make
|
||||
* a copy of the handler object as required. The equivalent function
|
||||
* signature of the handler must be: @code void handler(); @endcode
|
||||
*/
|
||||
template <typename Handler>
|
||||
void post(Handler handler)
|
||||
{
|
||||
service_.post(impl_, handler);
|
||||
}
|
||||
|
||||
/// Create a new handler that automatically dispatches the wrapped handler
|
||||
/// on the dispatcher.
|
||||
/**
|
||||
* This function is used to create a new handler function object that, when
|
||||
* invoked, will automatically pass the wrapped handler to the dispatcher's
|
||||
* dispatch function.
|
||||
*
|
||||
* @param handler The handler to be wrapped. The dispatcher will make a copy
|
||||
* of the handler object as required. The equivalent function signature of
|
||||
* the handler must be: @code void handler(); @endcode
|
||||
*/
|
||||
template <typename Handler>
|
||||
wrapped_handler<basic_locking_dispatcher<Service>, Handler> wrap(
|
||||
Handler handler)
|
||||
{
|
||||
return wrapped_handler<basic_locking_dispatcher<Service>, Handler>(*this,
|
||||
handler);
|
||||
}
|
||||
|
||||
private:
|
||||
/// The backend service implementation.
|
||||
service_type& service_;
|
||||
|
||||
/// The underlying native implementation.
|
||||
impl_type impl_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_LOCKING_DISPATCHER_HPP
|
@ -128,6 +128,91 @@ binder3<Handler, Arg1, Arg2, Arg3> bind_handler(Handler handler, Arg1 arg1,
|
||||
return binder3<Handler, Arg1, Arg2, Arg3>(handler, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
class binder4
|
||||
{
|
||||
public:
|
||||
binder4(Handler handler, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
|
||||
: handler_(handler),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
arg4_(arg4)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_);
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
Arg4 arg4_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4> bind_handler(Handler handler,
|
||||
Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
|
||||
{
|
||||
return binder4<Handler, Arg1, Arg2, Arg3, Arg4>(handler, arg1, arg2, arg3,
|
||||
arg4);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
class binder5
|
||||
{
|
||||
public:
|
||||
binder5(Handler handler, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4,
|
||||
Arg5 arg5)
|
||||
: handler_(handler),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
arg4_(arg4),
|
||||
arg5_(arg5)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
Arg4 arg4_;
|
||||
Arg5 arg5_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5> bind_handler(Handler handler,
|
||||
Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
|
||||
{
|
||||
return binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>(handler, arg1, arg2,
|
||||
arg3, arg4, arg5);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
|
252
asio/include/asio/detail/locking_dispatcher_service.hpp
Normal file
252
asio/include/asio/detail/locking_dispatcher_service.hpp
Normal file
@ -0,0 +1,252 @@
|
||||
//
|
||||
// locking_dispatcher_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003, 2004 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_LOCKING_DISPATCHER_SERVICE_HPP
|
||||
#define ASIO_DETAIL_LOCKING_DISPATCHER_SERVICE_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/detail/bind_handler.hpp"
|
||||
#include "asio/detail/mutex.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename Demuxer>
|
||||
class locking_dispatcher_service
|
||||
{
|
||||
public:
|
||||
class dispatcher_impl
|
||||
: private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
// Constructor.
|
||||
dispatcher_impl()
|
||||
: first_waiter_(),
|
||||
last_waiter_(),
|
||||
mutex_()
|
||||
{
|
||||
}
|
||||
|
||||
// Request a dispatcher to invoke the given handler.
|
||||
template <typename Handler>
|
||||
void dispatch(Demuxer& demuxer, Handler handler)
|
||||
{
|
||||
detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
if (first_waiter_ == 0)
|
||||
{
|
||||
// This handler now has the lock, so can be dispatched immediately.
|
||||
first_waiter_ = last_waiter_ = new waiter<Handler>(handler);
|
||||
lock.unlock();
|
||||
demuxer.dispatch(waiter_handler(demuxer, *this));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Another waiter already holds the lock, so this handler must join
|
||||
// the list of waiters. The handler will be posted automatically when
|
||||
// its turn comes.
|
||||
last_waiter_->next_ = new waiter<Handler>(handler);
|
||||
last_waiter_ = last_waiter_->next_;
|
||||
}
|
||||
}
|
||||
|
||||
// Request a dispatcher to invoke the given handler and return immediately.
|
||||
template <typename Handler>
|
||||
void post(Demuxer& demuxer, Handler handler)
|
||||
{
|
||||
detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
if (first_waiter_ == 0)
|
||||
{
|
||||
// This handler now has the lock, so can be posted immediately.
|
||||
first_waiter_ = last_waiter_ = new waiter<Handler>(handler);
|
||||
lock.unlock();
|
||||
demuxer.post(waiter_handler(demuxer, *this));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Another waiter already holds the lock, so this handler must join
|
||||
// the list of waiters. The handler will be posted automatically when
|
||||
// its turn comes.
|
||||
last_waiter_->next_ = new waiter<Handler>(handler);
|
||||
last_waiter_ = last_waiter_->next_;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Base class for all waiter types.
|
||||
class waiter_base
|
||||
{
|
||||
public:
|
||||
waiter_base()
|
||||
: next_(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~waiter_base()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void call() = 0;
|
||||
|
||||
waiter_base* next_;
|
||||
};
|
||||
|
||||
// Class template for a waiter.
|
||||
template <typename Handler>
|
||||
class waiter
|
||||
: public waiter_base
|
||||
{
|
||||
public:
|
||||
waiter(Handler handler)
|
||||
: handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void call()
|
||||
{
|
||||
handler_();
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
// Helper class to allow waiting handlers to be dispatched.
|
||||
class waiter_handler
|
||||
{
|
||||
public:
|
||||
waiter_handler(Demuxer& demuxer, dispatcher_impl& impl)
|
||||
: demuxer_(demuxer),
|
||||
impl_(impl)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
do_upcall();
|
||||
detail::mutex::scoped_lock lock(impl_.mutex_);
|
||||
waiter_base* tmp = impl_.first_waiter_;
|
||||
impl_.first_waiter_ = impl_.first_waiter_->next_;
|
||||
delete tmp;
|
||||
if (impl_.first_waiter_)
|
||||
{
|
||||
lock.unlock();
|
||||
demuxer_.post(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
impl_.last_waiter_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void do_upcall()
|
||||
{
|
||||
try
|
||||
{
|
||||
impl_.first_waiter_->call();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Demuxer& demuxer_;
|
||||
dispatcher_impl& impl_;
|
||||
};
|
||||
|
||||
friend class waiter_handler;
|
||||
|
||||
// The start of the list of waiters for the dispatcher. If this pointer
|
||||
// is non-null then it indicates that a handler holds the lock.
|
||||
waiter_base* first_waiter_;
|
||||
|
||||
// The end of the list of waiters for the dispatcher.
|
||||
waiter_base* last_waiter_;
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
detail::mutex mutex_;
|
||||
};
|
||||
|
||||
// The native type of the locking dispatcher.
|
||||
typedef dispatcher_impl* impl_type;
|
||||
|
||||
// Return a null locking dispatcher implementation.
|
||||
static impl_type null()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Constructor.
|
||||
locking_dispatcher_service(Demuxer& d)
|
||||
: demuxer_(d)
|
||||
{
|
||||
}
|
||||
|
||||
// The demuxer type for this service.
|
||||
typedef Demuxer demuxer_type;
|
||||
|
||||
// Get the demuxer associated with the service.
|
||||
demuxer_type& demuxer()
|
||||
{
|
||||
return demuxer_;
|
||||
}
|
||||
|
||||
// Create a new locking dispatcher implementation.
|
||||
void create(impl_type& impl)
|
||||
{
|
||||
impl = new dispatcher_impl;
|
||||
}
|
||||
|
||||
// Destroy a locking dispatcher implementation.
|
||||
void destroy(impl_type& impl)
|
||||
{
|
||||
if (impl != null())
|
||||
{
|
||||
delete impl;
|
||||
impl = null();
|
||||
}
|
||||
}
|
||||
|
||||
// Request a dispatcher to invoke the given handler.
|
||||
template <typename Handler>
|
||||
void dispatch(impl_type& impl, Handler handler)
|
||||
{
|
||||
impl->dispatch(demuxer_, handler);
|
||||
}
|
||||
|
||||
// Request a dispatcher to invoke the given handler and return immediately.
|
||||
template <typename Handler>
|
||||
void post(impl_type& impl, Handler handler)
|
||||
{
|
||||
impl->post(demuxer_, handler);
|
||||
}
|
||||
|
||||
private:
|
||||
// The demuxer used for dispatching handlers.
|
||||
Demuxer& demuxer_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_LOCKING_DISPATCHER_SERVICE_HPP
|
43
asio/include/asio/locking_dispatcher.hpp
Normal file
43
asio/include/asio/locking_dispatcher.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// locking_dispatcher.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003, 2004 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_LOCKING_DISPATCHER_HPP
|
||||
#define ASIO_LOCKING_DISPATCHER_HPP
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/basic_locking_dispatcher.hpp"
|
||||
#include "asio/demuxer.hpp"
|
||||
#include "asio/detail/locking_dispatcher_service.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Typedef for the typical usage of locking_dispatcher.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef basic_locking_dispatcher
|
||||
<
|
||||
implementation_defined
|
||||
> locking_dispatcher;
|
||||
#else
|
||||
typedef basic_locking_dispatcher
|
||||
<
|
||||
detail::locking_dispatcher_service<demuxer>
|
||||
> locking_dispatcher;
|
||||
#endif
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_LOCKING_DISPATCHER_HPP
|
119
asio/include/asio/wrapped_handler.hpp
Normal file
119
asio/include/asio/wrapped_handler.hpp
Normal file
@ -0,0 +1,119 @@
|
||||
//
|
||||
// wrapped_handler.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003, 2004 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_WRAPPED_HANDLER_HPP
|
||||
#define ASIO_WRAPPED_HANDLER_HPP
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/bind_handler.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
template <typename Dispatcher, typename Handler>
|
||||
class wrapped_handler
|
||||
{
|
||||
public:
|
||||
wrapped_handler(Dispatcher& dispatcher, Handler handler)
|
||||
: dispatcher_(dispatcher),
|
||||
handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
dispatcher_.dispatch(handler_);
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
dispatcher_.dispatch(handler_);
|
||||
}
|
||||
|
||||
template <typename Arg1>
|
||||
void operator()(Arg1 arg1)
|
||||
{
|
||||
dispatcher_.dispatch(detail::bind_handler(handler_, arg1));
|
||||
}
|
||||
|
||||
template <typename Arg1>
|
||||
void operator()(Arg1 arg1) const
|
||||
{
|
||||
dispatcher_.dispatch(detail::bind_handler(handler_, arg1));
|
||||
}
|
||||
|
||||
template <typename Arg1, typename Arg2>
|
||||
void operator()(Arg1 arg1, Arg2 arg2)
|
||||
{
|
||||
dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2));
|
||||
}
|
||||
|
||||
template <typename Arg1, typename Arg2>
|
||||
void operator()(Arg1 arg1, Arg2 arg2) const
|
||||
{
|
||||
dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2));
|
||||
}
|
||||
|
||||
template <typename Arg1, typename Arg2, typename Arg3>
|
||||
void operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3)
|
||||
{
|
||||
dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3));
|
||||
}
|
||||
|
||||
template <typename Arg1, typename Arg2, typename Arg3>
|
||||
void operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3) const
|
||||
{
|
||||
dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3));
|
||||
}
|
||||
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
|
||||
void operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
|
||||
{
|
||||
dispatcher_.dispatch(
|
||||
detail::bind_handler(handler_, arg1, arg2, arg3, arg4));
|
||||
}
|
||||
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
|
||||
void operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) const
|
||||
{
|
||||
dispatcher_.dispatch(
|
||||
detail::bind_handler(handler_, arg1, arg2, arg3, arg4));
|
||||
}
|
||||
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
|
||||
typename Arg5>
|
||||
void operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
|
||||
{
|
||||
dispatcher_.dispatch(
|
||||
detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));
|
||||
}
|
||||
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
|
||||
typename Arg5>
|
||||
void operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) const
|
||||
{
|
||||
dispatcher_.dispatch(
|
||||
detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));
|
||||
}
|
||||
|
||||
private:
|
||||
Dispatcher& dispatcher_;
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_WRAPPED_HANDLER_HPP
|
@ -9,6 +9,7 @@ noinst_PROGRAMS = \
|
||||
tests/unit/dgram_socket_test \
|
||||
tests/unit/error_handler_test \
|
||||
tests/unit/fixed_buffer_test \
|
||||
tests/unit/locking_dispatcher_test \
|
||||
tests/unit/socket_acceptor_test \
|
||||
tests/unit/timer_test \
|
||||
examples/chat/chat_client \
|
||||
@ -47,6 +48,7 @@ tests_unit_demuxer_test_SOURCES = tests/unit/demuxer_test.cpp
|
||||
tests_unit_dgram_socket_test_SOURCES = tests/unit/dgram_socket_test.cpp
|
||||
tests_unit_error_handler_test_SOURCES = tests/unit/error_handler_test.cpp
|
||||
tests_unit_fixed_buffer_test_SOURCES = tests/unit/fixed_buffer_test.cpp
|
||||
tests_unit_locking_dispatcher_test_SOURCES = tests/unit/locking_dispatcher_test.cpp
|
||||
tests_unit_socket_acceptor_test_SOURCES = tests/unit/socket_acceptor_test.cpp
|
||||
tests_unit_timer_test_SOURCES = tests/unit/timer_test.cpp
|
||||
examples_chat_chat_client_SOURCES = examples/chat/chat_client.cpp
|
||||
|
@ -13,6 +13,7 @@ all: \
|
||||
tests\unit\dgram_socket_test.exe \
|
||||
tests\unit\error_handler_test.exe \
|
||||
tests\unit\fixed_buffer_test.exe \
|
||||
tests\unit\locking_dispatcher_test.exe \
|
||||
tests\unit\socket_acceptor_test.exe \
|
||||
tests\unit\timer_test.exe \
|
||||
examples\chat\chat_client.exe \
|
||||
@ -36,6 +37,7 @@ check: all
|
||||
@tests\unit\dgram_socket_test.exe
|
||||
@tests\unit\error_handler_test.exe
|
||||
@tests\unit\fixed_buffer_test.exe
|
||||
@tests\unit\locking_dispatcher_test.exe
|
||||
@tests\unit\socket_acceptor_test.exe
|
||||
@tests\unit\timer_test.exe
|
||||
|
||||
|
@ -13,6 +13,7 @@ TEST_EXES = \
|
||||
tests/unit/dgram_socket_test.exe \
|
||||
tests/unit/error_handler_test.exe \
|
||||
tests/unit/fixed_buffer_test.exe \
|
||||
tests/unit/locking_dispatcher_test.exe \
|
||||
tests/unit/socket_acceptor_test.exe \
|
||||
tests/unit/timer_test.exe
|
||||
|
||||
|
@ -13,6 +13,7 @@ all: \
|
||||
tests\unit\dgram_socket_test.exe \
|
||||
tests\unit\error_handler_test.exe \
|
||||
tests\unit\fixed_buffer_test.exe \
|
||||
tests\unit\locking_dispatcher_test.exe \
|
||||
tests\unit\socket_acceptor_test.exe \
|
||||
tests\unit\timer_test.exe \
|
||||
examples\chat\chat_client.exe \
|
||||
@ -37,6 +38,7 @@ tests\unit\demuxer_test.exe: tests\unit\demuxer_test.obj
|
||||
tests\unit\dgram_socket_test.exe: tests\unit\dgram_socket_test.obj
|
||||
tests\unit\error_handler_test.exe: tests\unit\error_handler_test.obj
|
||||
tests\unit\fixed_buffer_test.exe: tests\unit\fixed_buffer_test.obj
|
||||
tests\unit\locking_dispatcher_test.exe: tests\unit\locking_dispatcher_test.obj
|
||||
tests\unit\socket_acceptor_test.exe: tests\unit\socket_acceptor_test.obj
|
||||
tests\unit\timer_test.exe: tests\unit\timer_test.obj
|
||||
examples\chat\chat_client.exe: examples\chat\chat_client.obj
|
||||
|
Loading…
Reference in New Issue
Block a user