Mercurial > hg > nginx-quic
comparison src/http/ngx_http_upstream.c @ 2386:4ccaa42de633
use already available r and u instead of ev
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 09 Dec 2008 17:25:03 +0000 |
parents | 3d7a70173d77 |
children | dbe746851b31 |
comparison
equal
deleted
inserted
replaced
2385:3b89b17bcd9c | 2386:4ccaa42de633 |
---|---|
18 ngx_http_upstream_t *u); | 18 ngx_http_upstream_t *u); |
19 static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r, | 19 static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r, |
20 ngx_http_upstream_t *u); | 20 ngx_http_upstream_t *u); |
21 static void ngx_http_upstream_send_request(ngx_http_request_t *r, | 21 static void ngx_http_upstream_send_request(ngx_http_request_t *r, |
22 ngx_http_upstream_t *u); | 22 ngx_http_upstream_t *u); |
23 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); | 23 static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r, |
24 static void ngx_http_upstream_process_header(ngx_event_t *rev); | 24 ngx_http_upstream_t *u); |
25 static void ngx_http_upstream_process_header(ngx_http_request_t *r, | |
26 ngx_http_upstream_t *u); | |
25 static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r, | 27 static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r, |
26 ngx_http_upstream_t *u); | 28 ngx_http_upstream_t *u); |
27 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r, | 29 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r, |
28 ngx_http_upstream_t *u); | 30 ngx_http_upstream_t *u); |
29 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c); | 31 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c); |
30 static void ngx_http_upstream_process_body_in_memory(ngx_event_t *rev); | 32 static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r, |
33 ngx_http_upstream_t *u); | |
31 static void ngx_http_upstream_send_response(ngx_http_request_t *r, | 34 static void ngx_http_upstream_send_response(ngx_http_request_t *r, |
32 ngx_http_upstream_t *u); | 35 ngx_http_upstream_t *u); |
33 static void | 36 static void |
34 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r); | 37 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r); |
35 static void ngx_http_upstream_process_non_buffered_upstream(ngx_event_t *ev); | 38 static void |
39 ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r, | |
40 ngx_http_upstream_t *u); | |
36 static void | 41 static void |
37 ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, | 42 ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, |
38 ngx_uint_t do_write); | 43 ngx_uint_t do_write); |
39 static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data); | 44 static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data); |
40 static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data, | 45 static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data, |
41 ssize_t bytes); | 46 ssize_t bytes); |
42 static void ngx_http_upstream_process_downstream(ngx_http_request_t *r); | 47 static void ngx_http_upstream_process_downstream(ngx_http_request_t *r); |
43 static void ngx_http_upstream_process_upstream(ngx_event_t *rev); | 48 static void ngx_http_upstream_process_upstream(ngx_http_request_t *r, |
49 ngx_http_upstream_t *u); | |
44 static void ngx_http_upstream_process_request(ngx_http_request_t *r); | 50 static void ngx_http_upstream_process_request(ngx_http_request_t *r); |
45 static void ngx_http_upstream_store(ngx_http_request_t *r, | 51 static void ngx_http_upstream_store(ngx_http_request_t *r, |
46 ngx_http_upstream_t *u); | 52 ngx_http_upstream_t *u); |
47 static void ngx_http_upstream_dummy_handler(ngx_event_t *wev); | 53 static void ngx_http_upstream_dummy_handler(ngx_http_request_t *r, |
54 ngx_http_upstream_t *u); | |
48 static void ngx_http_upstream_next(ngx_http_request_t *r, | 55 static void ngx_http_upstream_next(ngx_http_request_t *r, |
49 ngx_http_upstream_t *u, ngx_uint_t ft_type); | 56 ngx_http_upstream_t *u, ngx_uint_t ft_type); |
50 static void ngx_http_upstream_cleanup(void *data); | 57 static void ngx_http_upstream_cleanup(void *data); |
51 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, | 58 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, |
52 ngx_http_upstream_t *u, ngx_int_t rc); | 59 ngx_http_upstream_t *u, ngx_int_t rc); |
536 | 543 |
537 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | 544 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
538 "http upstream request: \"%V?%V\"", &r->uri, &r->args); | 545 "http upstream request: \"%V?%V\"", &r->uri, &r->args); |
539 | 546 |
540 if (ev->write) { | 547 if (ev->write) { |
541 u->write_event_handler(ev); | 548 u->write_event_handler(r, u); |
542 | 549 |
543 } else { | 550 } else { |
544 u->read_event_handler(ev); | 551 u->read_event_handler(r, u); |
545 } | 552 } |
546 | 553 |
547 ngx_http_run_posted_requests(c); | 554 ngx_http_run_posted_requests(c); |
548 } | 555 } |
549 | 556 |
994 } | 1001 } |
995 | 1002 |
996 if (rc == NGX_AGAIN) { | 1003 if (rc == NGX_AGAIN) { |
997 ngx_add_timer(c->write, u->conf->send_timeout); | 1004 ngx_add_timer(c->write, u->conf->send_timeout); |
998 | 1005 |
999 if (ngx_handle_write_event(c->write, u->conf->send_lowat) == NGX_ERROR) | 1006 if (ngx_handle_write_event(c->write, u->conf->send_lowat) != NGX_OK) { |
1000 { | |
1001 ngx_http_upstream_finalize_request(r, u, | 1007 ngx_http_upstream_finalize_request(r, u, |
1002 NGX_HTTP_INTERNAL_SERVER_ERROR); | 1008 NGX_HTTP_INTERNAL_SERVER_ERROR); |
1003 return; | 1009 return; |
1004 } | 1010 } |
1005 | 1011 |
1032 * although we can post aio operation just in the end | 1038 * although we can post aio operation just in the end |
1033 * of ngx_http_upstream_connect() CHECK IT !!! | 1039 * of ngx_http_upstream_connect() CHECK IT !!! |
1034 * it's better to do here because we postpone header buffer allocation | 1040 * it's better to do here because we postpone header buffer allocation |
1035 */ | 1041 */ |
1036 | 1042 |
1037 ngx_http_upstream_process_header(c->read); | 1043 ngx_http_upstream_process_header(r, u); |
1038 return; | 1044 return; |
1039 } | 1045 } |
1040 #endif | 1046 #endif |
1041 | 1047 |
1042 u->write_event_handler = ngx_http_upstream_dummy_handler; | 1048 u->write_event_handler = ngx_http_upstream_dummy_handler; |
1043 | 1049 |
1044 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | 1050 if (ngx_handle_write_event(c->write, 0) != NGX_OK) { |
1045 ngx_http_upstream_finalize_request(r, u, | 1051 ngx_http_upstream_finalize_request(r, u, |
1046 NGX_HTTP_INTERNAL_SERVER_ERROR); | 1052 NGX_HTTP_INTERNAL_SERVER_ERROR); |
1047 return; | 1053 return; |
1048 } | 1054 } |
1049 } | 1055 } |
1050 | 1056 |
1051 | 1057 |
1052 static void | 1058 static void |
1053 ngx_http_upstream_send_request_handler(ngx_event_t *wev) | 1059 ngx_http_upstream_send_request_handler(ngx_http_request_t *r, |
1054 { | 1060 ngx_http_upstream_t *u) |
1055 ngx_connection_t *c; | 1061 { |
1056 ngx_http_request_t *r; | 1062 ngx_connection_t *c; |
1057 ngx_http_upstream_t *u; | 1063 |
1058 | 1064 c = u->peer.connection; |
1059 c = wev->data; | 1065 |
1060 r = c->data; | 1066 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1061 u = r->upstream; | |
1062 | |
1063 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, | |
1064 "http upstream send request handler"); | 1067 "http upstream send request handler"); |
1065 | 1068 |
1066 if (wev->timedout) { | 1069 if (c->write->timedout) { |
1067 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); | 1070 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); |
1068 return; | 1071 return; |
1069 } | 1072 } |
1070 | 1073 |
1071 #if (NGX_HTTP_SSL) | 1074 #if (NGX_HTTP_SSL) |
1078 #endif | 1081 #endif |
1079 | 1082 |
1080 if (u->header_sent) { | 1083 if (u->header_sent) { |
1081 u->write_event_handler = ngx_http_upstream_dummy_handler; | 1084 u->write_event_handler = ngx_http_upstream_dummy_handler; |
1082 | 1085 |
1083 (void) ngx_handle_write_event(wev, 0); | 1086 (void) ngx_handle_write_event(c->write, 0); |
1084 | 1087 |
1085 return; | 1088 return; |
1086 } | 1089 } |
1087 | 1090 |
1088 ngx_http_upstream_send_request(r, u); | 1091 ngx_http_upstream_send_request(r, u); |
1089 } | 1092 } |
1090 | 1093 |
1091 | 1094 |
1092 static void | 1095 static void |
1093 ngx_http_upstream_process_header(ngx_event_t *rev) | 1096 ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u) |
1094 { | 1097 { |
1095 ssize_t n; | 1098 ssize_t n; |
1096 ngx_int_t rc; | 1099 ngx_int_t rc; |
1097 ngx_str_t *uri, args; | 1100 ngx_str_t *uri, args; |
1098 ngx_uint_t i, flags; | 1101 ngx_uint_t i, flags; |
1099 ngx_list_part_t *part; | 1102 ngx_list_part_t *part; |
1100 ngx_table_elt_t *h; | 1103 ngx_table_elt_t *h; |
1101 ngx_connection_t *c; | 1104 ngx_connection_t *c; |
1102 ngx_http_request_t *r; | |
1103 ngx_http_upstream_t *u; | |
1104 ngx_http_upstream_header_t *hh; | 1105 ngx_http_upstream_header_t *hh; |
1105 ngx_http_upstream_main_conf_t *umcf; | 1106 ngx_http_upstream_main_conf_t *umcf; |
1106 | 1107 |
1107 c = rev->data; | 1108 c = u->peer.connection; |
1108 r = c->data; | 1109 |
1109 u = r->upstream; | 1110 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1110 | |
1111 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
1112 "http upstream process header"); | 1111 "http upstream process header"); |
1113 | 1112 |
1114 c->log->action = "reading response header from upstream"; | 1113 c->log->action = "reading response header from upstream"; |
1115 | 1114 |
1116 if (rev->timedout) { | 1115 if (c->read->timedout) { |
1117 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); | 1116 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); |
1118 return; | 1117 return; |
1119 } | 1118 } |
1120 | 1119 |
1121 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { | 1120 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { |
1162 if (n == NGX_AGAIN) { | 1161 if (n == NGX_AGAIN) { |
1163 #if 0 | 1162 #if 0 |
1164 ngx_add_timer(rev, u->read_timeout); | 1163 ngx_add_timer(rev, u->read_timeout); |
1165 #endif | 1164 #endif |
1166 | 1165 |
1167 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { | 1166 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
1168 ngx_http_upstream_finalize_request(r, u, | 1167 ngx_http_upstream_finalize_request(r, u, |
1169 NGX_HTTP_INTERNAL_SERVER_ERROR); | 1168 NGX_HTTP_INTERNAL_SERVER_ERROR); |
1170 return; | 1169 return; |
1171 } | 1170 } |
1172 | 1171 |
1173 return; | 1172 return; |
1174 } | 1173 } |
1175 | 1174 |
1176 if (n == 0) { | 1175 if (n == 0) { |
1177 ngx_log_error(NGX_LOG_ERR, rev->log, 0, | 1176 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
1178 "upstream prematurely closed connection"); | 1177 "upstream prematurely closed connection"); |
1179 } | 1178 } |
1180 | 1179 |
1181 if (n == NGX_ERROR || n == 0) { | 1180 if (n == NGX_ERROR || n == 0) { |
1182 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); | 1181 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); |
1194 rc = u->process_header(r); | 1193 rc = u->process_header(r); |
1195 | 1194 |
1196 if (rc == NGX_AGAIN) { | 1195 if (rc == NGX_AGAIN) { |
1197 | 1196 |
1198 if (u->buffer.pos == u->buffer.end) { | 1197 if (u->buffer.pos == u->buffer.end) { |
1199 ngx_log_error(NGX_LOG_ERR, rev->log, 0, | 1198 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
1200 "upstream sent too big header"); | 1199 "upstream sent too big header"); |
1201 | 1200 |
1202 ngx_http_upstream_next(r, u, | 1201 ngx_http_upstream_next(r, u, |
1203 NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); | 1202 NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); |
1204 return; | 1203 return; |
1391 } | 1390 } |
1392 } | 1391 } |
1393 | 1392 |
1394 u->read_event_handler = ngx_http_upstream_process_body_in_memory; | 1393 u->read_event_handler = ngx_http_upstream_process_body_in_memory; |
1395 | 1394 |
1396 ngx_http_upstream_process_body_in_memory(rev); | 1395 ngx_http_upstream_process_body_in_memory(r, u); |
1397 } | 1396 } |
1398 | 1397 |
1399 | 1398 |
1400 static ngx_int_t | 1399 static ngx_int_t |
1401 ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u) | 1400 ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u) |
1535 return NGX_OK; | 1534 return NGX_OK; |
1536 } | 1535 } |
1537 | 1536 |
1538 | 1537 |
1539 static void | 1538 static void |
1540 ngx_http_upstream_process_body_in_memory(ngx_event_t *rev) | 1539 ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r, |
1541 { | 1540 ngx_http_upstream_t *u) |
1542 size_t size; | 1541 { |
1543 ssize_t n; | 1542 size_t size; |
1544 ngx_buf_t *b; | 1543 ssize_t n; |
1545 ngx_connection_t *c; | 1544 ngx_buf_t *b; |
1546 ngx_http_request_t *r; | 1545 ngx_event_t *rev; |
1547 ngx_http_upstream_t *u; | 1546 ngx_connection_t *c; |
1548 | 1547 |
1549 c = rev->data; | 1548 c = u->peer.connection; |
1550 r = c->data; | 1549 rev = c->read; |
1551 u = r->upstream; | |
1552 | 1550 |
1553 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1551 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1554 "http upstream process body on memory"); | 1552 "http upstream process body on memory"); |
1555 | 1553 |
1556 if (rev->timedout) { | 1554 if (rev->timedout) { |
1591 if (!rev->ready) { | 1589 if (!rev->ready) { |
1592 break; | 1590 break; |
1593 } | 1591 } |
1594 } | 1592 } |
1595 | 1593 |
1596 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { | 1594 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
1597 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); | 1595 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); |
1598 return; | 1596 return; |
1599 } | 1597 } |
1600 | 1598 |
1601 if (rev->active) { | 1599 if (rev->active) { |
1703 ngx_http_upstream_finalize_request(r, u, 0); | 1701 ngx_http_upstream_finalize_request(r, u, 0); |
1704 return; | 1702 return; |
1705 } | 1703 } |
1706 | 1704 |
1707 if (u->peer.connection->read->ready) { | 1705 if (u->peer.connection->read->ready) { |
1708 ngx_http_upstream_process_non_buffered_upstream( | 1706 ngx_http_upstream_process_non_buffered_upstream(r, u); |
1709 u->peer.connection->read); | |
1710 } | 1707 } |
1711 } | 1708 } |
1712 | 1709 |
1713 return; | 1710 return; |
1714 } | 1711 } |
1837 p->send_lowat = clcf->send_lowat; | 1834 p->send_lowat = clcf->send_lowat; |
1838 | 1835 |
1839 u->read_event_handler = ngx_http_upstream_process_upstream; | 1836 u->read_event_handler = ngx_http_upstream_process_upstream; |
1840 r->write_event_handler = ngx_http_upstream_process_downstream; | 1837 r->write_event_handler = ngx_http_upstream_process_downstream; |
1841 | 1838 |
1842 ngx_http_upstream_process_upstream(u->peer.connection->read); | 1839 ngx_http_upstream_process_upstream(r, u); |
1843 } | 1840 } |
1844 | 1841 |
1845 | 1842 |
1846 static void | 1843 static void |
1847 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r) | 1844 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r) |
1869 ngx_http_upstream_process_non_buffered_request(r, 1); | 1866 ngx_http_upstream_process_non_buffered_request(r, 1); |
1870 } | 1867 } |
1871 | 1868 |
1872 | 1869 |
1873 static void | 1870 static void |
1874 ngx_http_upstream_process_non_buffered_upstream(ngx_event_t *rev) | 1871 ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r, |
1875 { | 1872 ngx_http_upstream_t *u) |
1876 ngx_connection_t *c; | 1873 { |
1877 ngx_http_request_t *r; | 1874 ngx_connection_t *c; |
1878 ngx_http_upstream_t *u; | 1875 |
1879 | 1876 c = u->peer.connection; |
1880 c = rev->data; | |
1881 r = c->data; | |
1882 u = r->upstream; | |
1883 | 1877 |
1884 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1878 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1885 "http upstream process non buffered upstream"); | 1879 "http upstream process non buffered upstream"); |
1886 | 1880 |
1887 c->log->action = "reading upstream"; | 1881 c->log->action = "reading upstream"; |
1888 | 1882 |
1889 if (rev->timedout) { | 1883 if (c->read->timedout) { |
1890 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); | 1884 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); |
1891 ngx_http_upstream_finalize_request(r, u, 0); | 1885 ngx_http_upstream_finalize_request(r, u, 0); |
1892 return; | 1886 return; |
1893 } | 1887 } |
1894 | 1888 |
2140 ngx_http_upstream_process_request(r); | 2134 ngx_http_upstream_process_request(r); |
2141 } | 2135 } |
2142 | 2136 |
2143 | 2137 |
2144 static void | 2138 static void |
2145 ngx_http_upstream_process_upstream(ngx_event_t *rev) | 2139 ngx_http_upstream_process_upstream(ngx_http_request_t *r, |
2146 { | 2140 ngx_http_upstream_t *u) |
2147 ngx_connection_t *c; | 2141 { |
2148 ngx_event_pipe_t *p; | 2142 ngx_connection_t *c; |
2149 ngx_http_request_t *r; | 2143 |
2150 ngx_http_upstream_t *u; | 2144 c = u->peer.connection; |
2151 | |
2152 c = rev->data; | |
2153 r = c->data; | |
2154 u = r->upstream; | |
2155 p = u->pipe; | |
2156 | 2145 |
2157 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | 2146 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2158 "http upstream process upstream"); | 2147 "http upstream process upstream"); |
2159 | 2148 |
2160 c->log->action = "reading upstream"; | 2149 c->log->action = "reading upstream"; |
2161 | 2150 |
2162 if (rev->timedout) { | 2151 if (c->read->timedout) { |
2163 p->upstream_error = 1; | 2152 u->pipe->upstream_error = 1; |
2164 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); | 2153 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); |
2165 | 2154 |
2166 } else { | 2155 } else { |
2167 c = r->connection; | 2156 c = r->connection; |
2168 | 2157 |
2169 if (ngx_event_pipe(p, 0) == NGX_ABORT) { | 2158 if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) { |
2170 | 2159 |
2171 if (c->destroyed) { | 2160 if (c->destroyed) { |
2172 return; | 2161 return; |
2173 } | 2162 } |
2174 | 2163 |
2335 (void) ngx_ext_rename_file(&tf->file.name, &path, &ext); | 2324 (void) ngx_ext_rename_file(&tf->file.name, &path, &ext); |
2336 } | 2325 } |
2337 | 2326 |
2338 | 2327 |
2339 static void | 2328 static void |
2340 ngx_http_upstream_dummy_handler(ngx_event_t *wev) | 2329 ngx_http_upstream_dummy_handler(ngx_http_request_t *r, ngx_http_upstream_t *u) |
2341 { | 2330 { |
2342 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 2331 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2343 "http upstream dummy handler"); | 2332 "http upstream dummy handler"); |
2344 } | 2333 } |
2345 | 2334 |
2346 | 2335 |
2347 static void | 2336 static void |