Mercurial > hg > nginx
comparison src/event/ngx_event_connectex.c @ 186:c1f3a3c7c5db
nginx-0.0.1-2003-11-17-00:49:42 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 16 Nov 2003 21:49:42 +0000 |
parents | |
children | 5a9bbe99008b |
comparison
equal
deleted
inserted
replaced
185:d5f50cefc322 | 186:c1f3a3c7c5db |
---|---|
1 | |
2 #include <ngx_config.h> | |
3 #include <ngx_core.h> | |
4 #include <ngx_event.h> | |
5 | |
6 | |
7 #define NGX_MAX_PENDING_CONN 10 | |
8 | |
9 | |
10 static CRITICAL_SECTION connect_lock; | |
11 static int nconnects; | |
12 static ngx_connection_t pending_connects[NGX_MAX_PENDING_CONN]; | |
13 | |
14 static HANDLE pending_connect_event; | |
15 | |
16 __declspec(thread) int nevents = 0; | |
17 __declspec(thread) WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS]; | |
18 __declspec(thread) ngx_connection_t *conn[WSA_MAXIMUM_WAIT_EVENTS]; | |
19 | |
20 | |
21 | |
22 int ngx_iocp_wait_connect(ngx_connection_t *c) | |
23 { | |
24 for ( ;; ) { | |
25 EnterCriticalSection(&connect_lock); | |
26 | |
27 if (nconnects < NGX_MAX_PENDING_CONN) { | |
28 pending_connects[--nconnects] = c; | |
29 LeaveCriticalSection(&connect_lock); | |
30 | |
31 if (SetEvent(pending_connect_event) == 0) { | |
32 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
33 "SetEvent() failed"); | |
34 return NGX_ERROR; | |
35 | |
36 break; | |
37 } | |
38 | |
39 LeaveCriticalSection(&connect_lock); | |
40 ngx_log_error(NGX_LOG_NOTICE, c->log, 0, | |
41 "max number of pending connect()s is %d", | |
42 NGX_MAX_PENDING_CONN); | |
43 msleep(100); | |
44 } | |
45 | |
46 if (!started) { | |
47 if (ngx_iocp_new_thread(1) == NGX_ERROR) { | |
48 return NGX_ERROR; | |
49 } | |
50 started = 1; | |
51 } | |
52 | |
53 return NGX_OK; | |
54 } | |
55 | |
56 | |
57 int ngx_iocp_new_thread(int main) | |
58 { | |
59 u_int id; | |
60 | |
61 if (main) { | |
62 pending_connect_event = CreateEvent(NULL, 0, 1, NULL); | |
63 if (pending_connect_event == INVALID_HANDLE_VALUE) { | |
64 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
65 "CreateThread() failed"); | |
66 return NGX_ERROR; | |
67 } | |
68 } | |
69 | |
70 if (CreateThread(NULL, 0, ngx_iocp_wait_events, main, 0, &id) | |
71 == INVALID_HANDLE_VALUE) | |
72 { | |
73 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
74 "CreateThread() failed"); | |
75 return NGX_ERROR; | |
76 } | |
77 | |
78 SetEvent(event) { | |
79 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
80 "SetEvent() failed"); | |
81 return NGX_ERROR; | |
82 } | |
83 | |
84 return NGX_OK; | |
85 } | |
86 | |
87 | |
88 int ngx_iocp_new_connect() | |
89 { | |
90 EnterCriticalSection(&connect_lock); | |
91 c = pending_connects[--nconnects]; | |
92 LeaveCriticalSection(&connect_lock); | |
93 | |
94 conn[nevents] = c; | |
95 | |
96 events[nevents] = WSACreateEvent(); | |
97 if (events[nevents] == INVALID_HANDLE_VALUE) { | |
98 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, | |
99 "WSACreateEvent() failed"); | |
100 return NGX_ERROR; | |
101 } | |
102 | |
103 if (WSAEventSelect(c->fd, events[nevents], FD_CONNECT) == -1) | |
104 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, | |
105 "WSAEventSelect() failed"); | |
106 return NGX_ERROR; | |
107 } | |
108 | |
109 nevents++; | |
110 | |
111 return NGX_OK; | |
112 } | |
113 | |
114 | |
115 void ngx_iocp_wait_events(int main) | |
116 { | |
117 WSANETWORKEVENTS ne; | |
118 | |
119 nevents = 1; | |
120 events[0] = pending_connect_event; | |
121 conn[0] = NULL; | |
122 | |
123 for ( ;; ) { | |
124 offset = (nevents == WSA_MAXIMUM_WAIT_EVENTS) ? 1: 0; | |
125 timeout = (nevents == 1 && !first) ? 60000: INFINITE; | |
126 | |
127 n = WSAWaitForMultipleEvents(nevents - offset, events[offset], | |
128 0, timeout, 0); | |
129 if (n == WAIT_FAILED) { | |
130 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, | |
131 "WSAWaitForMultipleEvents() failed"); | |
132 continue; | |
133 } | |
134 | |
135 if (n == WAIT_TIMEOUT) { | |
136 if (nevents == 1 && !main) { | |
137 ExitThread(0); | |
138 } | |
139 | |
140 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
141 "WSAWaitForMultipleEvents() " | |
142 "returned unexpected WAIT_TIMEOUT"); | |
143 continue; | |
144 } | |
145 | |
146 n -= WSA_WAIT_EVENT_0; | |
147 | |
148 if (n == 0) { | |
149 | |
150 /* the first event is pending_connect_event */ | |
151 | |
152 if (nevents == WSA_MAXIMUM_WAIT_EVENTS) { | |
153 ngx_iocp_new_thread(0); | |
154 } else { | |
155 ngx_iocp_new_connect(); | |
156 } | |
157 | |
158 continue; | |
159 } | |
160 | |
161 if (WSAEnumNetworkEvents(c[n].fd, events[n], &ne) == -1) { | |
162 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, | |
163 "WSAEnumNetworkEvents() failed"); | |
164 continue; | |
165 } | |
166 | |
167 if (ne.lNetworkEvents & FD_CONNECT) { | |
168 conn[n].write->ovlp.error = ne.iErrorCode[FD_CONNECT_BIT]; | |
169 | |
170 if (PostQueuedCompletionStatus(iocp, 0, NGX_IOCP_CONNECT, | |
171 &conn[n].write->ovlp) == 0) | |
172 { | |
173 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, | |
174 "PostQueuedCompletionStatus() failed"); | |
175 continue; | |
176 } | |
177 | |
178 if (n < nevents) { | |
179 conn[n] = conn[nevents]; | |
180 events[n] = events[nevents]; | |
181 } | |
182 | |
183 nevents--; | |
184 continue; | |
185 } | |
186 | |
187 if (ne.lNetworkEvents & FD_ACCEPT) { | |
188 | |
189 /* CHECK ERROR ??? */ | |
190 | |
191 ngx_event_post_acceptex(conn[n].listening, 1); | |
192 continue; | |
193 } | |
194 | |
195 ngx_log_error(NGX_LOG_ALERT, c[n].log, 0, | |
196 "WSAWaitForMultipleEvents() " | |
197 "returned unexpected network event %lu", | |
198 ne.lNetworkEvents); | |
199 } | |
200 } |