From 771b6fbda1c988e8be722f0761757072ec89d6bb Mon Sep 17 00:00:00 2001 From: Denis Vaksman Date: Fri, 1 Sep 2023 16:50:47 +0300 Subject: [PATCH] fix curl resumable epoll related crash --- runtime/curl.cpp | 9 +++++++++ server/php-worker.cpp | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/runtime/curl.cpp b/runtime/curl.cpp index 5017b244c0..60f6316e24 100644 --- a/runtime/curl.cpp +++ b/runtime/curl.cpp @@ -1129,6 +1129,15 @@ void CurlRequest::detach_multi_and_easy_handles() const noexcept { } static int curl_epoll_cb(int fd, void *data, event_t *ev) { + // Sometimes epoll callbacks can be invoked AFTER the related 'fd' is removed from epoll. + // It happens because our net_reactor at first stores epoll events from epoll_wait, and only then runs related callbacks (see epoll_fetch_events()) + // Usually this situation is handled via some additional connection flags (conn_expect_query, C_WANTRD etc.) + // in callbacks like `server_read_write_gateway` and related. + // But here we try to keep it simple and not to do all of this stuff. + // So we need to check explicitly that this fd is still present in epoll reactor: + if (!(ev->state & EVT_IN_EPOLL)) { + return 0; + } auto *curl_request = static_cast(data); php_assert(curl_request); diff --git a/server/php-worker.cpp b/server/php-worker.cpp index 47c882d1f5..55a667db99 100644 --- a/server/php-worker.cpp +++ b/server/php-worker.cpp @@ -234,7 +234,11 @@ void PhpWorker::state_run() noexcept { tvkprintf(php_runner, 3, "PHP-worker before swap context [req_id = %016llx]\n", req_id); php_script->iterate(); tvkprintf(php_runner, 3, "PHP-worker after swap context [req_id = %016llx]\n", req_id);; - wait(0); // check for net events + if (php_script->state != run_state_t::finished) { + // We don't need to check net events when the script is going to finish. + // Otherwise we can fetch some net events related to this script that will be processed after the script termination. + wait(0); + } break; } case run_state_t::query: {