asio中的handler
handler的分配
申请和释放
void* asio_handler_allocate(std::size_t size, ...)
{
#if !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
# if defined(BOOST_ASIO_HAS_IOCP)typedef detail::win_iocp_io_service io_service_impl;typedef detail::win_iocp_thread_info thread_info;
# else // defined(BOOST_ASIO_HAS_IOCP)typedef detail::task_io_service io_service_impl;typedef detail::task_io_service_thread_info thread_info;
# endif // defined(BOOST_ASIO_HAS_IOCP)typedef detail::call_stack<io_service_impl, thread_info> call_stack;return thread_info::allocate(call_stack::top(), size);
#else // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)return ::operator new(size);
#endif // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
}void asio_handler_deallocate(void* pointer, std::size_t size, ...)
{
#if !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
# if defined(BOOST_ASIO_HAS_IOCP)typedef detail::win_iocp_io_service io_service_impl;typedef detail::win_iocp_thread_info thread_info;
# else // defined(BOOST_ASIO_HAS_IOCP)typedef detail::task_io_service io_service_impl;typedef detail::task_io_service_thread_info thread_info;
# endif // defined(BOOST_ASIO_HAS_IOCP)typedef detail::call_stack<io_service_impl, thread_info> call_stack;thread_info::deallocate(call_stack::top(), pointer, size);
#else // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)(void)size;::operator delete(pointer);
#endif // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
}
对于其它重载的asio_handler_allocate
,asio_handler_deallocate
最后是调用命名空间boost_asio_handler_alloc_helpers
的allocate
和deallocate
,最后就是调用命令空间boost::asio::asio_handler_allocate
和boost::asio::asio_handler_deallocate
template <typename Handler>
inline void* allocate(std::size_t s, Handler& h)
{
#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)return ::operator new(s);
#elseusing boost::asio::asio_handler_allocate;return asio_handler_allocate(s, boost::asio::detail::addressof(h));
#endif
}template <typename Handler>
inline void deallocate(void* p, std::size_t s, Handler& h)
{
#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)::operator delete(p);
#elseusing boost::asio::asio_handler_deallocate;asio_handler_deallocate(p, s, boost::asio::detail::addressof(h));
#endif
}
- 对于定义了宏
BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING
分配是直接使用new
和delete
- 没有定义宏
BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING
的使用- 非windows平台使用
task_io_service_thread_info::allocate
,task_io_service_thread_info::deallocate
- window平台使用
win_iocp_thread_info::allocate
,win_iocp_thread_info::deallocate
- 非windows平台使用
以linux平台为例
小内存分配策略为如果申请和释放不在一个线程时,在一个线程分配后,回收到另外一个线程。要求分配的大小不会超过255,分配时内存的最后一个字节表示分配的大小,回来收后第一字节表示内存大小
static void* allocate(thread_info_base* this_thread, std::size_t size){if (this_thread && this_thread->reusable_memory_){void* const pointer = this_thread->reusable_memory_;this_thread->reusable_memory_ = 0;unsigned char* const mem = static_cast<unsigned char*>(pointer);if (static_cast<std::size_t>(mem[0]) >= size){mem[size] = mem[0];return pointer;}::operator delete(pointer);}void* const pointer = ::operator new(size + 1);unsigned char* const mem = static_cast<unsigned char*>(pointer);mem[size] = (size <= UCHAR_MAX) ? static_cast<unsigned char>(size) : 0;return pointer;}static void deallocate(thread_info_base* this_thread,void* pointer, std::size_t size){if (size <= UCHAR_MAX){if (this_thread && this_thread->reusable_memory_ == 0){unsigned char* const mem = static_cast<unsigned char*>(pointer);mem[0] = mem[size];this_thread->reusable_memory_ = pointer;return;}}::operator delete(pointer);}
handler的调用
template <typename Function>
inline void asio_handler_invoke(Function& function, ...)
{function();
}template <typename Function>
inline void asio_handler_invoke(const Function& function, ...)
{Function tmp(function);tmp();
}
其它重载的asio_handler_invoke
函数调用boost_asio_handler_invoke_helpers::invoke
,最终是调用boost::asio::asio_handler_invoke
template <typename Function, typename Context>
inline void invoke(Function& function, Context& context)
{
#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)Function tmp(function);tmp();
#elseusing boost::asio::asio_handler_invoke;asio_handler_invoke(function, boost::asio::detail::addressof(context));
#endif
}template <typename Function, typename Context>
inline void invoke(const Function& function, Context& context)
{
#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)Function tmp(function);tmp();
#elseusing boost::asio::asio_handler_invoke;asio_handler_invoke(function, boost::asio::detail::addressof(context));
#endif
}
wrapped_handler
异步调用,将handler放到io_service
中运行
其asio_handler_invoke
定义为
template <typename Function, typename Dispatcher,typename Handler, typename IsContinuation>
inline void asio_handler_invoke(Function& function,wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)
{this_handler->dispatcher_.dispatch(rewrapped_handler<Function, Handler>(function, this_handler->handler_));
}
handler的类型
template <typename Handler, typename Signature>
struct handler_type
{/// The handler type for the specific signature.typedef Handler type;
};
其有不同的类型
template <typename Handler, typename Signature>
struct handler_type<const Handler, Signature>: handler_type<Handler, Signature> {};template <typename Handler, typename Signature>
struct handler_type<volatile Handler, Signature>: handler_type<Handler, Signature> {};template <typename Handler, typename Signature>
struct handler_type<const volatile Handler, Signature>: handler_type<Handler, Signature> {};template <typename Handler, typename Signature>
struct handler_type<const Handler&, Signature>: handler_type<Handler, Signature> {};template <typename Handler, typename Signature>
struct handler_type<volatile Handler&, Signature>: handler_type<Handler, Signature> {};template <typename Handler, typename Signature>
struct handler_type<const volatile Handler&, Signature>: handler_type<Handler, Signature> {};template <typename Handler, typename Signature>
struct handler_type<Handler&, Signature>: handler_type<Handler, Signature> {};#if defined(BOOST_ASIO_HAS_MOVE)
template <typename Handler, typename Signature>
struct handler_type<Handler&&, Signature>: handler_type<Handler, Signature> {};
#endif // defined(BOOST_ASIO_HAS_MOVE)template <typename ReturnType, typename Signature>
struct handler_type<ReturnType(), Signature>: handler_type<ReturnType(*)(), Signature> {};template <typename ReturnType, typename Arg1, typename Signature>
struct handler_type<ReturnType(Arg1), Signature>: handler_type<ReturnType(*)(Arg1), Signature> {};template <typename ReturnType, typename Arg1, typename Arg2, typename Signature>
struct handler_type<ReturnType(Arg1, Arg2), Signature>: handler_type<ReturnType(*)(Arg1, Arg2), Signature> {};template <typename ReturnType, typename Arg1, typename Arg2, typename Arg3,typename Signature>
struct handler_type<ReturnType(Arg1, Arg2, Arg3), Signature>: handler_type<ReturnType(*)(Arg1, Arg2, Arg3), Signature> {};template <typename ReturnType, typename Arg1, typename Arg2, typename Arg3,typename Arg4, typename Signature>
struct handler_type<ReturnType(Arg1, Arg2, Arg3, Arg4), Signature>: handler_type<ReturnType(*)(Arg1, Arg2, Arg3, Arg4), Signature> {};template <typename ReturnType, typename Arg1, typename Arg2, typename Arg3,typename Arg4, typename Arg5, typename Signature>
struct handler_type<ReturnType(Arg1, Arg2, Arg3, Arg4, Arg5), Signature>: handler_type<ReturnType(*)(Arg1, Arg2, Arg3, Arg4, Arg5), Signature> {};
handler连续性
默认为不可连续性
inline bool asio_handler_is_continuation(...)
{return false;
}
其它的重载函数默认是调用boost_asio_handler_cont_helpers::is_continuation
,其默认是调用boost::asio::asio_handler_is_continuation
,即默认是不可连续的
template <typename Context>
inline bool is_continuation(Context& context)
{
#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)return false;
#elseusing boost::asio::asio_handler_is_continuation;return asio_handler_is_continuation(boost::asio::detail::addressof(context));
#endif
}
以binder1为例
template <typename Handler, typename Arg1>
inline bool asio_handler_is_continuation(binder1<Handler, Arg1>* this_handler)
{return boost_asio_handler_cont_helpers::is_continuation(this_handler->handler_);
}
而wrapped_handler
的连续性通过下面两个来判断可连续性
- is_continuation_delegated:默认是不连续的
- is_continuation_if_running:调用
running_in_this_thread
(strand_service
中有这个方法)