Skip to content

Commit

Permalink
Connections now support immediate executors
Browse files Browse the repository at this point in the history
Immediate completions in connection and any_connection are now correctly
    dispatched to the token's immediate executor using asio::async_immediate
    instead of plain asio::post.
Added a section on executors in the reference docs of async functions in
    connection and any_connection
Disabled TSAN connection_pool_cancel_get_connection for libc++ builds

close #301
  • Loading branch information
anarthal authored Oct 3, 2024
1 parent 7ef6ff8 commit 268aa33
Show file tree
Hide file tree
Showing 9 changed files with 339 additions and 13 deletions.
70 changes: 70 additions & 0 deletions include/boost/mysql/any_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,16 @@ class any_connection
*
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code))
Expand Down Expand Up @@ -751,6 +761,16 @@ class any_connection
* The handler signature for this operation is
* `void(boost::mysql::error_code, std::size_t)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*
* \par Object lifetimes
* The storage that `output` references must be kept alive until the operation completes.
*/
Expand Down Expand Up @@ -799,6 +819,16 @@ class any_connection
* The handler signature for this operation is
* `void(boost::mysql::error_code, std::size_t)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*
* \par Object lifetimes
* The storage that `output` references must be kept alive until the operation completes.
*/
Expand Down Expand Up @@ -903,6 +933,16 @@ class any_connection
* \n
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
Expand Down Expand Up @@ -1017,6 +1057,16 @@ class any_connection
* \n
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
Expand Down Expand Up @@ -1076,6 +1126,16 @@ class any_connection
* \details
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code))
Expand Down Expand Up @@ -1143,6 +1203,16 @@ class any_connection
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*
* \par Object lifetimes
* The request and response objects must be kept alive and should not be modified
* until the operation completes.
Expand Down
140 changes: 140 additions & 0 deletions include/boost/mysql/connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,16 @@ class connection
*
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <
typename EndpointType,
Expand Down Expand Up @@ -322,6 +332,16 @@ class connection
*
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
Expand Down Expand Up @@ -393,6 +413,16 @@ class connection
*
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <
BOOST_MYSQL_EXECUTION_REQUEST ExecutionRequest,
Expand Down Expand Up @@ -495,6 +525,16 @@ class connection
*
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <
BOOST_MYSQL_EXECUTION_REQUEST ExecutionRequest,
Expand Down Expand Up @@ -576,6 +616,16 @@ class connection
*
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code, boost::mysql::statement)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::statement))
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
Expand Down Expand Up @@ -633,6 +683,16 @@ class connection
*
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
Expand Down Expand Up @@ -693,6 +753,16 @@ class connection
* \par Handler signature
* The handler signature for this operation is
* `void(boost::mysql::error_code, boost::mysql::rows_view)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::rows_view))
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
Expand Down Expand Up @@ -828,6 +898,16 @@ class connection
* The handler signature for this operation is
* `void(boost::mysql::error_code, std::size_t)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*
* \par Object lifetimes
* The storage that `output` references must be kept alive until the operation completes.
*/
Expand Down Expand Up @@ -878,6 +958,16 @@ class connection
* The handler signature for this operation is
* `void(boost::mysql::error_code, std::size_t)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*
* \par Object lifetimes
* The storage that `output` references must be kept alive until the operation completes.
*/
Expand Down Expand Up @@ -943,6 +1033,16 @@ class connection
* \par Handler signature
* The handler signature for this operation is
* `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <
BOOST_MYSQL_EXECUTION_STATE_TYPE ExecutionStateType,
Expand Down Expand Up @@ -999,6 +1099,16 @@ class connection
* \n
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
Expand Down Expand Up @@ -1071,6 +1181,16 @@ class connection
* \n
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
Expand Down Expand Up @@ -1128,6 +1248,16 @@ class connection
* \details
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
Expand Down Expand Up @@ -1186,6 +1316,16 @@ class connection
* \details
* \par Handler signature
* The handler signature for this operation is `void(boost::mysql::error_code)`.
*
* \par Executor
* Intermediate completion handlers, as well as the final handler, are executed using
* `token`'s associated executor, or `this->get_executor()` if the token doesn't have an associated
* executor.
*
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
*/
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
Expand Down
3 changes: 2 additions & 1 deletion include/boost/mysql/detail/engine_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <boost/asio/any_io_executor.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/compose.hpp>
#include <boost/asio/immediate.hpp>
#include <boost/asio/post.hpp>
#include <boost/assert.hpp>

Expand Down Expand Up @@ -66,7 +67,7 @@ struct run_algo_op
BOOST_MYSQL_YIELD(
resume_point_,
1,
asio::post(stream_.get_executor(), std::move(self))
asio::async_immediate(stream_.get_executor(), std::move(self))
)
}
self.complete(stored_ec_);
Expand Down
Loading

0 comments on commit 268aa33

Please sign in to comment.