asynchronous_operations.qbk

来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 177 行

QBK
177
字号
[/ / Copyright (c) 2003-2008 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) /][section:asynchronous_operations Requirements on asynchronous operations]In Boost.Asio, an asynchronous operation is initiated by a function that isnamed with the prefix `async_`. These functions will be referred to as['initiating functions].All initiating functions in Boost.Asio take a function object meeting [linkboost_asio.reference.Handler handler] requirements as the final parameter.These handlers accept as their first parameter an lvalue of type `consterror_code`.Implementations of asynchronous operations in Boost.Asio may call theapplication programming interface (API) provided by the operating system. Ifsuch an operating system API call results in an error, the handler will beinvoked with a `const error_code` lvalue that evaluates to true. Otherwise thehandler will be invoked with a `const error_code` lvalue that evaluates tofalse.Unless otherwise noted, when the behaviour of an asynchronous operation isdefined "as if" implemented by a __POSIX__ function, the handler will beinvoked with a value of type `error_code` that corresponds to the failurecondition described by __POSIX__ for that function, if any. Otherwise thehandler will be invoked with an implementation-defined `error_code` value thatreflects the operating system error.Asynchronous operations will not fail with an error condition that indicatesinterruption by a signal (__POSIX__ `EINTR`). Asynchronous operations will notfail with any error condition associated with non-blocking operations(__POSIX__ `EWOULDBLOCK`, `EAGAIN` or `EINPROGRESS`; __Windows__`WSAEWOULDBLOCK` or `WSAEINPROGRESS`).All asynchronous operations have an associated `io_service` object. Where theinitiating function is a member function, the associated `io_service` is thatreturned by the `io_service()` member function on the same object. Where theinitiating function is not a member function, the associated `io_service` isthat returned by the `io_service()` member function of the first argument tothe initiating function.Arguments to initiating functions will be treated as follows:[mdash] If the parameter is declared as a const reference or by-value, theprogram is not required to guarantee the validity of the argument after theinitiating function completes. The implementation may make copies of theargument, and all copies will be destroyed no later than immediately afterinvocation of the handler.[mdash] If the parameter is declared as a non-const reference, const pointer ornon-const pointer, the program must guarantee the validity of the argumentuntil the handler is invoked.The library implementation is only permitted to make calls to an initiatingfunction's arguments' copy constructors or destructors from a thread thatsatisfies one of the following conditions:[mdash] The thread is executing any member function of the associated`io_service` object.[mdash] The thread is executing the destructor of the associated `io_service`object.[mdash] The thread is executing one of the `io_service` service accessfunctions `use_service`, `add_service` or `has_service`, where the firstargument is the associated `io_service` object.[mdash] The thread is executing any member function, constructor or destructorof an object of a class defined in this clause, where the object's`io_service()` member function returns the associated `io_service` object.[mdash] The thread is executing any function defined in this clause, where anyargument to the function has an `io_service()` member function that returns theassociated `io_service` object.[blurb Boost.Asio may use one or more hidden threads to emulate asynchronousfunctionality. The above requirements are intended to prevent these hiddenthreads from making calls to program code. This means that a program can, forexample, use thread-unsafe reference counting in handler objects, provided theprogram ensures that all calls to an `io_service` and related objects occurfrom the one thread.]The `io_service` object associated with an asynchronous operation will haveunfinished work, as if by maintaining the existence of one or more objects ofclass `io_service::work` constructed using the `io_service`, until immediatelyafter the handler for the asynchronous operation has been invoked.When an asynchronous operation is complete, the handler for the operation willbe invoked as if by:# Constructing a bound completion handler `bch` for the handler, as described  below.# Calling `ios.post(bch)` to schedule the handler for deferred invocation,  where `ios` is the associated `io_service`.This implies that the handler must not be called directly from withinthe initiating function, even if the asynchronous operation completesimmediately.A bound completion handler is a handler object that contains a copy of auser-supplied handler, where the user-supplied handler accepts one or morearguments. The bound completion handler does not accept any arguments, andcontains values to be passed as arguments to the user-supplied handler. Thebound completion handler forwards the `asio_handler_allocate()`,`asio_handler_deallocate()`, and `asio_handler_invoke()` calls to thecorresponding functions for the user-supplied handler. A bound completionhandler meets the requirements for a [linkboost_asio.reference.CompletionHandler completion handler].For example, a bound completion handler for a `ReadHandler` may be implementedas follows:  template<class ReadHandler>  struct bound_read_handler  {    bound_read_handler(ReadHandler handler, const error_code& ec, size_t s)      : handler_(handler), ec_(ec), s_(s)    {    }    void operator()()    {      handler_(ec_, s_);    }    ReadHandler handler_;    const error_code ec_;    const size_t s_;  };  template<class ReadHandler>  void* asio_handler_allocate(size_t size,                              bound_read_handler<ReadHandler>* this_handler)  {    using namespace boost::asio;    return asio_handler_allocate(size, &this_handler->handler_);  }  template<class ReadHandler>  void asio_handler_deallocate(void* pointer, std::size_t size,                               bound_read_handler<ReadHandler>* this_handler)  {    using namespace boost::asio;    asio_handler_deallocate(pointer, size, &this_handler->handler_);  }  template<class F, class ReadHandler>  void asio_handler_invoke(const F& f,                           bound_read_handler<ReadHandler>* this_handler)  {    using namespace boost::asio;    asio_handler_invoke(f, &this_handler->handler_);  }If the thread that initiates an asynchronous operation terminates before theassociated handler is invoked, the behaviour is implementation-defined.Specifically, on __Windows__ versions prior to Vista, unfinished operations arecancelled when the initiating thread exits.The handler argument to an initiating function defines a handler identity. Thatis, the original handler argument and any copies of the handler argument willbe considered equivalent. If the implementation needs to allocate storage foran asynchronous operation, the implementation will perform`asio_handler_allocate(size, &h)`, where `size` is the required size in bytes,and `h` is the handler. The implementation will perform`asio_handler_deallocate(p, size, &h)`, where `p` is a pointer to the storage,to deallocate the storage prior to the invocation of the handler via`asio_handler_invoke`. Multiple storage blocks may be allocated for a singleasynchronous operation.[endsect]

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?