From 912df3ff3dfde504f4db107966aeb3bcff533a32 Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Sun, 18 Jan 2026 15:25:26 +0400 Subject: [PATCH] Upstream: process exit resolve cleanup. --- .../modules/ngx_http_upstream_zone_module.c | 62 +++++++++++++++++- src/stream/ngx_stream_upstream_zone_module.c | 63 ++++++++++++++++++- 2 files changed, 123 insertions(+), 2 deletions(-) diff --git a/src/http/modules/ngx_http_upstream_zone_module.c b/src/http/modules/ngx_http_upstream_zone_module.c index 2ce8a7b5b..4ad8a6817 100644 --- a/src/http/modules/ngx_http_upstream_zone_module.c +++ b/src/http/modules/ngx_http_upstream_zone_module.c @@ -29,6 +29,7 @@ static void ngx_http_upstream_zone_set_single( static void ngx_http_upstream_zone_remove_peer_locked( ngx_http_upstream_rr_peers_t *peers, ngx_http_upstream_rr_peer_t *peer); static ngx_int_t ngx_http_upstream_zone_init_worker(ngx_cycle_t *cycle); +static void ngx_http_upstream_zone_exit_worker(ngx_cycle_t *cycle); static void ngx_http_upstream_zone_resolve_timer(ngx_event_t *event); static void ngx_http_upstream_zone_resolve_handler(ngx_resolver_ctx_t *ctx); @@ -71,7 +72,7 @@ ngx_module_t ngx_http_upstream_zone_module = { ngx_http_upstream_zone_init_worker, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ - NULL, /* exit process */ + ngx_http_upstream_zone_exit_worker, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; @@ -696,6 +697,65 @@ ngx_http_upstream_zone_init_worker(ngx_cycle_t *cycle) } +static void +ngx_http_upstream_zone_exit_worker(ngx_cycle_t *cycle) +{ + ngx_uint_t i; + ngx_event_t *event; + ngx_http_upstream_rr_peer_t *peer; + ngx_http_upstream_rr_peers_t *peers; + ngx_http_upstream_srv_conf_t *uscf, **uscfp; + ngx_http_upstream_main_conf_t *umcf; + + if (ngx_process != NGX_PROCESS_WORKER + && ngx_process != NGX_PROCESS_SINGLE) + { + return; + } + + umcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_upstream_module); + + if (umcf == NULL) { + return; + } + + uscfp = umcf->upstreams.elts; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + + uscf = uscfp[i]; + + if (uscf->shm_zone == NULL) { + continue; + } + + peers = uscf->peer.data; + + do { + ngx_http_upstream_rr_peers_wlock(peers); + + for (peer = peers->resolve; peer; peer = peer->next) { + + if (peer->host->worker != ngx_worker) { + continue; + } + + event = &peer->host->event; + + if (event->timer_set) { + ngx_del_timer(event); + } + } + + ngx_http_upstream_rr_peers_unlock(peers); + + peers = peers->next; + + } while (peers); + } +} + + static void ngx_http_upstream_zone_resolve_timer(ngx_event_t *event) { diff --git a/src/stream/ngx_stream_upstream_zone_module.c b/src/stream/ngx_stream_upstream_zone_module.c index a6874dc33..d7b6c21c4 100644 --- a/src/stream/ngx_stream_upstream_zone_module.c +++ b/src/stream/ngx_stream_upstream_zone_module.c @@ -29,6 +29,7 @@ static void ngx_stream_upstream_zone_set_single( static void ngx_stream_upstream_zone_remove_peer_locked( ngx_stream_upstream_rr_peers_t *peers, ngx_stream_upstream_rr_peer_t *peer); static ngx_int_t ngx_stream_upstream_zone_init_worker(ngx_cycle_t *cycle); +static void ngx_stream_upstream_zone_exit_worker(ngx_cycle_t *cycle); static void ngx_stream_upstream_zone_resolve_timer(ngx_event_t *event); static void ngx_stream_upstream_zone_resolve_handler(ngx_resolver_ctx_t *ctx); @@ -68,7 +69,7 @@ ngx_module_t ngx_stream_upstream_zone_module = { ngx_stream_upstream_zone_init_worker, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ - NULL, /* exit process */ + ngx_stream_upstream_zone_exit_worker, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; @@ -694,6 +695,66 @@ ngx_stream_upstream_zone_init_worker(ngx_cycle_t *cycle) } +static void +ngx_stream_upstream_zone_exit_worker(ngx_cycle_t *cycle) +{ + ngx_uint_t i; + ngx_event_t *event; + ngx_stream_upstream_rr_peer_t *peer; + ngx_stream_upstream_rr_peers_t *peers; + ngx_stream_upstream_srv_conf_t *uscf, **uscfp; + ngx_stream_upstream_main_conf_t *umcf; + + if (ngx_process != NGX_PROCESS_WORKER + && ngx_process != NGX_PROCESS_SINGLE) + { + return; + } + + umcf = ngx_stream_cycle_get_module_main_conf(cycle, + ngx_stream_upstream_module); + + if (umcf == NULL) { + return; + } + + uscfp = umcf->upstreams.elts; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + + uscf = uscfp[i]; + + if (uscf->shm_zone == NULL) { + continue; + } + + peers = uscf->peer.data; + + do { + ngx_stream_upstream_rr_peers_wlock(peers); + + for (peer = peers->resolve; peer; peer = peer->next) { + + if (peer->host->worker != ngx_worker) { + continue; + } + + event = &peer->host->event; + + if (event->timer_set) { + ngx_del_timer(event); + } + } + + ngx_stream_upstream_rr_peers_unlock(peers); + + peers = peers->next; + + } while (peers); + } +} + + static void ngx_stream_upstream_zone_resolve_timer(ngx_event_t *event) {