c-programming

What is the callback function?

A callback function is a function you provide to another function, allowing it to be called by another function.

Callbacks are most easily described in terms of the telephone system. A function call is analogous to calling someone on a telephone, asking her a question, getting an answer, and hanging up; adding a callback changes the analogy so that after asking her a question, you also give her your name and number so she can call you back with the answer.

-- Paul Jakubik, "Callback Implementations in C++"

The callback is highly used in the event-driven design where the asynchronous notification can be sent to another process. For example, you need a notification whenever a USB is inserted into the system or removed from the system without blocking your current task. You want to enable the copy operation if the USB is plugged in or you want to stop the copy operation and notify the user if the USB is removed from the system. In order to achieve the above design one can write the main function for copy operation and error notification to the user and same time, a thread can be created which will keep on checking the status of the USB. In the thread, upon ADD/REMOVE event of USB, it can call the callback function which will allow the main process to do the desired operation.

At the system level, a signal handler works with the concept of callback functions.

Let’s understand this one simple example. Notify the main process whenever a number is completely divisible by 10.

counter_thread.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <limits.h>

typedef void (*fptr_callback)(int);

typedef struct callback_meta
{
    fptr_callback callback;
} callback_meta;

void *callback_thread(void *cbm)
{
    int l_data = 0;
    callback_meta* cb_meta = (callback_meta*)cbm;

    while (1)
    {
        printf("CallBack Job Running!! \n");
        usleep(10);
        l_data++;
        if(l_data % 10 == 0)
        {
            //Notify callback
            cb_meta->callback(l_data);
        }
        if(l_data == INT_MAX)
        {
            l_data = 0;
        }
    }
}

extern void create_call_back_thread(pthread_t *pthread_id, fptr_callback callback_fun)
{
    printf("In- create_call_back_thread \n");

    callback_meta *cbm = malloc(sizeof(callback_meta));
    cbm->callback = callback_fun;

    pthread_create(pthread_id, NULL, callback_thread, (void *)cbm);
    
    printf("Out- create_call_back_thread \n");
}

main.c

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void on_value_divided_by_ten(int val)
{
    printf("This value is divided by 10 (%d).\n", val);
}

int main()
{
    printf("In Main ---\n");

    int x = 10;
    pthread_t update_thread;

    // Creating a callback function - which will call on_value_divided_by_ten.
    create_call_back_thread(&update_thread, on_value_divided_by_ten);

    while(1)
    {
        usleep(100);
        printf("Some other job is running\n");
    }

    pthread_join(update_thread, NULL);
    return 0;
} 

Output

Spread the love

Rohit

I am a software developer by profession. I love coding and learning new skills.

Leave a Reply

Your email address will not be published. Required fields are marked *