OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) |
6 | 6 |
7 #include "platform/globals.h" | 7 #include "platform/globals.h" |
8 #if defined(HOST_OS_WINDOWS) | 8 #if defined(HOST_OS_WINDOWS) |
9 | 9 |
10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 static const int kStdOverlappedBufferSize = 16 * 1024; | 33 static const int kStdOverlappedBufferSize = 16 * 1024; |
34 static const int kMaxUDPPackageLength = 64 * 1024; | 34 static const int kMaxUDPPackageLength = 64 * 1024; |
35 | 35 |
36 OverlappedBuffer* OverlappedBuffer::AllocateBuffer(int buffer_size, | 36 OverlappedBuffer* OverlappedBuffer::AllocateBuffer(int buffer_size, |
37 Operation operation) { | 37 Operation operation) { |
38 OverlappedBuffer* buffer = | 38 OverlappedBuffer* buffer = |
39 new (buffer_size) OverlappedBuffer(buffer_size, operation); | 39 new (buffer_size) OverlappedBuffer(buffer_size, operation); |
40 return buffer; | 40 return buffer; |
41 } | 41 } |
42 | 42 |
43 | |
44 OverlappedBuffer* OverlappedBuffer::AllocateAcceptBuffer(int buffer_size) { | 43 OverlappedBuffer* OverlappedBuffer::AllocateAcceptBuffer(int buffer_size) { |
45 OverlappedBuffer* buffer = AllocateBuffer(buffer_size, kAccept); | 44 OverlappedBuffer* buffer = AllocateBuffer(buffer_size, kAccept); |
46 return buffer; | 45 return buffer; |
47 } | 46 } |
48 | 47 |
49 | |
50 OverlappedBuffer* OverlappedBuffer::AllocateReadBuffer(int buffer_size) { | 48 OverlappedBuffer* OverlappedBuffer::AllocateReadBuffer(int buffer_size) { |
51 return AllocateBuffer(buffer_size, kRead); | 49 return AllocateBuffer(buffer_size, kRead); |
52 } | 50 } |
53 | 51 |
54 | |
55 OverlappedBuffer* OverlappedBuffer::AllocateRecvFromBuffer(int buffer_size) { | 52 OverlappedBuffer* OverlappedBuffer::AllocateRecvFromBuffer(int buffer_size) { |
56 // For calling recvfrom additional buffer space is needed for the source | 53 // For calling recvfrom additional buffer space is needed for the source |
57 // address information. | 54 // address information. |
58 buffer_size += sizeof(socklen_t) + sizeof(struct sockaddr_storage); | 55 buffer_size += sizeof(socklen_t) + sizeof(struct sockaddr_storage); |
59 return AllocateBuffer(buffer_size, kRecvFrom); | 56 return AllocateBuffer(buffer_size, kRecvFrom); |
60 } | 57 } |
61 | 58 |
62 | |
63 OverlappedBuffer* OverlappedBuffer::AllocateWriteBuffer(int buffer_size) { | 59 OverlappedBuffer* OverlappedBuffer::AllocateWriteBuffer(int buffer_size) { |
64 return AllocateBuffer(buffer_size, kWrite); | 60 return AllocateBuffer(buffer_size, kWrite); |
65 } | 61 } |
66 | 62 |
67 | |
68 OverlappedBuffer* OverlappedBuffer::AllocateSendToBuffer(int buffer_size) { | 63 OverlappedBuffer* OverlappedBuffer::AllocateSendToBuffer(int buffer_size) { |
69 return AllocateBuffer(buffer_size, kSendTo); | 64 return AllocateBuffer(buffer_size, kSendTo); |
70 } | 65 } |
71 | 66 |
72 | |
73 OverlappedBuffer* OverlappedBuffer::AllocateDisconnectBuffer() { | 67 OverlappedBuffer* OverlappedBuffer::AllocateDisconnectBuffer() { |
74 return AllocateBuffer(0, kDisconnect); | 68 return AllocateBuffer(0, kDisconnect); |
75 } | 69 } |
76 | 70 |
77 | |
78 OverlappedBuffer* OverlappedBuffer::AllocateConnectBuffer() { | 71 OverlappedBuffer* OverlappedBuffer::AllocateConnectBuffer() { |
79 return AllocateBuffer(0, kConnect); | 72 return AllocateBuffer(0, kConnect); |
80 } | 73 } |
81 | 74 |
82 | |
83 void OverlappedBuffer::DisposeBuffer(OverlappedBuffer* buffer) { | 75 void OverlappedBuffer::DisposeBuffer(OverlappedBuffer* buffer) { |
84 delete buffer; | 76 delete buffer; |
85 } | 77 } |
86 | 78 |
87 | |
88 OverlappedBuffer* OverlappedBuffer::GetFromOverlapped(OVERLAPPED* overlapped) { | 79 OverlappedBuffer* OverlappedBuffer::GetFromOverlapped(OVERLAPPED* overlapped) { |
89 OverlappedBuffer* buffer = | 80 OverlappedBuffer* buffer = |
90 CONTAINING_RECORD(overlapped, OverlappedBuffer, overlapped_); | 81 CONTAINING_RECORD(overlapped, OverlappedBuffer, overlapped_); |
91 return buffer; | 82 return buffer; |
92 } | 83 } |
93 | 84 |
94 | |
95 int OverlappedBuffer::Read(void* buffer, int num_bytes) { | 85 int OverlappedBuffer::Read(void* buffer, int num_bytes) { |
96 if (num_bytes > GetRemainingLength()) { | 86 if (num_bytes > GetRemainingLength()) { |
97 num_bytes = GetRemainingLength(); | 87 num_bytes = GetRemainingLength(); |
98 } | 88 } |
99 memmove(buffer, GetBufferStart() + index_, num_bytes); | 89 memmove(buffer, GetBufferStart() + index_, num_bytes); |
100 index_ += num_bytes; | 90 index_ += num_bytes; |
101 return num_bytes; | 91 return num_bytes; |
102 } | 92 } |
103 | 93 |
104 | |
105 int OverlappedBuffer::Write(const void* buffer, int num_bytes) { | 94 int OverlappedBuffer::Write(const void* buffer, int num_bytes) { |
106 ASSERT(num_bytes == buflen_); | 95 ASSERT(num_bytes == buflen_); |
107 memmove(GetBufferStart(), buffer, num_bytes); | 96 memmove(GetBufferStart(), buffer, num_bytes); |
108 data_length_ = num_bytes; | 97 data_length_ = num_bytes; |
109 return num_bytes; | 98 return num_bytes; |
110 } | 99 } |
111 | 100 |
112 | |
113 int OverlappedBuffer::GetRemainingLength() { | 101 int OverlappedBuffer::GetRemainingLength() { |
114 ASSERT(operation_ == kRead || operation_ == kRecvFrom); | 102 ASSERT(operation_ == kRead || operation_ == kRecvFrom); |
115 return data_length_ - index_; | 103 return data_length_ - index_; |
116 } | 104 } |
117 | 105 |
118 | |
119 Handle::Handle(intptr_t handle) | 106 Handle::Handle(intptr_t handle) |
120 : ReferenceCounted(), | 107 : ReferenceCounted(), |
121 DescriptorInfoBase(handle), | 108 DescriptorInfoBase(handle), |
122 handle_(reinterpret_cast<HANDLE>(handle)), | 109 handle_(reinterpret_cast<HANDLE>(handle)), |
123 completion_port_(INVALID_HANDLE_VALUE), | 110 completion_port_(INVALID_HANDLE_VALUE), |
124 event_handler_(NULL), | 111 event_handler_(NULL), |
125 data_ready_(NULL), | 112 data_ready_(NULL), |
126 pending_read_(NULL), | 113 pending_read_(NULL), |
127 pending_write_(NULL), | 114 pending_write_(NULL), |
128 last_error_(NOERROR), | 115 last_error_(NOERROR), |
129 flags_(0), | 116 flags_(0), |
130 read_thread_id_(Thread::kInvalidThreadId), | 117 read_thread_id_(Thread::kInvalidThreadId), |
131 read_thread_handle_(NULL), | 118 read_thread_handle_(NULL), |
132 read_thread_starting_(false), | 119 read_thread_starting_(false), |
133 read_thread_finished_(false), | 120 read_thread_finished_(false), |
134 monitor_(new Monitor()) {} | 121 monitor_(new Monitor()) {} |
135 | 122 |
136 | |
137 Handle::~Handle() { | 123 Handle::~Handle() { |
138 delete monitor_; | 124 delete monitor_; |
139 } | 125 } |
140 | 126 |
141 | |
142 bool Handle::CreateCompletionPort(HANDLE completion_port) { | 127 bool Handle::CreateCompletionPort(HANDLE completion_port) { |
143 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); | 128 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); |
144 // A reference to the Handle is Retained by the IO completion port. | 129 // A reference to the Handle is Retained by the IO completion port. |
145 // It is Released by DeleteIfClosed. | 130 // It is Released by DeleteIfClosed. |
146 Retain(); | 131 Retain(); |
147 completion_port_ = CreateIoCompletionPort( | 132 completion_port_ = CreateIoCompletionPort( |
148 handle(), completion_port, reinterpret_cast<ULONG_PTR>(this), 0); | 133 handle(), completion_port, reinterpret_cast<ULONG_PTR>(this), 0); |
149 return (completion_port_ != NULL); | 134 return (completion_port_ != NULL); |
150 } | 135 } |
151 | 136 |
152 | |
153 void Handle::Close() { | 137 void Handle::Close() { |
154 MonitorLocker ml(monitor_); | 138 MonitorLocker ml(monitor_); |
155 if (!SupportsOverlappedIO()) { | 139 if (!SupportsOverlappedIO()) { |
156 // If the handle uses synchronous I/O (e.g. stdin), cancel any pending | 140 // If the handle uses synchronous I/O (e.g. stdin), cancel any pending |
157 // operation before closing the handle, so the read thread is not blocked. | 141 // operation before closing the handle, so the read thread is not blocked. |
158 BOOL result = CancelIoEx(handle_, NULL); | 142 BOOL result = CancelIoEx(handle_, NULL); |
159 // The Dart code 'stdin.listen(() {}).cancel()' causes this assert to be | 143 // The Dart code 'stdin.listen(() {}).cancel()' causes this assert to be |
160 // triggered on Windows 7, but not on Windows 10. | 144 // triggered on Windows 7, but not on Windows 10. |
161 #if defined(DEBUG) | 145 #if defined(DEBUG) |
162 if (IsWindows10OrGreater()) { | 146 if (IsWindows10OrGreater()) { |
163 ASSERT(result || (GetLastError() == ERROR_NOT_FOUND)); | 147 ASSERT(result || (GetLastError() == ERROR_NOT_FOUND)); |
164 } | 148 } |
165 #else | 149 #else |
166 USE(result); | 150 USE(result); |
167 #endif | 151 #endif |
168 } | 152 } |
169 if (!IsClosing()) { | 153 if (!IsClosing()) { |
170 // Close the socket and set the closing state. This close method can be | 154 // Close the socket and set the closing state. This close method can be |
171 // called again if this socket has pending IO operations in flight. | 155 // called again if this socket has pending IO operations in flight. |
172 MarkClosing(); | 156 MarkClosing(); |
173 // Perform handle type specific closing. | 157 // Perform handle type specific closing. |
174 DoClose(); | 158 DoClose(); |
175 } | 159 } |
176 ASSERT(IsHandleClosed()); | 160 ASSERT(IsHandleClosed()); |
177 } | 161 } |
178 | 162 |
179 | |
180 void Handle::DoClose() { | 163 void Handle::DoClose() { |
181 if (!IsHandleClosed()) { | 164 if (!IsHandleClosed()) { |
182 CloseHandle(handle_); | 165 CloseHandle(handle_); |
183 handle_ = INVALID_HANDLE_VALUE; | 166 handle_ = INVALID_HANDLE_VALUE; |
184 } | 167 } |
185 } | 168 } |
186 | 169 |
187 | |
188 bool Handle::HasPendingRead() { | 170 bool Handle::HasPendingRead() { |
189 MonitorLocker ml(monitor_); | 171 MonitorLocker ml(monitor_); |
190 return pending_read_ != NULL; | 172 return pending_read_ != NULL; |
191 } | 173 } |
192 | 174 |
193 | |
194 bool Handle::HasPendingWrite() { | 175 bool Handle::HasPendingWrite() { |
195 MonitorLocker ml(monitor_); | 176 MonitorLocker ml(monitor_); |
196 return pending_write_ != NULL; | 177 return pending_write_ != NULL; |
197 } | 178 } |
198 | 179 |
199 | |
200 void Handle::WaitForReadThreadStarted() { | 180 void Handle::WaitForReadThreadStarted() { |
201 MonitorLocker ml(monitor_); | 181 MonitorLocker ml(monitor_); |
202 while (read_thread_starting_) { | 182 while (read_thread_starting_) { |
203 ml.Wait(); | 183 ml.Wait(); |
204 } | 184 } |
205 } | 185 } |
206 | 186 |
207 | |
208 void Handle::WaitForReadThreadFinished() { | 187 void Handle::WaitForReadThreadFinished() { |
209 HANDLE to_join = NULL; | 188 HANDLE to_join = NULL; |
210 { | 189 { |
211 MonitorLocker ml(monitor_); | 190 MonitorLocker ml(monitor_); |
212 if (read_thread_id_ != Thread::kInvalidThreadId) { | 191 if (read_thread_id_ != Thread::kInvalidThreadId) { |
213 while (!read_thread_finished_) { | 192 while (!read_thread_finished_) { |
214 ml.Wait(); | 193 ml.Wait(); |
215 } | 194 } |
216 read_thread_finished_ = false; | 195 read_thread_finished_ = false; |
217 read_thread_id_ = Thread::kInvalidThreadId; | 196 read_thread_id_ = Thread::kInvalidThreadId; |
218 to_join = read_thread_handle_; | 197 to_join = read_thread_handle_; |
219 read_thread_handle_ = NULL; | 198 read_thread_handle_ = NULL; |
220 } | 199 } |
221 } | 200 } |
222 if (to_join != NULL) { | 201 if (to_join != NULL) { |
223 // Join the read thread. | 202 // Join the read thread. |
224 DWORD res = WaitForSingleObject(to_join, INFINITE); | 203 DWORD res = WaitForSingleObject(to_join, INFINITE); |
225 CloseHandle(to_join); | 204 CloseHandle(to_join); |
226 ASSERT(res == WAIT_OBJECT_0); | 205 ASSERT(res == WAIT_OBJECT_0); |
227 } | 206 } |
228 } | 207 } |
229 | 208 |
230 | |
231 void Handle::ReadComplete(OverlappedBuffer* buffer) { | 209 void Handle::ReadComplete(OverlappedBuffer* buffer) { |
232 WaitForReadThreadStarted(); | 210 WaitForReadThreadStarted(); |
233 { | 211 { |
234 MonitorLocker ml(monitor_); | 212 MonitorLocker ml(monitor_); |
235 // Currently only one outstanding read at the time. | 213 // Currently only one outstanding read at the time. |
236 ASSERT(pending_read_ == buffer); | 214 ASSERT(pending_read_ == buffer); |
237 ASSERT(data_ready_ == NULL); | 215 ASSERT(data_ready_ == NULL); |
238 if (!IsClosing() && !buffer->IsEmpty()) { | 216 if (!IsClosing() && !buffer->IsEmpty()) { |
239 data_ready_ = pending_read_; | 217 data_ready_ = pending_read_; |
240 } else { | 218 } else { |
241 OverlappedBuffer::DisposeBuffer(buffer); | 219 OverlappedBuffer::DisposeBuffer(buffer); |
242 } | 220 } |
243 pending_read_ = NULL; | 221 pending_read_ = NULL; |
244 } | 222 } |
245 WaitForReadThreadFinished(); | 223 WaitForReadThreadFinished(); |
246 } | 224 } |
247 | 225 |
248 | |
249 void Handle::RecvFromComplete(OverlappedBuffer* buffer) { | 226 void Handle::RecvFromComplete(OverlappedBuffer* buffer) { |
250 ReadComplete(buffer); | 227 ReadComplete(buffer); |
251 } | 228 } |
252 | 229 |
253 | |
254 void Handle::WriteComplete(OverlappedBuffer* buffer) { | 230 void Handle::WriteComplete(OverlappedBuffer* buffer) { |
255 MonitorLocker ml(monitor_); | 231 MonitorLocker ml(monitor_); |
256 // Currently only one outstanding write at the time. | 232 // Currently only one outstanding write at the time. |
257 ASSERT(pending_write_ == buffer); | 233 ASSERT(pending_write_ == buffer); |
258 OverlappedBuffer::DisposeBuffer(buffer); | 234 OverlappedBuffer::DisposeBuffer(buffer); |
259 pending_write_ = NULL; | 235 pending_write_ = NULL; |
260 } | 236 } |
261 | 237 |
262 | |
263 static void ReadFileThread(uword args) { | 238 static void ReadFileThread(uword args) { |
264 Handle* handle = reinterpret_cast<Handle*>(args); | 239 Handle* handle = reinterpret_cast<Handle*>(args); |
265 handle->ReadSyncCompleteAsync(); | 240 handle->ReadSyncCompleteAsync(); |
266 } | 241 } |
267 | 242 |
268 | |
269 void Handle::NotifyReadThreadStarted() { | 243 void Handle::NotifyReadThreadStarted() { |
270 MonitorLocker ml(monitor_); | 244 MonitorLocker ml(monitor_); |
271 ASSERT(read_thread_starting_); | 245 ASSERT(read_thread_starting_); |
272 ASSERT(read_thread_id_ == Thread::kInvalidThreadId); | 246 ASSERT(read_thread_id_ == Thread::kInvalidThreadId); |
273 read_thread_id_ = Thread::GetCurrentThreadId(); | 247 read_thread_id_ = Thread::GetCurrentThreadId(); |
274 read_thread_handle_ = OpenThread(SYNCHRONIZE, false, read_thread_id_); | 248 read_thread_handle_ = OpenThread(SYNCHRONIZE, false, read_thread_id_); |
275 read_thread_starting_ = false; | 249 read_thread_starting_ = false; |
276 ml.Notify(); | 250 ml.Notify(); |
277 } | 251 } |
278 | 252 |
279 | |
280 void Handle::NotifyReadThreadFinished() { | 253 void Handle::NotifyReadThreadFinished() { |
281 MonitorLocker ml(monitor_); | 254 MonitorLocker ml(monitor_); |
282 ASSERT(!read_thread_finished_); | 255 ASSERT(!read_thread_finished_); |
283 ASSERT(read_thread_id_ != Thread::kInvalidThreadId); | 256 ASSERT(read_thread_id_ != Thread::kInvalidThreadId); |
284 read_thread_finished_ = true; | 257 read_thread_finished_ = true; |
285 ml.Notify(); | 258 ml.Notify(); |
286 } | 259 } |
287 | 260 |
288 | |
289 void Handle::ReadSyncCompleteAsync() { | 261 void Handle::ReadSyncCompleteAsync() { |
290 NotifyReadThreadStarted(); | 262 NotifyReadThreadStarted(); |
291 ASSERT(pending_read_ != NULL); | 263 ASSERT(pending_read_ != NULL); |
292 ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize); | 264 ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize); |
293 | 265 |
294 DWORD buffer_size = pending_read_->GetBufferSize(); | 266 DWORD buffer_size = pending_read_->GetBufferSize(); |
295 if (GetFileType(handle_) == FILE_TYPE_CHAR) { | 267 if (GetFileType(handle_) == FILE_TYPE_CHAR) { |
296 buffer_size = kStdOverlappedBufferSize; | 268 buffer_size = kStdOverlappedBufferSize; |
297 } | 269 } |
298 char* buffer_start = pending_read_->GetBufferStart(); | 270 char* buffer_start = pending_read_->GetBufferStart(); |
299 DWORD bytes_read = 0; | 271 DWORD bytes_read = 0; |
300 BOOL ok = ReadFile(handle_, buffer_start, buffer_size, &bytes_read, NULL); | 272 BOOL ok = ReadFile(handle_, buffer_start, buffer_size, &bytes_read, NULL); |
301 if (!ok) { | 273 if (!ok) { |
302 bytes_read = 0; | 274 bytes_read = 0; |
303 } | 275 } |
304 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); | 276 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); |
305 ok = | 277 ok = |
306 PostQueuedCompletionStatus(event_handler_->completion_port(), bytes_read, | 278 PostQueuedCompletionStatus(event_handler_->completion_port(), bytes_read, |
307 reinterpret_cast<ULONG_PTR>(this), overlapped); | 279 reinterpret_cast<ULONG_PTR>(this), overlapped); |
308 if (!ok) { | 280 if (!ok) { |
309 FATAL("PostQueuedCompletionStatus failed"); | 281 FATAL("PostQueuedCompletionStatus failed"); |
310 } | 282 } |
311 NotifyReadThreadFinished(); | 283 NotifyReadThreadFinished(); |
312 } | 284 } |
313 | 285 |
314 | |
315 bool Handle::IssueRead() { | 286 bool Handle::IssueRead() { |
316 ASSERT(type_ != kListenSocket); | 287 ASSERT(type_ != kListenSocket); |
317 ASSERT(pending_read_ == NULL); | 288 ASSERT(pending_read_ == NULL); |
318 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); | 289 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); |
319 if (SupportsOverlappedIO()) { | 290 if (SupportsOverlappedIO()) { |
320 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 291 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
321 | 292 |
322 BOOL ok = | 293 BOOL ok = |
323 ReadFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), | 294 ReadFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), |
324 NULL, buffer->GetCleanOverlapped()); | 295 NULL, buffer->GetCleanOverlapped()); |
(...skipping 10 matching lines...) Expand all Loading... |
335 pending_read_ = buffer; | 306 pending_read_ = buffer; |
336 read_thread_starting_ = true; | 307 read_thread_starting_ = true; |
337 int result = Thread::Start(ReadFileThread, reinterpret_cast<uword>(this)); | 308 int result = Thread::Start(ReadFileThread, reinterpret_cast<uword>(this)); |
338 if (result != 0) { | 309 if (result != 0) { |
339 FATAL1("Failed to start read file thread %d", result); | 310 FATAL1("Failed to start read file thread %d", result); |
340 } | 311 } |
341 return true; | 312 return true; |
342 } | 313 } |
343 } | 314 } |
344 | 315 |
345 | |
346 bool Handle::IssueRecvFrom() { | 316 bool Handle::IssueRecvFrom() { |
347 return false; | 317 return false; |
348 } | 318 } |
349 | 319 |
350 | |
351 bool Handle::IssueWrite() { | 320 bool Handle::IssueWrite() { |
352 MonitorLocker ml(monitor_); | 321 MonitorLocker ml(monitor_); |
353 ASSERT(type_ != kListenSocket); | 322 ASSERT(type_ != kListenSocket); |
354 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 323 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
355 ASSERT(pending_write_ != NULL); | 324 ASSERT(pending_write_ != NULL); |
356 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); | 325 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); |
357 | 326 |
358 OverlappedBuffer* buffer = pending_write_; | 327 OverlappedBuffer* buffer = pending_write_; |
359 BOOL ok = | 328 BOOL ok = |
360 WriteFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), | 329 WriteFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), |
361 NULL, buffer->GetCleanOverlapped()); | 330 NULL, buffer->GetCleanOverlapped()); |
362 if (ok || (GetLastError() == ERROR_IO_PENDING)) { | 331 if (ok || (GetLastError() == ERROR_IO_PENDING)) { |
363 // Completing asynchronously. | 332 // Completing asynchronously. |
364 pending_write_ = buffer; | 333 pending_write_ = buffer; |
365 return true; | 334 return true; |
366 } | 335 } |
367 OverlappedBuffer::DisposeBuffer(buffer); | 336 OverlappedBuffer::DisposeBuffer(buffer); |
368 HandleIssueError(); | 337 HandleIssueError(); |
369 return false; | 338 return false; |
370 } | 339 } |
371 | 340 |
372 | |
373 bool Handle::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { | 341 bool Handle::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { |
374 return false; | 342 return false; |
375 } | 343 } |
376 | 344 |
377 | |
378 static void HandleClosed(Handle* handle) { | 345 static void HandleClosed(Handle* handle) { |
379 if (!handle->IsClosing()) { | 346 if (!handle->IsClosing()) { |
380 int event_mask = 1 << kCloseEvent; | 347 int event_mask = 1 << kCloseEvent; |
381 handle->NotifyAllDartPorts(event_mask); | 348 handle->NotifyAllDartPorts(event_mask); |
382 } | 349 } |
383 } | 350 } |
384 | 351 |
385 | |
386 static void HandleError(Handle* handle) { | 352 static void HandleError(Handle* handle) { |
387 handle->set_last_error(WSAGetLastError()); | 353 handle->set_last_error(WSAGetLastError()); |
388 handle->MarkError(); | 354 handle->MarkError(); |
389 if (!handle->IsClosing()) { | 355 if (!handle->IsClosing()) { |
390 handle->NotifyAllDartPorts(1 << kErrorEvent); | 356 handle->NotifyAllDartPorts(1 << kErrorEvent); |
391 } | 357 } |
392 } | 358 } |
393 | 359 |
394 | |
395 void Handle::HandleIssueError() { | 360 void Handle::HandleIssueError() { |
396 DWORD error = GetLastError(); | 361 DWORD error = GetLastError(); |
397 if (error == ERROR_BROKEN_PIPE) { | 362 if (error == ERROR_BROKEN_PIPE) { |
398 HandleClosed(this); | 363 HandleClosed(this); |
399 } else { | 364 } else { |
400 HandleError(this); | 365 HandleError(this); |
401 } | 366 } |
402 SetLastError(error); | 367 SetLastError(error); |
403 } | 368 } |
404 | 369 |
405 | |
406 void FileHandle::EnsureInitialized(EventHandlerImplementation* event_handler) { | 370 void FileHandle::EnsureInitialized(EventHandlerImplementation* event_handler) { |
407 MonitorLocker ml(monitor_); | 371 MonitorLocker ml(monitor_); |
408 event_handler_ = event_handler; | 372 event_handler_ = event_handler; |
409 if (completion_port_ == INVALID_HANDLE_VALUE) { | 373 if (completion_port_ == INVALID_HANDLE_VALUE) { |
410 if (SupportsOverlappedIO()) { | 374 if (SupportsOverlappedIO()) { |
411 CreateCompletionPort(event_handler_->completion_port()); | 375 CreateCompletionPort(event_handler_->completion_port()); |
412 } else { | 376 } else { |
413 // We need to retain the Handle even if overlapped IO is not supported. | 377 // We need to retain the Handle even if overlapped IO is not supported. |
414 // It is Released by DeleteIfClosed after ReadSyncCompleteAsync | 378 // It is Released by DeleteIfClosed after ReadSyncCompleteAsync |
415 // manually puts an event on the IO completion port. | 379 // manually puts an event on the IO completion port. |
416 Retain(); | 380 Retain(); |
417 completion_port_ = event_handler_->completion_port(); | 381 completion_port_ = event_handler_->completion_port(); |
418 } | 382 } |
419 } | 383 } |
420 } | 384 } |
421 | 385 |
422 | |
423 bool FileHandle::IsClosed() { | 386 bool FileHandle::IsClosed() { |
424 return IsClosing() && !HasPendingRead() && !HasPendingWrite(); | 387 return IsClosing() && !HasPendingRead() && !HasPendingWrite(); |
425 } | 388 } |
426 | 389 |
427 | |
428 void DirectoryWatchHandle::EnsureInitialized( | 390 void DirectoryWatchHandle::EnsureInitialized( |
429 EventHandlerImplementation* event_handler) { | 391 EventHandlerImplementation* event_handler) { |
430 MonitorLocker ml(monitor_); | 392 MonitorLocker ml(monitor_); |
431 event_handler_ = event_handler; | 393 event_handler_ = event_handler; |
432 if (completion_port_ == INVALID_HANDLE_VALUE) { | 394 if (completion_port_ == INVALID_HANDLE_VALUE) { |
433 CreateCompletionPort(event_handler_->completion_port()); | 395 CreateCompletionPort(event_handler_->completion_port()); |
434 } | 396 } |
435 } | 397 } |
436 | 398 |
437 | |
438 bool DirectoryWatchHandle::IsClosed() { | 399 bool DirectoryWatchHandle::IsClosed() { |
439 return IsClosing() && (pending_read_ == NULL); | 400 return IsClosing() && (pending_read_ == NULL); |
440 } | 401 } |
441 | 402 |
442 | |
443 bool DirectoryWatchHandle::IssueRead() { | 403 bool DirectoryWatchHandle::IssueRead() { |
444 // It may have been started before, as we start the directory-handler when | 404 // It may have been started before, as we start the directory-handler when |
445 // we create it. | 405 // we create it. |
446 if ((pending_read_ != NULL) || (data_ready_ != NULL)) { | 406 if ((pending_read_ != NULL) || (data_ready_ != NULL)) { |
447 return true; | 407 return true; |
448 } | 408 } |
449 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); | 409 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); |
450 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 410 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
451 BOOL ok = ReadDirectoryChangesW(handle_, buffer->GetBufferStart(), | 411 BOOL ok = ReadDirectoryChangesW(handle_, buffer->GetBufferStart(), |
452 buffer->GetBufferSize(), recursive_, events_, | 412 buffer->GetBufferSize(), recursive_, events_, |
453 NULL, buffer->GetCleanOverlapped(), NULL); | 413 NULL, buffer->GetCleanOverlapped(), NULL); |
454 if (ok || (GetLastError() == ERROR_IO_PENDING)) { | 414 if (ok || (GetLastError() == ERROR_IO_PENDING)) { |
455 // Completing asynchronously. | 415 // Completing asynchronously. |
456 pending_read_ = buffer; | 416 pending_read_ = buffer; |
457 return true; | 417 return true; |
458 } | 418 } |
459 OverlappedBuffer::DisposeBuffer(buffer); | 419 OverlappedBuffer::DisposeBuffer(buffer); |
460 return false; | 420 return false; |
461 } | 421 } |
462 | 422 |
463 | |
464 void DirectoryWatchHandle::Stop() { | 423 void DirectoryWatchHandle::Stop() { |
465 MonitorLocker ml(monitor_); | 424 MonitorLocker ml(monitor_); |
466 // Stop the outstanding read, so we can close the handle. | 425 // Stop the outstanding read, so we can close the handle. |
467 | 426 |
468 if (pending_read_ != NULL) { | 427 if (pending_read_ != NULL) { |
469 CancelIoEx(handle(), pending_read_->GetCleanOverlapped()); | 428 CancelIoEx(handle(), pending_read_->GetCleanOverlapped()); |
470 // Don't dispose of the buffer, as it will still complete (with length 0). | 429 // Don't dispose of the buffer, as it will still complete (with length 0). |
471 } | 430 } |
472 | 431 |
473 DoClose(); | 432 DoClose(); |
474 } | 433 } |
475 | 434 |
476 | |
477 void SocketHandle::HandleIssueError() { | 435 void SocketHandle::HandleIssueError() { |
478 int error = WSAGetLastError(); | 436 int error = WSAGetLastError(); |
479 if (error == WSAECONNRESET) { | 437 if (error == WSAECONNRESET) { |
480 HandleClosed(this); | 438 HandleClosed(this); |
481 } else { | 439 } else { |
482 HandleError(this); | 440 HandleError(this); |
483 } | 441 } |
484 WSASetLastError(error); | 442 WSASetLastError(error); |
485 } | 443 } |
486 | 444 |
487 | |
488 bool ListenSocket::LoadAcceptEx() { | 445 bool ListenSocket::LoadAcceptEx() { |
489 // Load the AcceptEx function into memory using WSAIoctl. | 446 // Load the AcceptEx function into memory using WSAIoctl. |
490 GUID guid_accept_ex = WSAID_ACCEPTEX; | 447 GUID guid_accept_ex = WSAID_ACCEPTEX; |
491 DWORD bytes; | 448 DWORD bytes; |
492 int status = WSAIoctl(socket(), SIO_GET_EXTENSION_FUNCTION_POINTER, | 449 int status = WSAIoctl(socket(), SIO_GET_EXTENSION_FUNCTION_POINTER, |
493 &guid_accept_ex, sizeof(guid_accept_ex), &AcceptEx_, | 450 &guid_accept_ex, sizeof(guid_accept_ex), &AcceptEx_, |
494 sizeof(AcceptEx_), &bytes, NULL, NULL); | 451 sizeof(AcceptEx_), &bytes, NULL, NULL); |
495 return (status != SOCKET_ERROR); | 452 return (status != SOCKET_ERROR); |
496 } | 453 } |
497 | 454 |
498 | |
499 bool ListenSocket::IssueAccept() { | 455 bool ListenSocket::IssueAccept() { |
500 MonitorLocker ml(monitor_); | 456 MonitorLocker ml(monitor_); |
501 | 457 |
502 // For AcceptEx there needs to be buffer storage for address | 458 // For AcceptEx there needs to be buffer storage for address |
503 // information for two addresses (local and remote address). The | 459 // information for two addresses (local and remote address). The |
504 // AcceptEx documentation says: "This value must be at least 16 | 460 // AcceptEx documentation says: "This value must be at least 16 |
505 // bytes more than the maximum address length for the transport | 461 // bytes more than the maximum address length for the transport |
506 // protocol in use." | 462 // protocol in use." |
507 static const int kAcceptExAddressAdditionalBytes = 16; | 463 static const int kAcceptExAddressAdditionalBytes = 16; |
508 static const int kAcceptExAddressStorageSize = | 464 static const int kAcceptExAddressStorageSize = |
(...skipping 14 matching lines...) Expand all Loading... |
523 WSASetLastError(error); | 479 WSASetLastError(error); |
524 return false; | 480 return false; |
525 } | 481 } |
526 } | 482 } |
527 | 483 |
528 pending_accept_count_++; | 484 pending_accept_count_++; |
529 | 485 |
530 return true; | 486 return true; |
531 } | 487 } |
532 | 488 |
533 | |
534 void ListenSocket::AcceptComplete(OverlappedBuffer* buffer, | 489 void ListenSocket::AcceptComplete(OverlappedBuffer* buffer, |
535 HANDLE completion_port) { | 490 HANDLE completion_port) { |
536 MonitorLocker ml(monitor_); | 491 MonitorLocker ml(monitor_); |
537 if (!IsClosing()) { | 492 if (!IsClosing()) { |
538 // Update the accepted socket to support the full range of API calls. | 493 // Update the accepted socket to support the full range of API calls. |
539 SOCKET s = socket(); | 494 SOCKET s = socket(); |
540 int rc = setsockopt(buffer->client(), SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, | 495 int rc = setsockopt(buffer->client(), SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, |
541 reinterpret_cast<char*>(&s), sizeof(s)); | 496 reinterpret_cast<char*>(&s), sizeof(s)); |
542 if (rc == NO_ERROR) { | 497 if (rc == NO_ERROR) { |
543 // Insert the accepted socket into the list. | 498 // Insert the accepted socket into the list. |
(...skipping 14 matching lines...) Expand all Loading... |
558 } | 513 } |
559 } else { | 514 } else { |
560 // Close the socket, as it's already accepted. | 515 // Close the socket, as it's already accepted. |
561 closesocket(buffer->client()); | 516 closesocket(buffer->client()); |
562 } | 517 } |
563 | 518 |
564 pending_accept_count_--; | 519 pending_accept_count_--; |
565 OverlappedBuffer::DisposeBuffer(buffer); | 520 OverlappedBuffer::DisposeBuffer(buffer); |
566 } | 521 } |
567 | 522 |
568 | |
569 static void DeleteIfClosed(Handle* handle) { | 523 static void DeleteIfClosed(Handle* handle) { |
570 if (handle->IsClosed()) { | 524 if (handle->IsClosed()) { |
571 handle->set_completion_port(INVALID_HANDLE_VALUE); | 525 handle->set_completion_port(INVALID_HANDLE_VALUE); |
572 handle->set_event_handler(NULL); | 526 handle->set_event_handler(NULL); |
573 handle->NotifyAllDartPorts(1 << kDestroyedEvent); | 527 handle->NotifyAllDartPorts(1 << kDestroyedEvent); |
574 handle->RemoveAllPorts(); | 528 handle->RemoveAllPorts(); |
575 // Once the Handle is closed, no further events on the IO completion port | 529 // Once the Handle is closed, no further events on the IO completion port |
576 // will mention it. Thus, we can drop the reference here. | 530 // will mention it. Thus, we can drop the reference here. |
577 handle->Release(); | 531 handle->Release(); |
578 } | 532 } |
579 } | 533 } |
580 | 534 |
581 | |
582 void ListenSocket::DoClose() { | 535 void ListenSocket::DoClose() { |
583 closesocket(socket()); | 536 closesocket(socket()); |
584 handle_ = INVALID_HANDLE_VALUE; | 537 handle_ = INVALID_HANDLE_VALUE; |
585 while (CanAccept()) { | 538 while (CanAccept()) { |
586 // Get rid of connections already accepted. | 539 // Get rid of connections already accepted. |
587 ClientSocket* client = Accept(); | 540 ClientSocket* client = Accept(); |
588 if (client != NULL) { | 541 if (client != NULL) { |
589 client->Close(); | 542 client->Close(); |
590 // Release the reference from the list. | 543 // Release the reference from the list. |
591 // When an accept completes, we make a new ClientSocket (1 reference), | 544 // When an accept completes, we make a new ClientSocket (1 reference), |
592 // and add it to the IO completion port (1 more reference). If an | 545 // and add it to the IO completion port (1 more reference). If an |
593 // accepted connection is never requested by the Dart code, then | 546 // accepted connection is never requested by the Dart code, then |
594 // this list owns a reference (first Release), and the IO completion | 547 // this list owns a reference (first Release), and the IO completion |
595 // port owns a reference, (second Release in DeleteIfClosed). | 548 // port owns a reference, (second Release in DeleteIfClosed). |
596 client->Release(); | 549 client->Release(); |
597 DeleteIfClosed(client); | 550 DeleteIfClosed(client); |
598 } else { | 551 } else { |
599 break; | 552 break; |
600 } | 553 } |
601 } | 554 } |
602 // To finish resetting the state of the ListenSocket back to what it was | 555 // To finish resetting the state of the ListenSocket back to what it was |
603 // before EnsureInitialized was called, we have to reset the AcceptEx_ | 556 // before EnsureInitialized was called, we have to reset the AcceptEx_ |
604 // function pointer. | 557 // function pointer. |
605 AcceptEx_ = NULL; | 558 AcceptEx_ = NULL; |
606 } | 559 } |
607 | 560 |
608 | |
609 bool ListenSocket::CanAccept() { | 561 bool ListenSocket::CanAccept() { |
610 MonitorLocker ml(monitor_); | 562 MonitorLocker ml(monitor_); |
611 return accepted_head_ != NULL; | 563 return accepted_head_ != NULL; |
612 } | 564 } |
613 | 565 |
614 | |
615 ClientSocket* ListenSocket::Accept() { | 566 ClientSocket* ListenSocket::Accept() { |
616 MonitorLocker ml(monitor_); | 567 MonitorLocker ml(monitor_); |
617 | 568 |
618 ClientSocket* result = NULL; | 569 ClientSocket* result = NULL; |
619 | 570 |
620 if (accepted_head_ != NULL) { | 571 if (accepted_head_ != NULL) { |
621 result = accepted_head_; | 572 result = accepted_head_; |
622 accepted_head_ = accepted_head_->next(); | 573 accepted_head_ = accepted_head_->next(); |
623 if (accepted_head_ == NULL) { | 574 if (accepted_head_ == NULL) { |
624 accepted_tail_ = NULL; | 575 accepted_tail_ = NULL; |
625 } | 576 } |
626 result->set_next(NULL); | 577 result->set_next(NULL); |
627 accepted_count_--; | 578 accepted_count_--; |
628 } | 579 } |
629 | 580 |
630 if (pending_accept_count_ < 5) { | 581 if (pending_accept_count_ < 5) { |
631 // We have less than 5 pending accepts, queue another. | 582 // We have less than 5 pending accepts, queue another. |
632 if (!IsClosing()) { | 583 if (!IsClosing()) { |
633 if (!IssueAccept()) { | 584 if (!IssueAccept()) { |
634 HandleError(this); | 585 HandleError(this); |
635 } | 586 } |
636 } | 587 } |
637 } | 588 } |
638 | 589 |
639 return result; | 590 return result; |
640 } | 591 } |
641 | 592 |
642 | |
643 void ListenSocket::EnsureInitialized( | 593 void ListenSocket::EnsureInitialized( |
644 EventHandlerImplementation* event_handler) { | 594 EventHandlerImplementation* event_handler) { |
645 MonitorLocker ml(monitor_); | 595 MonitorLocker ml(monitor_); |
646 if (AcceptEx_ == NULL) { | 596 if (AcceptEx_ == NULL) { |
647 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); | 597 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); |
648 ASSERT(event_handler_ == NULL); | 598 ASSERT(event_handler_ == NULL); |
649 event_handler_ = event_handler; | 599 event_handler_ = event_handler; |
650 CreateCompletionPort(event_handler_->completion_port()); | 600 CreateCompletionPort(event_handler_->completion_port()); |
651 LoadAcceptEx(); | 601 LoadAcceptEx(); |
652 } | 602 } |
653 } | 603 } |
654 | 604 |
655 | |
656 bool ListenSocket::IsClosed() { | 605 bool ListenSocket::IsClosed() { |
657 return IsClosing() && !HasPendingAccept(); | 606 return IsClosing() && !HasPendingAccept(); |
658 } | 607 } |
659 | 608 |
660 | |
661 intptr_t Handle::Available() { | 609 intptr_t Handle::Available() { |
662 MonitorLocker ml(monitor_); | 610 MonitorLocker ml(monitor_); |
663 if (data_ready_ == NULL) { | 611 if (data_ready_ == NULL) { |
664 return 0; | 612 return 0; |
665 } | 613 } |
666 ASSERT(!data_ready_->IsEmpty()); | 614 ASSERT(!data_ready_->IsEmpty()); |
667 return data_ready_->GetRemainingLength(); | 615 return data_ready_->GetRemainingLength(); |
668 } | 616 } |
669 | 617 |
670 | |
671 intptr_t Handle::Read(void* buffer, intptr_t num_bytes) { | 618 intptr_t Handle::Read(void* buffer, intptr_t num_bytes) { |
672 MonitorLocker ml(monitor_); | 619 MonitorLocker ml(monitor_); |
673 if (data_ready_ == NULL) { | 620 if (data_ready_ == NULL) { |
674 return 0; | 621 return 0; |
675 } | 622 } |
676 num_bytes = | 623 num_bytes = |
677 data_ready_->Read(buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); | 624 data_ready_->Read(buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); |
678 if (data_ready_->IsEmpty()) { | 625 if (data_ready_->IsEmpty()) { |
679 OverlappedBuffer::DisposeBuffer(data_ready_); | 626 OverlappedBuffer::DisposeBuffer(data_ready_); |
680 data_ready_ = NULL; | 627 data_ready_ = NULL; |
681 if (!IsClosing() && !IsClosedRead()) { | 628 if (!IsClosing() && !IsClosedRead()) { |
682 IssueRead(); | 629 IssueRead(); |
683 } | 630 } |
684 } | 631 } |
685 return num_bytes; | 632 return num_bytes; |
686 } | 633 } |
687 | 634 |
688 | |
689 intptr_t Handle::RecvFrom(void* buffer, | 635 intptr_t Handle::RecvFrom(void* buffer, |
690 intptr_t num_bytes, | 636 intptr_t num_bytes, |
691 struct sockaddr* sa, | 637 struct sockaddr* sa, |
692 socklen_t sa_len) { | 638 socklen_t sa_len) { |
693 MonitorLocker ml(monitor_); | 639 MonitorLocker ml(monitor_); |
694 if (data_ready_ == NULL) { | 640 if (data_ready_ == NULL) { |
695 return 0; | 641 return 0; |
696 } | 642 } |
697 num_bytes = | 643 num_bytes = |
698 data_ready_->Read(buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); | 644 data_ready_->Read(buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); |
699 if (data_ready_->from()->sa_family == AF_INET) { | 645 if (data_ready_->from()->sa_family == AF_INET) { |
700 ASSERT(sa_len >= sizeof(struct sockaddr_in)); | 646 ASSERT(sa_len >= sizeof(struct sockaddr_in)); |
701 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); | 647 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); |
702 } else { | 648 } else { |
703 ASSERT(data_ready_->from()->sa_family == AF_INET6); | 649 ASSERT(data_ready_->from()->sa_family == AF_INET6); |
704 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); | 650 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); |
705 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); | 651 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); |
706 } | 652 } |
707 // Always dispose of the buffer, as UDP messages must be read in their | 653 // Always dispose of the buffer, as UDP messages must be read in their |
708 // entirety to match how recvfrom works in a socket. | 654 // entirety to match how recvfrom works in a socket. |
709 OverlappedBuffer::DisposeBuffer(data_ready_); | 655 OverlappedBuffer::DisposeBuffer(data_ready_); |
710 data_ready_ = NULL; | 656 data_ready_ = NULL; |
711 if (!IsClosing() && !IsClosedRead()) { | 657 if (!IsClosing() && !IsClosedRead()) { |
712 IssueRecvFrom(); | 658 IssueRecvFrom(); |
713 } | 659 } |
714 return num_bytes; | 660 return num_bytes; |
715 } | 661 } |
716 | 662 |
717 | |
718 intptr_t Handle::Write(const void* buffer, intptr_t num_bytes) { | 663 intptr_t Handle::Write(const void* buffer, intptr_t num_bytes) { |
719 MonitorLocker ml(monitor_); | 664 MonitorLocker ml(monitor_); |
720 if (pending_write_ != NULL) { | 665 if (pending_write_ != NULL) { |
721 return 0; | 666 return 0; |
722 } | 667 } |
723 if (num_bytes > kBufferSize) { | 668 if (num_bytes > kBufferSize) { |
724 num_bytes = kBufferSize; | 669 num_bytes = kBufferSize; |
725 } | 670 } |
726 ASSERT(SupportsOverlappedIO()); | 671 ASSERT(SupportsOverlappedIO()); |
727 if (completion_port_ == INVALID_HANDLE_VALUE) { | 672 if (completion_port_ == INVALID_HANDLE_VALUE) { |
728 return 0; | 673 return 0; |
729 } | 674 } |
730 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); | 675 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); |
731 pending_write_ = OverlappedBuffer::AllocateWriteBuffer(truncated_bytes); | 676 pending_write_ = OverlappedBuffer::AllocateWriteBuffer(truncated_bytes); |
732 pending_write_->Write(buffer, truncated_bytes); | 677 pending_write_->Write(buffer, truncated_bytes); |
733 if (!IssueWrite()) { | 678 if (!IssueWrite()) { |
734 return -1; | 679 return -1; |
735 } | 680 } |
736 return truncated_bytes; | 681 return truncated_bytes; |
737 } | 682 } |
738 | 683 |
739 | |
740 intptr_t Handle::SendTo(const void* buffer, | 684 intptr_t Handle::SendTo(const void* buffer, |
741 intptr_t num_bytes, | 685 intptr_t num_bytes, |
742 struct sockaddr* sa, | 686 struct sockaddr* sa, |
743 socklen_t sa_len) { | 687 socklen_t sa_len) { |
744 MonitorLocker ml(monitor_); | 688 MonitorLocker ml(monitor_); |
745 if (pending_write_ != NULL) { | 689 if (pending_write_ != NULL) { |
746 return 0; | 690 return 0; |
747 } | 691 } |
748 if (num_bytes > kBufferSize) { | 692 if (num_bytes > kBufferSize) { |
749 num_bytes = kBufferSize; | 693 num_bytes = kBufferSize; |
750 } | 694 } |
751 ASSERT(SupportsOverlappedIO()); | 695 ASSERT(SupportsOverlappedIO()); |
752 if (completion_port_ == INVALID_HANDLE_VALUE) { | 696 if (completion_port_ == INVALID_HANDLE_VALUE) { |
753 return 0; | 697 return 0; |
754 } | 698 } |
755 pending_write_ = OverlappedBuffer::AllocateSendToBuffer(num_bytes); | 699 pending_write_ = OverlappedBuffer::AllocateSendToBuffer(num_bytes); |
756 pending_write_->Write(buffer, num_bytes); | 700 pending_write_->Write(buffer, num_bytes); |
757 if (!IssueSendTo(sa, sa_len)) { | 701 if (!IssueSendTo(sa, sa_len)) { |
758 return -1; | 702 return -1; |
759 } | 703 } |
760 return num_bytes; | 704 return num_bytes; |
761 } | 705 } |
762 | 706 |
763 | |
764 Mutex* StdHandle::stdin_mutex_ = new Mutex(); | 707 Mutex* StdHandle::stdin_mutex_ = new Mutex(); |
765 StdHandle* StdHandle::stdin_ = NULL; | 708 StdHandle* StdHandle::stdin_ = NULL; |
766 | 709 |
767 StdHandle* StdHandle::Stdin(HANDLE handle) { | 710 StdHandle* StdHandle::Stdin(HANDLE handle) { |
768 MutexLocker ml(stdin_mutex_); | 711 MutexLocker ml(stdin_mutex_); |
769 if (stdin_ == NULL) { | 712 if (stdin_ == NULL) { |
770 stdin_ = new StdHandle(handle); | 713 stdin_ = new StdHandle(handle); |
771 } | 714 } |
772 return stdin_; | 715 return stdin_; |
773 } | 716 } |
774 | 717 |
775 | |
776 static void WriteFileThread(uword args) { | 718 static void WriteFileThread(uword args) { |
777 StdHandle* handle = reinterpret_cast<StdHandle*>(args); | 719 StdHandle* handle = reinterpret_cast<StdHandle*>(args); |
778 handle->RunWriteLoop(); | 720 handle->RunWriteLoop(); |
779 } | 721 } |
780 | 722 |
781 | |
782 void StdHandle::RunWriteLoop() { | 723 void StdHandle::RunWriteLoop() { |
783 MonitorLocker ml(monitor_); | 724 MonitorLocker ml(monitor_); |
784 write_thread_running_ = true; | 725 write_thread_running_ = true; |
785 thread_id_ = Thread::GetCurrentThreadId(); | 726 thread_id_ = Thread::GetCurrentThreadId(); |
786 thread_handle_ = OpenThread(SYNCHRONIZE, false, thread_id_); | 727 thread_handle_ = OpenThread(SYNCHRONIZE, false, thread_id_); |
787 // Notify we have started. | 728 // Notify we have started. |
788 ml.Notify(); | 729 ml.Notify(); |
789 | 730 |
790 while (write_thread_running_) { | 731 while (write_thread_running_) { |
791 ml.Wait(Monitor::kNoTimeout); | 732 ml.Wait(Monitor::kNoTimeout); |
792 if (pending_write_ != NULL) { | 733 if (pending_write_ != NULL) { |
793 // We woke up and had a pending write. Execute it. | 734 // We woke up and had a pending write. Execute it. |
794 WriteSyncCompleteAsync(); | 735 WriteSyncCompleteAsync(); |
795 } | 736 } |
796 } | 737 } |
797 | 738 |
798 write_thread_exists_ = false; | 739 write_thread_exists_ = false; |
799 ml.Notify(); | 740 ml.Notify(); |
800 } | 741 } |
801 | 742 |
802 | |
803 void StdHandle::WriteSyncCompleteAsync() { | 743 void StdHandle::WriteSyncCompleteAsync() { |
804 ASSERT(pending_write_ != NULL); | 744 ASSERT(pending_write_ != NULL); |
805 | 745 |
806 DWORD bytes_written = -1; | 746 DWORD bytes_written = -1; |
807 BOOL ok = WriteFile(handle_, pending_write_->GetBufferStart(), | 747 BOOL ok = WriteFile(handle_, pending_write_->GetBufferStart(), |
808 pending_write_->GetBufferSize(), &bytes_written, NULL); | 748 pending_write_->GetBufferSize(), &bytes_written, NULL); |
809 if (!ok) { | 749 if (!ok) { |
810 bytes_written = 0; | 750 bytes_written = 0; |
811 } | 751 } |
812 thread_wrote_ += bytes_written; | 752 thread_wrote_ += bytes_written; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 } | 796 } |
857 // Only queue up to INT_MAX bytes. | 797 // Only queue up to INT_MAX bytes. |
858 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); | 798 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); |
859 // Create buffer and notify thread about the new handle. | 799 // Create buffer and notify thread about the new handle. |
860 pending_write_ = OverlappedBuffer::AllocateWriteBuffer(truncated_bytes); | 800 pending_write_ = OverlappedBuffer::AllocateWriteBuffer(truncated_bytes); |
861 pending_write_->Write(buffer, truncated_bytes); | 801 pending_write_->Write(buffer, truncated_bytes); |
862 ml.Notify(); | 802 ml.Notify(); |
863 return 0; | 803 return 0; |
864 } | 804 } |
865 | 805 |
866 | |
867 void StdHandle::DoClose() { | 806 void StdHandle::DoClose() { |
868 { | 807 { |
869 MonitorLocker ml(monitor_); | 808 MonitorLocker ml(monitor_); |
870 if (write_thread_exists_) { | 809 if (write_thread_exists_) { |
871 write_thread_running_ = false; | 810 write_thread_running_ = false; |
872 ml.Notify(); | 811 ml.Notify(); |
873 while (write_thread_exists_) { | 812 while (write_thread_exists_) { |
874 ml.Wait(Monitor::kNoTimeout); | 813 ml.Wait(Monitor::kNoTimeout); |
875 } | 814 } |
876 // Join the thread. | 815 // Join the thread. |
877 DWORD res = WaitForSingleObject(thread_handle_, INFINITE); | 816 DWORD res = WaitForSingleObject(thread_handle_, INFINITE); |
878 CloseHandle(thread_handle_); | 817 CloseHandle(thread_handle_); |
879 ASSERT(res == WAIT_OBJECT_0); | 818 ASSERT(res == WAIT_OBJECT_0); |
880 } | 819 } |
881 Handle::DoClose(); | 820 Handle::DoClose(); |
882 } | 821 } |
883 MutexLocker ml(stdin_mutex_); | 822 MutexLocker ml(stdin_mutex_); |
884 stdin_->Release(); | 823 stdin_->Release(); |
885 StdHandle::stdin_ = NULL; | 824 StdHandle::stdin_ = NULL; |
886 } | 825 } |
887 | 826 |
888 | |
889 #if defined(DEBUG) | 827 #if defined(DEBUG) |
890 intptr_t ClientSocket::disconnecting_ = 0; | 828 intptr_t ClientSocket::disconnecting_ = 0; |
891 #endif | 829 #endif |
892 | 830 |
893 | |
894 bool ClientSocket::LoadDisconnectEx() { | 831 bool ClientSocket::LoadDisconnectEx() { |
895 // Load the DisconnectEx function into memory using WSAIoctl. | 832 // Load the DisconnectEx function into memory using WSAIoctl. |
896 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; | 833 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; |
897 DWORD bytes; | 834 DWORD bytes; |
898 int status = | 835 int status = |
899 WSAIoctl(socket(), SIO_GET_EXTENSION_FUNCTION_POINTER, | 836 WSAIoctl(socket(), SIO_GET_EXTENSION_FUNCTION_POINTER, |
900 &guid_disconnect_ex, sizeof(guid_disconnect_ex), &DisconnectEx_, | 837 &guid_disconnect_ex, sizeof(guid_disconnect_ex), &DisconnectEx_, |
901 sizeof(DisconnectEx_), &bytes, NULL, NULL); | 838 sizeof(DisconnectEx_), &bytes, NULL, NULL); |
902 return (status != SOCKET_ERROR); | 839 return (status != SOCKET_ERROR); |
903 } | 840 } |
904 | 841 |
905 | |
906 void ClientSocket::Shutdown(int how) { | 842 void ClientSocket::Shutdown(int how) { |
907 int rc = shutdown(socket(), how); | 843 int rc = shutdown(socket(), how); |
908 if (how == SD_RECEIVE) { | 844 if (how == SD_RECEIVE) { |
909 MarkClosedRead(); | 845 MarkClosedRead(); |
910 } | 846 } |
911 if (how == SD_SEND) { | 847 if (how == SD_SEND) { |
912 MarkClosedWrite(); | 848 MarkClosedWrite(); |
913 } | 849 } |
914 if (how == SD_BOTH) { | 850 if (how == SD_BOTH) { |
915 MarkClosedRead(); | 851 MarkClosedRead(); |
916 MarkClosedWrite(); | 852 MarkClosedWrite(); |
917 } | 853 } |
918 } | 854 } |
919 | 855 |
920 | |
921 void ClientSocket::DoClose() { | 856 void ClientSocket::DoClose() { |
922 // Always do a shutdown before initiating a disconnect. | 857 // Always do a shutdown before initiating a disconnect. |
923 shutdown(socket(), SD_BOTH); | 858 shutdown(socket(), SD_BOTH); |
924 IssueDisconnect(); | 859 IssueDisconnect(); |
925 handle_ = INVALID_HANDLE_VALUE; | 860 handle_ = INVALID_HANDLE_VALUE; |
926 } | 861 } |
927 | 862 |
928 | |
929 bool ClientSocket::IssueRead() { | 863 bool ClientSocket::IssueRead() { |
930 MonitorLocker ml(monitor_); | 864 MonitorLocker ml(monitor_); |
931 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 865 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
932 ASSERT(pending_read_ == NULL); | 866 ASSERT(pending_read_ == NULL); |
933 | 867 |
934 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can | 868 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can |
935 // handle 64k datagrams. | 869 // handle 64k datagrams. |
936 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(65536); | 870 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(65536); |
937 | 871 |
938 DWORD flags; | 872 DWORD flags; |
939 flags = 0; | 873 flags = 0; |
940 int rc = WSARecv(socket(), buffer->GetWASBUF(), 1, NULL, &flags, | 874 int rc = WSARecv(socket(), buffer->GetWASBUF(), 1, NULL, &flags, |
941 buffer->GetCleanOverlapped(), NULL); | 875 buffer->GetCleanOverlapped(), NULL); |
942 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 876 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
943 pending_read_ = buffer; | 877 pending_read_ = buffer; |
944 return true; | 878 return true; |
945 } | 879 } |
946 OverlappedBuffer::DisposeBuffer(buffer); | 880 OverlappedBuffer::DisposeBuffer(buffer); |
947 pending_read_ = NULL; | 881 pending_read_ = NULL; |
948 HandleIssueError(); | 882 HandleIssueError(); |
949 return false; | 883 return false; |
950 } | 884 } |
951 | 885 |
952 | |
953 bool ClientSocket::IssueWrite() { | 886 bool ClientSocket::IssueWrite() { |
954 MonitorLocker ml(monitor_); | 887 MonitorLocker ml(monitor_); |
955 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 888 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
956 ASSERT(pending_write_ != NULL); | 889 ASSERT(pending_write_ != NULL); |
957 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); | 890 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); |
958 | 891 |
959 int rc = WSASend(socket(), pending_write_->GetWASBUF(), 1, NULL, 0, | 892 int rc = WSASend(socket(), pending_write_->GetWASBUF(), 1, NULL, 0, |
960 pending_write_->GetCleanOverlapped(), NULL); | 893 pending_write_->GetCleanOverlapped(), NULL); |
961 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 894 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
962 return true; | 895 return true; |
963 } | 896 } |
964 OverlappedBuffer::DisposeBuffer(pending_write_); | 897 OverlappedBuffer::DisposeBuffer(pending_write_); |
965 pending_write_ = NULL; | 898 pending_write_ = NULL; |
966 HandleIssueError(); | 899 HandleIssueError(); |
967 return false; | 900 return false; |
968 } | 901 } |
969 | 902 |
970 | |
971 void ClientSocket::IssueDisconnect() { | 903 void ClientSocket::IssueDisconnect() { |
972 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); | 904 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); |
973 BOOL ok = | 905 BOOL ok = |
974 DisconnectEx_(socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); | 906 DisconnectEx_(socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); |
975 // DisconnectEx works like other OverlappedIO APIs, where we can get either an | 907 // DisconnectEx works like other OverlappedIO APIs, where we can get either an |
976 // immediate success or delayed operation by WSA_IO_PENDING being set. | 908 // immediate success or delayed operation by WSA_IO_PENDING being set. |
977 if (ok || (WSAGetLastError() != WSA_IO_PENDING)) { | 909 if (ok || (WSAGetLastError() != WSA_IO_PENDING)) { |
978 DisconnectComplete(buffer); | 910 DisconnectComplete(buffer); |
979 } | 911 } |
980 // When the Dart side receives this event, it may decide to close its Dart | 912 // When the Dart side receives this event, it may decide to close its Dart |
981 // ports. When all ports are closed, the VM will shut down. The EventHandler | 913 // ports. When all ports are closed, the VM will shut down. The EventHandler |
982 // will then shut down. If the EventHandler shuts down before this | 914 // will then shut down. If the EventHandler shuts down before this |
983 // asynchronous disconnect finishes, this ClientSocket will be leaked. | 915 // asynchronous disconnect finishes, this ClientSocket will be leaked. |
984 // TODO(dart:io): Retain a list of client sockets that are in the process of | 916 // TODO(dart:io): Retain a list of client sockets that are in the process of |
985 // disconnecting. Disconnect them forcefully, and clean up their resources | 917 // disconnecting. Disconnect them forcefully, and clean up their resources |
986 // when the EventHandler shuts down. | 918 // when the EventHandler shuts down. |
987 NotifyAllDartPorts(1 << kDestroyedEvent); | 919 NotifyAllDartPorts(1 << kDestroyedEvent); |
988 RemoveAllPorts(); | 920 RemoveAllPorts(); |
989 #if defined(DEBUG) | 921 #if defined(DEBUG) |
990 disconnecting_++; | 922 disconnecting_++; |
991 #endif | 923 #endif |
992 } | 924 } |
993 | 925 |
994 | |
995 void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { | 926 void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { |
996 OverlappedBuffer::DisposeBuffer(buffer); | 927 OverlappedBuffer::DisposeBuffer(buffer); |
997 closesocket(socket()); | 928 closesocket(socket()); |
998 if (data_ready_ != NULL) { | 929 if (data_ready_ != NULL) { |
999 OverlappedBuffer::DisposeBuffer(data_ready_); | 930 OverlappedBuffer::DisposeBuffer(data_ready_); |
1000 } | 931 } |
1001 mark_closed(); | 932 mark_closed(); |
1002 #if defined(DEBUG) | 933 #if defined(DEBUG) |
1003 disconnecting_--; | 934 disconnecting_--; |
1004 #endif | 935 #endif |
1005 } | 936 } |
1006 | 937 |
1007 | |
1008 void ClientSocket::ConnectComplete(OverlappedBuffer* buffer) { | 938 void ClientSocket::ConnectComplete(OverlappedBuffer* buffer) { |
1009 OverlappedBuffer::DisposeBuffer(buffer); | 939 OverlappedBuffer::DisposeBuffer(buffer); |
1010 // Update socket to support full socket API, after ConnectEx completed. | 940 // Update socket to support full socket API, after ConnectEx completed. |
1011 setsockopt(socket(), SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0); | 941 setsockopt(socket(), SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0); |
1012 // If the port is set, we already listen for this socket in Dart. | 942 // If the port is set, we already listen for this socket in Dart. |
1013 // Handle the cases here. | 943 // Handle the cases here. |
1014 if (!IsClosedRead() && ((Mask() & (1 << kInEvent)) != 0)) { | 944 if (!IsClosedRead() && ((Mask() & (1 << kInEvent)) != 0)) { |
1015 IssueRead(); | 945 IssueRead(); |
1016 } | 946 } |
1017 if (!IsClosedWrite() && ((Mask() & (1 << kOutEvent)) != 0)) { | 947 if (!IsClosedWrite() && ((Mask() & (1 << kOutEvent)) != 0)) { |
1018 Dart_Port port = NextNotifyDartPort(1 << kOutEvent); | 948 Dart_Port port = NextNotifyDartPort(1 << kOutEvent); |
1019 DartUtils::PostInt32(port, 1 << kOutEvent); | 949 DartUtils::PostInt32(port, 1 << kOutEvent); |
1020 } | 950 } |
1021 } | 951 } |
1022 | 952 |
1023 | |
1024 void ClientSocket::EnsureInitialized( | 953 void ClientSocket::EnsureInitialized( |
1025 EventHandlerImplementation* event_handler) { | 954 EventHandlerImplementation* event_handler) { |
1026 MonitorLocker ml(monitor_); | 955 MonitorLocker ml(monitor_); |
1027 if (completion_port_ == INVALID_HANDLE_VALUE) { | 956 if (completion_port_ == INVALID_HANDLE_VALUE) { |
1028 ASSERT(event_handler_ == NULL); | 957 ASSERT(event_handler_ == NULL); |
1029 event_handler_ = event_handler; | 958 event_handler_ = event_handler; |
1030 CreateCompletionPort(event_handler_->completion_port()); | 959 CreateCompletionPort(event_handler_->completion_port()); |
1031 } | 960 } |
1032 } | 961 } |
1033 | 962 |
1034 | |
1035 bool ClientSocket::IsClosed() { | 963 bool ClientSocket::IsClosed() { |
1036 return connected_ && closed_; | 964 return connected_ && closed_; |
1037 } | 965 } |
1038 | 966 |
1039 | |
1040 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { | 967 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { |
1041 MonitorLocker ml(monitor_); | 968 MonitorLocker ml(monitor_); |
1042 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 969 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
1043 ASSERT(pending_write_ != NULL); | 970 ASSERT(pending_write_ != NULL); |
1044 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); | 971 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); |
1045 | 972 |
1046 int rc = WSASendTo(socket(), pending_write_->GetWASBUF(), 1, NULL, 0, sa, | 973 int rc = WSASendTo(socket(), pending_write_->GetWASBUF(), 1, NULL, 0, sa, |
1047 sa_len, pending_write_->GetCleanOverlapped(), NULL); | 974 sa_len, pending_write_->GetCleanOverlapped(), NULL); |
1048 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 975 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
1049 return true; | 976 return true; |
1050 } | 977 } |
1051 OverlappedBuffer::DisposeBuffer(pending_write_); | 978 OverlappedBuffer::DisposeBuffer(pending_write_); |
1052 pending_write_ = NULL; | 979 pending_write_ = NULL; |
1053 HandleIssueError(); | 980 HandleIssueError(); |
1054 return false; | 981 return false; |
1055 } | 982 } |
1056 | 983 |
1057 | |
1058 bool DatagramSocket::IssueRecvFrom() { | 984 bool DatagramSocket::IssueRecvFrom() { |
1059 MonitorLocker ml(monitor_); | 985 MonitorLocker ml(monitor_); |
1060 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 986 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
1061 ASSERT(pending_read_ == NULL); | 987 ASSERT(pending_read_ == NULL); |
1062 | 988 |
1063 OverlappedBuffer* buffer = | 989 OverlappedBuffer* buffer = |
1064 OverlappedBuffer::AllocateRecvFromBuffer(kMaxUDPPackageLength); | 990 OverlappedBuffer::AllocateRecvFromBuffer(kMaxUDPPackageLength); |
1065 | 991 |
1066 DWORD flags; | 992 DWORD flags; |
1067 flags = 0; | 993 flags = 0; |
1068 int rc = WSARecvFrom(socket(), buffer->GetWASBUF(), 1, NULL, &flags, | 994 int rc = WSARecvFrom(socket(), buffer->GetWASBUF(), 1, NULL, &flags, |
1069 buffer->from(), buffer->from_len_addr(), | 995 buffer->from(), buffer->from_len_addr(), |
1070 buffer->GetCleanOverlapped(), NULL); | 996 buffer->GetCleanOverlapped(), NULL); |
1071 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 997 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
1072 pending_read_ = buffer; | 998 pending_read_ = buffer; |
1073 return true; | 999 return true; |
1074 } | 1000 } |
1075 OverlappedBuffer::DisposeBuffer(buffer); | 1001 OverlappedBuffer::DisposeBuffer(buffer); |
1076 pending_read_ = NULL; | 1002 pending_read_ = NULL; |
1077 HandleIssueError(); | 1003 HandleIssueError(); |
1078 return false; | 1004 return false; |
1079 } | 1005 } |
1080 | 1006 |
1081 | |
1082 void DatagramSocket::EnsureInitialized( | 1007 void DatagramSocket::EnsureInitialized( |
1083 EventHandlerImplementation* event_handler) { | 1008 EventHandlerImplementation* event_handler) { |
1084 MonitorLocker ml(monitor_); | 1009 MonitorLocker ml(monitor_); |
1085 if (completion_port_ == INVALID_HANDLE_VALUE) { | 1010 if (completion_port_ == INVALID_HANDLE_VALUE) { |
1086 ASSERT(event_handler_ == NULL); | 1011 ASSERT(event_handler_ == NULL); |
1087 event_handler_ = event_handler; | 1012 event_handler_ = event_handler; |
1088 CreateCompletionPort(event_handler_->completion_port()); | 1013 CreateCompletionPort(event_handler_->completion_port()); |
1089 } | 1014 } |
1090 } | 1015 } |
1091 | 1016 |
1092 | |
1093 bool DatagramSocket::IsClosed() { | 1017 bool DatagramSocket::IsClosed() { |
1094 return IsClosing() && !HasPendingRead() && !HasPendingWrite(); | 1018 return IsClosing() && !HasPendingRead() && !HasPendingWrite(); |
1095 } | 1019 } |
1096 | 1020 |
1097 | |
1098 void DatagramSocket::DoClose() { | 1021 void DatagramSocket::DoClose() { |
1099 // Just close the socket. This will cause any queued requests to be aborted. | 1022 // Just close the socket. This will cause any queued requests to be aborted. |
1100 closesocket(socket()); | 1023 closesocket(socket()); |
1101 MarkClosedRead(); | 1024 MarkClosedRead(); |
1102 MarkClosedWrite(); | 1025 MarkClosedWrite(); |
1103 handle_ = INVALID_HANDLE_VALUE; | 1026 handle_ = INVALID_HANDLE_VALUE; |
1104 } | 1027 } |
1105 | 1028 |
1106 | |
1107 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { | 1029 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { |
1108 ASSERT(this != NULL); | 1030 ASSERT(this != NULL); |
1109 if (msg->id == kTimerId) { | 1031 if (msg->id == kTimerId) { |
1110 // Change of timeout request. Just set the new timeout and port as the | 1032 // Change of timeout request. Just set the new timeout and port as the |
1111 // completion thread will use the new timeout value for its next wait. | 1033 // completion thread will use the new timeout value for its next wait. |
1112 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); | 1034 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); |
1113 } else if (msg->id == kShutdownId) { | 1035 } else if (msg->id == kShutdownId) { |
1114 shutdown_ = true; | 1036 shutdown_ = true; |
1115 } else { | 1037 } else { |
1116 Socket* socket = reinterpret_cast<Socket*>(msg->id); | 1038 Socket* socket = reinterpret_cast<Socket*>(msg->id); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 socket->SetClosedFd(); | 1139 socket->SetClosedFd(); |
1218 } else { | 1140 } else { |
1219 UNREACHABLE(); | 1141 UNREACHABLE(); |
1220 } | 1142 } |
1221 } | 1143 } |
1222 | 1144 |
1223 DeleteIfClosed(handle); | 1145 DeleteIfClosed(handle); |
1224 } | 1146 } |
1225 } | 1147 } |
1226 | 1148 |
1227 | |
1228 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket, | 1149 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket, |
1229 OverlappedBuffer* buffer) { | 1150 OverlappedBuffer* buffer) { |
1230 listen_socket->AcceptComplete(buffer, completion_port_); | 1151 listen_socket->AcceptComplete(buffer, completion_port_); |
1231 | 1152 |
1232 { | 1153 { |
1233 MonitorLocker ml(listen_socket->monitor_); | 1154 MonitorLocker ml(listen_socket->monitor_); |
1234 TryDispatchingPendingAccepts(listen_socket); | 1155 TryDispatchingPendingAccepts(listen_socket); |
1235 } | 1156 } |
1236 | 1157 |
1237 DeleteIfClosed(listen_socket); | 1158 DeleteIfClosed(listen_socket); |
1238 } | 1159 } |
1239 | 1160 |
1240 | |
1241 void EventHandlerImplementation::TryDispatchingPendingAccepts( | 1161 void EventHandlerImplementation::TryDispatchingPendingAccepts( |
1242 ListenSocket* listen_socket) { | 1162 ListenSocket* listen_socket) { |
1243 if (!listen_socket->IsClosing() && listen_socket->CanAccept()) { | 1163 if (!listen_socket->IsClosing() && listen_socket->CanAccept()) { |
1244 intptr_t event_mask = 1 << kInEvent; | 1164 intptr_t event_mask = 1 << kInEvent; |
1245 for (int i = 0; (i < listen_socket->accepted_count()) && | 1165 for (int i = 0; (i < listen_socket->accepted_count()) && |
1246 (listen_socket->Mask() == event_mask); | 1166 (listen_socket->Mask() == event_mask); |
1247 i++) { | 1167 i++) { |
1248 Dart_Port port = listen_socket->NextNotifyDartPort(event_mask); | 1168 Dart_Port port = listen_socket->NextNotifyDartPort(event_mask); |
1249 DartUtils::PostInt32(port, event_mask); | 1169 DartUtils::PostInt32(port, event_mask); |
1250 } | 1170 } |
1251 } | 1171 } |
1252 } | 1172 } |
1253 | 1173 |
1254 | |
1255 void EventHandlerImplementation::HandleRead(Handle* handle, | 1174 void EventHandlerImplementation::HandleRead(Handle* handle, |
1256 int bytes, | 1175 int bytes, |
1257 OverlappedBuffer* buffer) { | 1176 OverlappedBuffer* buffer) { |
1258 buffer->set_data_length(bytes); | 1177 buffer->set_data_length(bytes); |
1259 handle->ReadComplete(buffer); | 1178 handle->ReadComplete(buffer); |
1260 if (bytes > 0) { | 1179 if (bytes > 0) { |
1261 if (!handle->IsClosing()) { | 1180 if (!handle->IsClosing()) { |
1262 int event_mask = 1 << kInEvent; | 1181 int event_mask = 1 << kInEvent; |
1263 if ((handle->Mask() & event_mask) != 0) { | 1182 if ((handle->Mask() & event_mask) != 0) { |
1264 Dart_Port port = handle->NextNotifyDartPort(event_mask); | 1183 Dart_Port port = handle->NextNotifyDartPort(event_mask); |
1265 DartUtils::PostInt32(port, event_mask); | 1184 DartUtils::PostInt32(port, event_mask); |
1266 } | 1185 } |
1267 } | 1186 } |
1268 } else { | 1187 } else { |
1269 handle->MarkClosedRead(); | 1188 handle->MarkClosedRead(); |
1270 if (bytes == 0) { | 1189 if (bytes == 0) { |
1271 HandleClosed(handle); | 1190 HandleClosed(handle); |
1272 } else { | 1191 } else { |
1273 HandleError(handle); | 1192 HandleError(handle); |
1274 } | 1193 } |
1275 } | 1194 } |
1276 | 1195 |
1277 DeleteIfClosed(handle); | 1196 DeleteIfClosed(handle); |
1278 } | 1197 } |
1279 | 1198 |
1280 | |
1281 void EventHandlerImplementation::HandleRecvFrom(Handle* handle, | 1199 void EventHandlerImplementation::HandleRecvFrom(Handle* handle, |
1282 int bytes, | 1200 int bytes, |
1283 OverlappedBuffer* buffer) { | 1201 OverlappedBuffer* buffer) { |
1284 ASSERT(handle->is_datagram_socket()); | 1202 ASSERT(handle->is_datagram_socket()); |
1285 if (bytes >= 0) { | 1203 if (bytes >= 0) { |
1286 buffer->set_data_length(bytes); | 1204 buffer->set_data_length(bytes); |
1287 handle->ReadComplete(buffer); | 1205 handle->ReadComplete(buffer); |
1288 if (!handle->IsClosing()) { | 1206 if (!handle->IsClosing()) { |
1289 int event_mask = 1 << kInEvent; | 1207 int event_mask = 1 << kInEvent; |
1290 if ((handle->Mask() & event_mask) != 0) { | 1208 if ((handle->Mask() & event_mask) != 0) { |
1291 Dart_Port port = handle->NextNotifyDartPort(event_mask); | 1209 Dart_Port port = handle->NextNotifyDartPort(event_mask); |
1292 DartUtils::PostInt32(port, event_mask); | 1210 DartUtils::PostInt32(port, event_mask); |
1293 } | 1211 } |
1294 } | 1212 } |
1295 } else { | 1213 } else { |
1296 HandleError(handle); | 1214 HandleError(handle); |
1297 } | 1215 } |
1298 | 1216 |
1299 DeleteIfClosed(handle); | 1217 DeleteIfClosed(handle); |
1300 } | 1218 } |
1301 | 1219 |
1302 | |
1303 void EventHandlerImplementation::HandleWrite(Handle* handle, | 1220 void EventHandlerImplementation::HandleWrite(Handle* handle, |
1304 int bytes, | 1221 int bytes, |
1305 OverlappedBuffer* buffer) { | 1222 OverlappedBuffer* buffer) { |
1306 handle->WriteComplete(buffer); | 1223 handle->WriteComplete(buffer); |
1307 | 1224 |
1308 if (bytes >= 0) { | 1225 if (bytes >= 0) { |
1309 if (!handle->IsError() && !handle->IsClosing()) { | 1226 if (!handle->IsError() && !handle->IsClosing()) { |
1310 int event_mask = 1 << kOutEvent; | 1227 int event_mask = 1 << kOutEvent; |
1311 ASSERT(!handle->is_client_socket() || | 1228 ASSERT(!handle->is_client_socket() || |
1312 reinterpret_cast<ClientSocket*>(handle)->is_connected()); | 1229 reinterpret_cast<ClientSocket*>(handle)->is_connected()); |
1313 if ((handle->Mask() & event_mask) != 0) { | 1230 if ((handle->Mask() & event_mask) != 0) { |
1314 Dart_Port port = handle->NextNotifyDartPort(event_mask); | 1231 Dart_Port port = handle->NextNotifyDartPort(event_mask); |
1315 DartUtils::PostInt32(port, event_mask); | 1232 DartUtils::PostInt32(port, event_mask); |
1316 } | 1233 } |
1317 } | 1234 } |
1318 } else { | 1235 } else { |
1319 HandleError(handle); | 1236 HandleError(handle); |
1320 } | 1237 } |
1321 | 1238 |
1322 DeleteIfClosed(handle); | 1239 DeleteIfClosed(handle); |
1323 } | 1240 } |
1324 | 1241 |
1325 | |
1326 void EventHandlerImplementation::HandleDisconnect(ClientSocket* client_socket, | 1242 void EventHandlerImplementation::HandleDisconnect(ClientSocket* client_socket, |
1327 int bytes, | 1243 int bytes, |
1328 OverlappedBuffer* buffer) { | 1244 OverlappedBuffer* buffer) { |
1329 client_socket->DisconnectComplete(buffer); | 1245 client_socket->DisconnectComplete(buffer); |
1330 DeleteIfClosed(client_socket); | 1246 DeleteIfClosed(client_socket); |
1331 } | 1247 } |
1332 | 1248 |
1333 | |
1334 void EventHandlerImplementation::HandleConnect(ClientSocket* client_socket, | 1249 void EventHandlerImplementation::HandleConnect(ClientSocket* client_socket, |
1335 int bytes, | 1250 int bytes, |
1336 OverlappedBuffer* buffer) { | 1251 OverlappedBuffer* buffer) { |
1337 if (bytes < 0) { | 1252 if (bytes < 0) { |
1338 HandleError(client_socket); | 1253 HandleError(client_socket); |
1339 OverlappedBuffer::DisposeBuffer(buffer); | 1254 OverlappedBuffer::DisposeBuffer(buffer); |
1340 } else { | 1255 } else { |
1341 client_socket->ConnectComplete(buffer); | 1256 client_socket->ConnectComplete(buffer); |
1342 } | 1257 } |
1343 client_socket->mark_connected(); | 1258 client_socket->mark_connected(); |
1344 DeleteIfClosed(client_socket); | 1259 DeleteIfClosed(client_socket); |
1345 } | 1260 } |
1346 | 1261 |
1347 | |
1348 void EventHandlerImplementation::HandleTimeout() { | 1262 void EventHandlerImplementation::HandleTimeout() { |
1349 if (!timeout_queue_.HasTimeout()) { | 1263 if (!timeout_queue_.HasTimeout()) { |
1350 return; | 1264 return; |
1351 } | 1265 } |
1352 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 1266 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
1353 timeout_queue_.RemoveCurrent(); | 1267 timeout_queue_.RemoveCurrent(); |
1354 } | 1268 } |
1355 | 1269 |
1356 | |
1357 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, | 1270 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, |
1358 ULONG_PTR key, | 1271 ULONG_PTR key, |
1359 OVERLAPPED* overlapped) { | 1272 OVERLAPPED* overlapped) { |
1360 OverlappedBuffer* buffer = OverlappedBuffer::GetFromOverlapped(overlapped); | 1273 OverlappedBuffer* buffer = OverlappedBuffer::GetFromOverlapped(overlapped); |
1361 switch (buffer->operation()) { | 1274 switch (buffer->operation()) { |
1362 case OverlappedBuffer::kAccept: { | 1275 case OverlappedBuffer::kAccept: { |
1363 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(key); | 1276 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(key); |
1364 HandleAccept(listen_socket, buffer); | 1277 HandleAccept(listen_socket, buffer); |
1365 break; | 1278 break; |
1366 } | 1279 } |
(...skipping 21 matching lines...) Expand all Loading... |
1388 case OverlappedBuffer::kConnect: { | 1301 case OverlappedBuffer::kConnect: { |
1389 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); | 1302 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); |
1390 HandleConnect(client_socket, bytes, buffer); | 1303 HandleConnect(client_socket, bytes, buffer); |
1391 break; | 1304 break; |
1392 } | 1305 } |
1393 default: | 1306 default: |
1394 UNREACHABLE(); | 1307 UNREACHABLE(); |
1395 } | 1308 } |
1396 } | 1309 } |
1397 | 1310 |
1398 | |
1399 void EventHandlerImplementation::HandleCompletionOrInterrupt( | 1311 void EventHandlerImplementation::HandleCompletionOrInterrupt( |
1400 BOOL ok, | 1312 BOOL ok, |
1401 DWORD bytes, | 1313 DWORD bytes, |
1402 ULONG_PTR key, | 1314 ULONG_PTR key, |
1403 OVERLAPPED* overlapped) { | 1315 OVERLAPPED* overlapped) { |
1404 if (!ok) { | 1316 if (!ok) { |
1405 // Treat ERROR_CONNECTION_ABORTED as connection closed. | 1317 // Treat ERROR_CONNECTION_ABORTED as connection closed. |
1406 // The error ERROR_OPERATION_ABORTED is set for pending | 1318 // The error ERROR_OPERATION_ABORTED is set for pending |
1407 // accept requests for a listen socket which is closed. | 1319 // accept requests for a listen socket which is closed. |
1408 // ERROR_NETNAME_DELETED occurs when the client closes | 1320 // ERROR_NETNAME_DELETED occurs when the client closes |
(...skipping 17 matching lines...) Expand all Loading... |
1426 } else if (key == NULL) { | 1338 } else if (key == NULL) { |
1427 // A key of NULL signals an interrupt message. | 1339 // A key of NULL signals an interrupt message. |
1428 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(overlapped); | 1340 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(overlapped); |
1429 HandleInterrupt(msg); | 1341 HandleInterrupt(msg); |
1430 delete msg; | 1342 delete msg; |
1431 } else { | 1343 } else { |
1432 HandleIOCompletion(bytes, key, overlapped); | 1344 HandleIOCompletion(bytes, key, overlapped); |
1433 } | 1345 } |
1434 } | 1346 } |
1435 | 1347 |
1436 | |
1437 EventHandlerImplementation::EventHandlerImplementation() { | 1348 EventHandlerImplementation::EventHandlerImplementation() { |
1438 startup_monitor_ = new Monitor(); | 1349 startup_monitor_ = new Monitor(); |
1439 handler_thread_id_ = Thread::kInvalidThreadId; | 1350 handler_thread_id_ = Thread::kInvalidThreadId; |
1440 handler_thread_handle_ = NULL; | 1351 handler_thread_handle_ = NULL; |
1441 completion_port_ = | 1352 completion_port_ = |
1442 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); | 1353 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); |
1443 if (completion_port_ == NULL) { | 1354 if (completion_port_ == NULL) { |
1444 FATAL("Completion port creation failed"); | 1355 FATAL("Completion port creation failed"); |
1445 } | 1356 } |
1446 shutdown_ = false; | 1357 shutdown_ = false; |
1447 } | 1358 } |
1448 | 1359 |
1449 | |
1450 EventHandlerImplementation::~EventHandlerImplementation() { | 1360 EventHandlerImplementation::~EventHandlerImplementation() { |
1451 // Join the handler thread. | 1361 // Join the handler thread. |
1452 DWORD res = WaitForSingleObject(handler_thread_handle_, INFINITE); | 1362 DWORD res = WaitForSingleObject(handler_thread_handle_, INFINITE); |
1453 CloseHandle(handler_thread_handle_); | 1363 CloseHandle(handler_thread_handle_); |
1454 ASSERT(res == WAIT_OBJECT_0); | 1364 ASSERT(res == WAIT_OBJECT_0); |
1455 delete startup_monitor_; | 1365 delete startup_monitor_; |
1456 CloseHandle(completion_port_); | 1366 CloseHandle(completion_port_); |
1457 } | 1367 } |
1458 | 1368 |
1459 | |
1460 int64_t EventHandlerImplementation::GetTimeout() { | 1369 int64_t EventHandlerImplementation::GetTimeout() { |
1461 if (!timeout_queue_.HasTimeout()) { | 1370 if (!timeout_queue_.HasTimeout()) { |
1462 return kInfinityTimeout; | 1371 return kInfinityTimeout; |
1463 } | 1372 } |
1464 int64_t millis = | 1373 int64_t millis = |
1465 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); | 1374 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); |
1466 return (millis < 0) ? 0 : millis; | 1375 return (millis < 0) ? 0 : millis; |
1467 } | 1376 } |
1468 | 1377 |
1469 | |
1470 void EventHandlerImplementation::SendData(intptr_t id, | 1378 void EventHandlerImplementation::SendData(intptr_t id, |
1471 Dart_Port dart_port, | 1379 Dart_Port dart_port, |
1472 int64_t data) { | 1380 int64_t data) { |
1473 InterruptMessage* msg = new InterruptMessage; | 1381 InterruptMessage* msg = new InterruptMessage; |
1474 msg->id = id; | 1382 msg->id = id; |
1475 msg->dart_port = dart_port; | 1383 msg->dart_port = dart_port; |
1476 msg->data = data; | 1384 msg->data = data; |
1477 BOOL ok = PostQueuedCompletionStatus(completion_port_, 0, NULL, | 1385 BOOL ok = PostQueuedCompletionStatus(completion_port_, 0, NULL, |
1478 reinterpret_cast<OVERLAPPED*>(msg)); | 1386 reinterpret_cast<OVERLAPPED*>(msg)); |
1479 if (!ok) { | 1387 if (!ok) { |
1480 FATAL("PostQueuedCompletionStatus failed"); | 1388 FATAL("PostQueuedCompletionStatus failed"); |
1481 } | 1389 } |
1482 } | 1390 } |
1483 | 1391 |
1484 | |
1485 void EventHandlerImplementation::EventHandlerEntry(uword args) { | 1392 void EventHandlerImplementation::EventHandlerEntry(uword args) { |
1486 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 1393 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
1487 EventHandlerImplementation* handler_impl = &handler->delegate_; | 1394 EventHandlerImplementation* handler_impl = &handler->delegate_; |
1488 ASSERT(handler_impl != NULL); | 1395 ASSERT(handler_impl != NULL); |
1489 | 1396 |
1490 { | 1397 { |
1491 MonitorLocker ml(handler_impl->startup_monitor_); | 1398 MonitorLocker ml(handler_impl->startup_monitor_); |
1492 handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId(); | 1399 handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId(); |
1493 handler_impl->handler_thread_handle_ = | 1400 handler_impl->handler_thread_handle_ = |
1494 OpenThread(SYNCHRONIZE, false, handler_impl->handler_thread_id_); | 1401 OpenThread(SYNCHRONIZE, false, handler_impl->handler_thread_id_); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 // Furthermore, if the Dart program references stdin, but does not | 1454 // Furthermore, if the Dart program references stdin, but does not |
1548 // explicitly close it, then the StdHandle for it will be leaked to here. | 1455 // explicitly close it, then the StdHandle for it will be leaked to here. |
1549 const intptr_t stdin_leaked = (StdHandle::StdinPtr() == NULL) ? 0 : 1; | 1456 const intptr_t stdin_leaked = (StdHandle::StdinPtr() == NULL) ? 0 : 1; |
1550 DEBUG_ASSERT(ReferenceCounted<Handle>::instances() == | 1457 DEBUG_ASSERT(ReferenceCounted<Handle>::instances() == |
1551 ClientSocket::disconnecting() + stdin_leaked); | 1458 ClientSocket::disconnecting() + stdin_leaked); |
1552 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); | 1459 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); |
1553 #endif // defined(DEBUG) | 1460 #endif // defined(DEBUG) |
1554 handler->NotifyShutdownDone(); | 1461 handler->NotifyShutdownDone(); |
1555 } | 1462 } |
1556 | 1463 |
1557 | |
1558 void EventHandlerImplementation::Start(EventHandler* handler) { | 1464 void EventHandlerImplementation::Start(EventHandler* handler) { |
1559 int result = | 1465 int result = |
1560 Thread::Start(EventHandlerEntry, reinterpret_cast<uword>(handler)); | 1466 Thread::Start(EventHandlerEntry, reinterpret_cast<uword>(handler)); |
1561 if (result != 0) { | 1467 if (result != 0) { |
1562 FATAL1("Failed to start event handler thread %d", result); | 1468 FATAL1("Failed to start event handler thread %d", result); |
1563 } | 1469 } |
1564 | 1470 |
1565 { | 1471 { |
1566 MonitorLocker ml(startup_monitor_); | 1472 MonitorLocker ml(startup_monitor_); |
1567 while (handler_thread_id_ == Thread::kInvalidThreadId) { | 1473 while (handler_thread_id_ == Thread::kInvalidThreadId) { |
1568 ml.Wait(); | 1474 ml.Wait(); |
1569 } | 1475 } |
1570 } | 1476 } |
1571 | 1477 |
1572 // Initialize Winsock32 | 1478 // Initialize Winsock32 |
1573 if (!SocketBase::Initialize()) { | 1479 if (!SocketBase::Initialize()) { |
1574 FATAL("Failed to initialized Windows sockets"); | 1480 FATAL("Failed to initialized Windows sockets"); |
1575 } | 1481 } |
1576 } | 1482 } |
1577 | 1483 |
1578 | |
1579 void EventHandlerImplementation::Shutdown() { | 1484 void EventHandlerImplementation::Shutdown() { |
1580 SendData(kShutdownId, 0, 0); | 1485 SendData(kShutdownId, 0, 0); |
1581 } | 1486 } |
1582 | 1487 |
1583 } // namespace bin | 1488 } // namespace bin |
1584 } // namespace dart | 1489 } // namespace dart |
1585 | 1490 |
1586 #endif // defined(HOST_OS_WINDOWS) | 1491 #endif // defined(HOST_OS_WINDOWS) |
1587 | 1492 |
1588 #endif // !defined(DART_IO_DISABLED) | 1493 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |