Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Handler Tracking
3.
Customizing Handler Tracking
3.1.
Implementation
3.1.1.
Explanation
3.1.2.
Output
3.1.3.
Code
3.1.4.
Output
4.
Frequently Asked Questions
4.1.
What is the full form of Asio?
4.2.
What is the use of the Asio library?
4.3.
What is the main use of Handler Tracking?
4.4.
Which macro is used to get the location information?
5.
Conclusion
Last Updated: Mar 27, 2024
Medium

What is Handler Tracking?

Introduction

Do you know that the C++ library Asio provides support for handler tracking? Do you know how handler tracking helps in debugging asynchronous programs?

Introduction to Handler Tracking

In this article, we will discuss about handler tracking. We will also discuss about how we can customize handler tracking using a macro. The interface, features, and behaviour of Asio can all be managed by the macros. In the end, we will make a program to understand handler tracking more clearly.

Also read, Abstract Data Types in C++ and Application of Oops

Handler Tracking

The Asio library supports handler tracking, which helps in debugging asynchronous programs. We can enable handler tracking by defining ASIO_ENABLE_HANDLER_TRACKING in our programs. Handler tracking is used to know about the chaining of asynchronous operations, debugging and also helpful in finding pending asynchronous operations.

What is Handler Tracking?

Customizing Handler Tracking

The handler tracking can also be customized by using a macro to the name of the header file. The macro is ASIO_CUSTOM_HANDLER_TRACKING. 

The header file implements preprocessor macros, which are as follows:

👉 ASIO_INHERIT_TRACKED_HANDLER is used to specify a base class that implements asynchronous operations.

👉 ASIO_HANDLER _TRACKING_INIT is used to initialize the tracking mechanism.

👉 ASIO_HANDLER _LOCATION(args) is used in defining the location of the code. The args is a parenthesized function that contains a file name, line number, and function name as arguments. The parenthesized function means that there are some arguments that has to be written in parenthesis while using a macro.

👉 ASIO_HANDLER_CREATION(args) is an expression that is called whenever an asynchronous operation is created. The args is a parenthesized function that contains execution context, tracked handler, object type name, pointer, native handle, and the operation name.

👉 ASIO_HANDLER_COMPLETION(args) is an expression that is called whenever an asynchronous operation is completed. The args is a parenthesized function that contains a tracked handler.

👉 ASIO_HANDLER_INVOCATION_BEGIN(args) is an expression that is called just before a completion handler is called. The args is a parenthesized function that contains arguments to the completion handlers.

👉 ASIO_HANDLER_INVOCATION_END is an expression that is called just after a completion handler is called.

👉 ASIO_HANDLER_OPERATION(args) is an expression that is called whenever a synchronous object is called. The args is a parenthesized function that contains execution context, object type name, pointer, native handle, and the operation name.

👉 ASIO_HANDLER_REACTOR_REGISTRATION(args) is an expression that is called whenever the object is registered with the reactor. The args is a parenthesized function that contains execution context, native handle, and unique registration key.

👉 ASIO_HANDLER_REACTOR_DEREGISTRATION(args)  is an expression that is called whenever the object is deregistered with the reactor. The args is a parenthesized function that contains execution context, native handle, and unique registration key.

👉 ASIO_HANDLER_REACTOR_READ_EVENT is used to identify reactor read readiness events.

👉 ASIO_HANDLER_REACTOR_WRITE_EVENT is used to identify reactor write readiness events.

👉 ASIO_HANDLER_REACTOR_ERROR_EVENT is used to identify reactor error readiness events.

👉 ASIO_HANDLER_REACTOR_EVENTS(args) is an expression that is called whenever the object is registered with the reactor and becomes ready. The args is a parenthesized function that contains execution context, a unique registration key, and a bitmask of ready events.

