Blocking or non-blocking API calls

API functions often allow application to set blocking parameter indicating if function shall be blocking or non-blocking.

Blocking mode

When the function is called in blocking mode blocking = 1, application thread gets suspended until response from ESP device is received. If there is a queue of multiple commands, thread may wait a while before receiving data.

When API function returns, application has valid response data and can react immediately.

  • Linear programming model may be used

  • Application may use multiple threads for real-time execution to prevent system stalling when running function call

Warning

Due to internal architecture, it is not allowed to call API functions in blocking mode from events or callbacks. Any attempt to do so will result in function returning error.

Example code:

Blocking command example
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
char hostname[20];

/* Somewhere in thread function */

/* Get device hostname in blocking mode */
/* Function returns actual result */
if (lwesp_hostname_get(hostname, sizeof(hostname), NULL, NULL, 1 /* 1 means blocking call */) == lwespOK) {
    /* At this point we have valid result and parameters from API function */
    printf("ESP hostname is %s\r\n", hostname);
} else {
    printf("Error reading ESP hostname..\r\n");
}

Non-blocking mode

If the API function is called in non-blocking mode, function will return immediately with status indicating if command request has been successfully sent to internal command queue. Response has to be processed in event callback function.

Warning

Due to internal architecture, it is only allowed to call API functions in non-blocking mode from events or callbacks. Any attempt to do so will result in function returning error.

Example code:

Non-blocking command example
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
char hostname[20];

/* Hostname event function, called when lwesp_hostname_get() function finishes */
void
hostname_fn(lwespr_t res, void* arg) {
    /* Check actual result from device */
    if (res == lwespOK) {
        printf("ESP hostname is %s\r\n", hostname);
    } else {
        printf("Error reading ESP hostname...\r\n");
    }
}

/* Somewhere in thread and/or other ESP event function */

/* Get device hostname in non-blocking mode */
/* Function now returns if command has been sent to internal message queue */
if (lwesp_hostname_get(hostname, sizeof(hostname), hostname_fn, NULL, 0 /* 0 means non-blocking call */) == lwespOK) {
    /* At this point application knows that command has been sent to queue */
    /* But it does not have yet valid data in "hostname" variable */
    printf("ESP hostname get command sent to queue.\r\n");
} else {
    /* Error writing message to queue */
    printf("Cannot send hostname get command to queue.\r\n");
}

Warning

When using non-blocking API calls, do not use local variables as parameter. This may introduce undefined behavior and memory corruption if application function returns before command is executed.

Example of a bad code:

Example of bad usage of non-blocking command
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
char hostname[20];

/* Hostname event function, called when lwesp_hostname_get() function finishes */
void
hostname_fn(lwespr_t res, void* arg) {
    /* Check actual result from device */
    if (res == lwespOK) {
        printf("ESP hostname is %s\r\n", hostname);
    } else {
        printf("Error reading ESP hostname...\r\n");
    }
}

/* Check hostname */
void
check_hostname(void) {
    char hostname[20];

    /* Somewhere in thread and/or other ESP event function */

    /* Get device hostname in non-blocking mode */
    /* Function now returns if command has been sent to internal message queue */
    /* Function will use local "hostname" variable and will write to undefined memory */
    if (lwesp_hostname_get(hostname, sizeof(hostname), hostname_fn, NULL, 0 /* 0 means non-blocking call */) == lwespOK) {
        /* At this point application knows that command has been sent to queue */
        /* But it does not have yet valid data in "hostname" variable */
        printf("ESP hostname get command sent to queue.\r\n");
    } else {
        /* Error writing message to queue */
        printf("Cannot send hostname get command to queue.\r\n");
    }
}