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 }