Mercurial > hg > nginx-quic
annotate src/event/ngx_event_timer.c @ 8867:5119c8150478
Fixed runtime handling of systems without EPOLLRDHUP support.
In 7583:efd71d49bde0 (nginx 1.17.5) along with introduction of the
ioctl(FIONREAD) support proper handling of systems without EPOLLRDHUP
support in the kernel (but with EPOLLRDHUP in headers) was broken.
Before the change, rev->available was never set to 0 unless
ngx_use_epoll_rdhup was also set (that is, runtime test for EPOLLRDHUP
introduced in 6536:f7849bfb6d21 succeeded). After the change,
rev->available might reach 0 on systems without runtime EPOLLRDHUP
support, stopping further reading in ngx_readv_chain() and ngx_unix_recv().
And, if EOF happened to be already reported along with the last event,
it is not reported again by epoll_wait(), leading to connection hangs
and timeouts on such systems.
This affects Linux kernels before 2.6.17 if nginx was compiled
with newer headers, and, more importantly, emulation layers, such as
DigitalOcean's App Platform's / gVisor's epoll emulation layer.
Fix is to explicitly check ngx_use_epoll_rdhup before the corresponding
rev->pending_eof tests in ngx_readv_chain() and ngx_unix_recv().
author | Marcus Ball <marcus.ball@live.com> |
---|---|
date | Mon, 30 May 2022 02:38:07 +0300 |
parents | 0c5e84096d99 |
children |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
381
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
381
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
4412 | 4 * Copyright (C) Nginx, Inc. |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
381
diff
changeset
|
5 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
381
diff
changeset
|
6 |
50
b288069a8696
nginx-0.0.1-2003-01-23-21:47:54 import
Igor Sysoev <igor@sysoev.ru>
parents:
49
diff
changeset
|
7 |
b288069a8696
nginx-0.0.1-2003-01-23-21:47:54 import
Igor Sysoev <igor@sysoev.ru>
parents:
49
diff
changeset
|
8 #include <ngx_config.h> |
b288069a8696
nginx-0.0.1-2003-01-23-21:47:54 import
Igor Sysoev <igor@sysoev.ru>
parents:
49
diff
changeset
|
9 #include <ngx_core.h> |
b288069a8696
nginx-0.0.1-2003-01-23-21:47:54 import
Igor Sysoev <igor@sysoev.ru>
parents:
49
diff
changeset
|
10 #include <ngx_event.h> |
b288069a8696
nginx-0.0.1-2003-01-23-21:47:54 import
Igor Sysoev <igor@sysoev.ru>
parents:
49
diff
changeset
|
11 |
b288069a8696
nginx-0.0.1-2003-01-23-21:47:54 import
Igor Sysoev <igor@sysoev.ru>
parents:
49
diff
changeset
|
12 |
5894
1f513d7f1b45
Events: removed broken thread support from event timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5820
diff
changeset
|
13 ngx_rbtree_t ngx_event_timer_rbtree; |
1f513d7f1b45
Events: removed broken thread support from event timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5820
diff
changeset
|
14 static ngx_rbtree_node_t ngx_event_timer_sentinel; |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
15 |
1022 | 16 /* |
17 * the event timer rbtree may contain the duplicate keys, however, | |
18 * it should not be a problem, because we use the rbtree to find | |
19 * a minimum timer value only | |
20 */ | |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
21 |
493 | 22 ngx_int_t |
23 ngx_event_timer_init(ngx_log_t *log) | |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
24 { |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1022
diff
changeset
|
25 ngx_rbtree_init(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel, |
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1022
diff
changeset
|
26 ngx_rbtree_insert_timer_value); |
559 | 27 |
270
7bb9562216ce
nginx-0.0.2-2004-02-25-23:16:15 import
Igor Sysoev <igor@sysoev.ru>
parents:
266
diff
changeset
|
28 return NGX_OK; |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
29 } |
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
30 |
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
31 |
493 | 32 ngx_msec_t |
33 ngx_event_find_timer(void) | |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
34 { |
561 | 35 ngx_msec_int_t timer; |
36 ngx_rbtree_node_t *node, *root, *sentinel; | |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
37 |
559 | 38 if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) { |
316
a0beefedaf94
nginx-0.0.3-2004-04-15-00:34:05 import
Igor Sysoev <igor@sysoev.ru>
parents:
315
diff
changeset
|
39 return NGX_TIMER_INFINITE; |
213
f536f91e8e99
nginx-0.0.1-2003-12-19-15:45:27 import
Igor Sysoev <igor@sysoev.ru>
parents:
212
diff
changeset
|
40 } |
f536f91e8e99
nginx-0.0.1-2003-12-19-15:45:27 import
Igor Sysoev <igor@sysoev.ru>
parents:
212
diff
changeset
|
41 |
559 | 42 root = ngx_event_timer_rbtree.root; |
43 sentinel = ngx_event_timer_rbtree.sentinel; | |
44 | |
45 node = ngx_rbtree_min(root, sentinel); | |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
46 |
4576
876e6b0814a5
Fixed signed integer overflows in timer code (ticket #145).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
47 timer = (ngx_msec_int_t) (node->key - ngx_current_msec); |
315
39b6f2df45c0
nginx-0.0.3-2004-04-14-21:44:28 import
Igor Sysoev <igor@sysoev.ru>
parents:
306
diff
changeset
|
48 |
559 | 49 return (ngx_msec_t) (timer > 0 ? timer : 0); |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
50 } |
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
51 |
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
52 |
493 | 53 void |
557 | 54 ngx_event_expire_timers(void) |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
55 { |
559 | 56 ngx_event_t *ev; |
57 ngx_rbtree_node_t *node, *root, *sentinel; | |
58 | |
59 sentinel = ngx_event_timer_rbtree.sentinel; | |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
60 |
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
61 for ( ;; ) { |
559 | 62 root = ngx_event_timer_rbtree.root; |
63 | |
64 if (root == sentinel) { | |
65 return; | |
66 } | |
67 | |
68 node = ngx_rbtree_min(root, sentinel); | |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
69 |
6935 | 70 /* node->key > ngx_current_msec */ |
557 | 71 |
5895
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
72 if ((ngx_msec_int_t) (node->key - ngx_current_msec) > 0) { |
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
73 return; |
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
74 } |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
75 |
8523
0c5e84096d99
Core: added the ngx_rbtree_data() macro.
Vladimir Homutov <vl@nginx.com>
parents:
6935
diff
changeset
|
76 ev = ngx_rbtree_data(node, ngx_event_t, timer); |
371
780e93985b93
nginx-0.0.7-2004-06-28-20:05:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
361
diff
changeset
|
77 |
5895
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
78 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, |
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
79 "event timer del: %d: %M", |
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
80 ngx_event_ident(ev->data), ev->timer.key); |
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
81 |
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
82 ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
83 |
371
780e93985b93
nginx-0.0.7-2004-06-28-20:05:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
361
diff
changeset
|
84 #if (NGX_DEBUG) |
5895
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
85 ev->timer.left = NULL; |
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
86 ev->timer.right = NULL; |
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
87 ev->timer.parent = NULL; |
371
780e93985b93
nginx-0.0.7-2004-06-28-20:05:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
361
diff
changeset
|
88 #endif |
780e93985b93
nginx-0.0.7-2004-06-28-20:05:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
361
diff
changeset
|
89 |
5895
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
90 ev->timer_set = 0; |
374
213f17e9f776
nginx-0.0.7-2004-07-02-09:47:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
372
diff
changeset
|
91 |
5895
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
92 ev->timedout = 1; |
374
213f17e9f776
nginx-0.0.7-2004-07-02-09:47:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
372
diff
changeset
|
93 |
5895
0f53e5fb7205
Events: simplified cycle in ngx_event_expire_timers().
Valentin Bartenev <vbart@nginx.com>
parents:
5894
diff
changeset
|
94 ev->handler(ev); |
205
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
95 } |
4a9a2b1dd6fa
nginx-0.0.1-2003-12-04-17:53:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
96 } |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
97 |
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
98 |
6929
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
99 ngx_int_t |
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
100 ngx_event_no_timers_left(void) |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
101 { |
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
102 ngx_event_t *ev; |
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
103 ngx_rbtree_node_t *node, *root, *sentinel; |
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
104 |
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
105 sentinel = ngx_event_timer_rbtree.sentinel; |
6929
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
106 root = ngx_event_timer_rbtree.root; |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
107 |
6929
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
108 if (root == sentinel) { |
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
109 return NGX_OK; |
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
110 } |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
111 |
6929
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
112 for (node = ngx_rbtree_min(root, sentinel); |
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
113 node; |
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
114 node = ngx_rbtree_next(&ngx_event_timer_rbtree, node)) |
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
115 { |
8523
0c5e84096d99
Core: added the ngx_rbtree_data() macro.
Vladimir Homutov <vl@nginx.com>
parents:
6935
diff
changeset
|
116 ev = ngx_rbtree_data(node, ngx_event_t, timer); |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
117 |
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
118 if (!ev->cancelable) { |
6929
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
119 return NGX_AGAIN; |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
120 } |
6929
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
121 } |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
122 |
6929
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
123 /* only cancelable timers left */ |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
124 |
6929
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5896
diff
changeset
|
125 return NGX_OK; |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5895
diff
changeset
|
126 } |