PrevUpHomeNext

Executors

Every asynchronous operation has an associated executor that determines how the completion handlers are queued and run. Asynchronous operations use the associated executor to track the existence of the work of asynchronous tasks, schedule the completion handlers for execution, and prevent re-entrant execution of the completion handlers to avoid recursion and potential stack overflow issues.

Every asynchronous operation within the mqtt_client is defined as a composed operation. This implies that each async_xxx operation is a sequence consisting of an initiating function, a series of intermediate asynchronous operations, and a final completion handler.

Upon creating an instance of the mqtt_client, it is necessary to provide an executor or an ExecutionContext. The specified executor (or ExecutionContext's executor) will become the default executor associated with the mqtt_client and will be used for the execution of all the intermediate operations and a final completion handler for all asynchronous operations that have not bound an executor. If an executor is bound to an asynchronous operation, that executor will be used for the final completion handler instead.

The following examples will demonstrate the previously described interactions.

Example: using the constructor's executor as the default associated executor

In this code snippet, the mqtt_client is constructed with a strand. Consequently, the mqtt_client adopts the strand as its new default executor, which is used to execute the mqtt_client::async_publish operation.

int main() {
	boost::asio::io_context ioc;

	// Construct the Client with a strand.
	auto strand = boost::asio::make_strand(ioc.get_executor());
	async_mqtt5::mqtt_client<boost::asio::ip::tcp::socket> client(strand);

	client.brokers("<your-mqtt-broker>", 1883)
		.async_run(boost::asio::detached);

	// This asynchronous operation will use the default associated executor,
	// which is the strand with which the Client is constructed.
	client.async_publish<async_mqtt5::qos_e::at_most_once>(
		"<topic>", "Hello world!",
		async_mqtt5::retain_e::no, async_mqtt5::publish_props {},
		[&client, &strand](async_mqtt5::error_code /* ec */) {
			assert(strand.running_in_this_thread());
			client.cancel();
		}
	);

	ioc.run();
}

PrevUpHomeNext