mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 18:10:57 +02:00
fix(esp_http_server): Fix async requests on same socket blocking issue
1. In async requests, if the two or more requests are made on same socket then it used to block the second request. 2. The main thread is used to block on select call. And there done no FD_SET for particular fd. Closes https://github.com/espressif/esp-idf/issues/16998
This commit is contained in:
@@ -41,6 +41,19 @@ extern "C" {
|
||||
/* Formats a log string to prepend context function name */
|
||||
#define LOG_FMT(x) "%s: " x, __func__
|
||||
|
||||
/**
|
||||
* @brief Control message data structure for internal use. Sent to control socket.
|
||||
*/
|
||||
struct httpd_ctrl_data {
|
||||
enum httpd_ctrl_msg {
|
||||
HTTPD_CTRL_SHUTDOWN,
|
||||
HTTPD_CTRL_WORK,
|
||||
HTTPD_CTRL_MAX,
|
||||
} hc_msg;
|
||||
httpd_work_fn_t hc_work;
|
||||
void *hc_work_arg;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Thread related data for internal use
|
||||
*/
|
||||
|
@@ -133,15 +133,6 @@ exit:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
struct httpd_ctrl_data {
|
||||
enum httpd_ctrl_msg {
|
||||
HTTPD_CTRL_SHUTDOWN,
|
||||
HTTPD_CTRL_WORK,
|
||||
} hc_msg;
|
||||
httpd_work_fn_t hc_work;
|
||||
void *hc_work_arg;
|
||||
};
|
||||
|
||||
esp_err_t httpd_queue_work(httpd_handle_t handle, httpd_work_fn_t work, void *arg)
|
||||
{
|
||||
if (handle == NULL || work == NULL) {
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include <esp_http_server.h>
|
||||
#include "esp_httpd_priv.h"
|
||||
#include <netinet/tcp.h>
|
||||
#include "ctrl_sock.h"
|
||||
|
||||
static const char *TAG = "httpd_txrx";
|
||||
|
||||
@@ -655,6 +656,11 @@ esp_err_t httpd_req_async_handler_complete(httpd_req_t *r)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Get server handle and control socket info before freeing the request
|
||||
struct httpd_data *hd = (struct httpd_data *) r->handle;
|
||||
int msg_fd = hd->msg_fd;
|
||||
int port = hd->config.ctrl_port;
|
||||
|
||||
struct httpd_req_aux *ra = r->aux;
|
||||
ra->sd->for_async_req = false;
|
||||
|
||||
@@ -662,6 +668,18 @@ esp_err_t httpd_req_async_handler_complete(httpd_req_t *r)
|
||||
free(r->aux);
|
||||
free(r);
|
||||
|
||||
// Send a dummy control message(httpd_ctrl_data) to unblock the main HTTP server task from the select() call.
|
||||
// Since the current connection FD was marked as inactive for async requests, the main task
|
||||
// will now re-add this FD to its select() descriptor list. This ensures that subsequent requests
|
||||
// on the same FD are processed correctly
|
||||
struct httpd_ctrl_data msg = {.hc_msg = HTTPD_CTRL_MAX};
|
||||
int ret = cs_send_to_ctrl_sock(msg_fd, port, &msg, sizeof(msg));
|
||||
if (ret < 0) {
|
||||
ESP_LOGW(TAG, LOG_FMT("failed to send socket notification"));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, LOG_FMT("socket notification sent"));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user