Files
libremetaverse/libsecondlife/include/boost/asio/basic_locking_dispatcher.hpp
2006-06-08 14:47:51 +00:00

184 lines
5.9 KiB
C++

//
// basic_locking_dispatcher.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2005 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 BOOST_ASIO_BASIC_LOCKING_DISPATCHER_HPP
#define BOOST_ASIO_BASIC_LOCKING_DISPATCHER_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/push_options.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/service_factory.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/wrapped_handler.hpp>
namespace boost {
namespace asio {
/// Provides serialised handler execution.
/**
* 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 boost::asio::locking_dispatcher typedef.
*
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Safe.
*
* @par Concepts:
* Async_Object, Dispatcher, Error_Source.
*/
template <typename Service>
class basic_locking_dispatcher
: private noncopyable
{
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;
/// The type used for reporting errors.
typedef boost::asio::error error_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_);
}
/// Get the demuxer associated with the asynchronous object.
/**
* This function may be used to obtain the demuxer object that the locking
* dispatcher uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the demuxer object that the dispatcher will use to
* dispatch handlers. Ownership is not transferred to the caller.
*/
demuxer_type& demuxer()
{
return service_.demuxer();
}
/// 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 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 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 function signature of the handler
* must be: @code void handler(A1 a1, ... An an); @endcode
*
* @return A function object that, when invoked, passes the wrapped handler to
* the dispatcher's dispatch function. Given a function object with the
* signature:
* @code R f(A1 a1, ... An an); @endcode
* If this function object is passed to the wrap function like so:
* @code dispatcher.wrap(f); @endcode
* then the return value is a function object with the signature
* @code void g(A1 a1, ... An an); @endcode
* that, when invoked, executes code equivalent to:
* @code dispatcher.dispatch(boost::bind(f, a1, ... an)); @endcode
*/
template <typename Handler>
#if defined(GENERATING_DOCUMENTATION)
unspecified
#else
detail::wrapped_handler<basic_locking_dispatcher<Service>, Handler>
#endif
wrap(Handler handler)
{
return detail::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
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_BASIC_LOCKING_DISPATCHER_HPP