mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 10:00:57 +02:00
Merge branch 'fix/http_server_async_requests_on_same_socket_blocks_v5.4' into 'release/v5.4'
Fix async requests on same socket blocking server (v5.4) See merge request espressif/esp-idf!41998
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