👉 ASIO_HANDLER_REACTOR_OPERATION(args) is an expression that is called whenever a system call takes place as a part of a reactor-based asynchronous operation. The args is a parenthesized function that contains tracked handler, operation name, error code, and transferred number of bytes is optional.

Implementation

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <asio.hpp>

using namespace std;
using asio::ip::tcp;

#define HANDLER_LOCATION \
  ASIO_HANDLER_LOCATION((__FILE__, __LINE__, __func__))

class server
{
public:
    server(asio::io_context& io, short port) : acceptor(io, tcp::endpoint(tcp::v4(), port))
    {
        acceptor.async_accept([this](std::error_code ec, tcp::socket socket)
            {
                HANDLER_LOCATION;
            });
        std::cout << "Inside server Constructor." << endl;
    }
    tcp::acceptor acceptor;
};

int main(int argc, char* argv[])
{
    asio::io_context io;
    std::cout << "Tracking Error..." << endl;
    server s(io, std::atoi(argv[1]));
    std::cout << "No Error Tracked." << endl;
    return 0;
}

Explanation

In this program, we made a server class, where we are specifying endpoint. The server uses an endpoint as it specifies the IP address and protocol port that the application wants to listen to. We have used an acceptor socket, the acceptor socket is required to allocate a new socket and bind it to an endpoint that is chosen by the operating system. We are enabling handler tracking inside server constructor. Now, inside the main function we have called our parameterized constructor with wrong arguments so we will receive a debug error message with three options Abort, Retry and Ignore. 

Clicking on Abort and Ignore will exit the code, whereas if we click on the Retry button, it will take us to the breaking point in our code. See the below images for your reference.

Output

Output Screen


After clicking on the Retry button, we will be redirected to the breakpoint.

Redirected to Breakpoint

We can solve this error by passing the correct argument. Currently, we are writing argv[1], which is creating an out-of-bound error. If we try to write an array outside its bounds, then it will end up overwriting the data to other parts of the code and cause errors. So here, if we pass argv[0] then our program will work fine. See the below code for your reference.

Code

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <asio.hpp>
 
using namespace std;
using asio::ip::tcp;
 
#define HANDLER_LOCATION \
  ASIO_HANDLER_LOCATION((__FILE__, __LINE__, __func__))

class server
{
public:
    server(asio::io_context& io, short port) : acceptor(io, tcp::endpoint(tcp::v4(), port))
    {
        acceptor.async_accept([this](std::error_code ec, tcp::socket socket)
            {
                HANDLER_LOCATION;
            });
        std::cout << "Inside server Constructor." << endl;
    }
    tcp::acceptor acceptor;
};

int main(int argc, char* argv[])
{
    asio::io_context io;
    std::cout << "Tracking Error..." << endl;
    server s(io, std::atoi(argv[0]));
    std::cout << "No Error Tracked." << endl;
    return 0;
}

 

Output

Output Screen

Frequently Asked Questions

What is the full form of Asio?

Asio stands for Asynchronous Input Output.

What is the use of the Asio library?

Asio helps in doing network programming using C++ language. It allows the processing of data asynchronously by providing asynchronous I/O models.

What is the main use of Handler Tracking?

Handler Tracking is used for debugging asynchronous programs and finding pending asynchronous operations.

Which macro is used to get the location information?

The macro ASIO_HANDLER_LOCATION is used to get the location information in the source code.

Conclusion

In this article, we have discussed handler tracking. We have discussed how we can customize handler tracking using the ASIO_CUSTOM_HANDLER_TRACKING macro. In the end, we have made a program to better understand handler tracking. To learn more about the Asio library, you can read the below-mentioned articles:

 

We hope this article helped you in understanding handler tracking. You can read more such articles on our platform, Coding Ninjas Studio. You will find articles on almost every topic on our platform. Also, you can practice coding questions at Coding Ninjas to crack good product-based companies. For interview preparations, you can read the Interview Experiences of popular companies.

Happy Coding!

Live masterclass