OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #include <process.h> | 5 #include <process.h> |
6 #include <winsock2.h> | 6 #include <winsock2.h> |
7 #include <ws2tcpip.h> | 7 #include <ws2tcpip.h> |
8 #include <mswsock.h> | 8 #include <mswsock.h> |
9 | 9 |
10 #include "bin/builtin.h" | 10 #include "bin/builtin.h" |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 buffer->GetBufferStart(), | 211 buffer->GetBufferStart(), |
212 buffer->GetBufferSize(), | 212 buffer->GetBufferSize(), |
213 NULL, | 213 NULL, |
214 buffer->GetCleanOverlapped()); | 214 buffer->GetCleanOverlapped()); |
215 if (ok || GetLastError() == ERROR_IO_PENDING) { | 215 if (ok || GetLastError() == ERROR_IO_PENDING) { |
216 // Completing asynchronously. | 216 // Completing asynchronously. |
217 pending_read_ = buffer; | 217 pending_read_ = buffer; |
218 return true; | 218 return true; |
219 } | 219 } |
220 | 220 |
221 fprintf(stderr, "ReadFile failed: %d\n", GetLastError()); | 221 if (GetLastError() != ERROR_BROKEN_PIPE) { |
| 222 fprintf(stderr, "ReadFile failed: %d\n", GetLastError()); |
| 223 } |
222 event_handler_->HandleClosed(this); | 224 event_handler_->HandleClosed(this); |
223 IOBuffer::DisposeBuffer(buffer); | 225 IOBuffer::DisposeBuffer(buffer); |
224 return false; | 226 return false; |
225 } | 227 } |
226 | 228 |
227 | 229 |
228 bool Handle::IssueWrite() { | 230 bool Handle::IssueWrite() { |
229 ScopedLock lock(this); | 231 ScopedLock lock(this); |
230 ASSERT(type_ != kListenSocket); | 232 ASSERT(type_ != kListenSocket); |
231 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 233 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
232 ASSERT(pending_write_ != NULL); | 234 ASSERT(pending_write_ != NULL); |
233 ASSERT(pending_write_->operation() == IOBuffer::kWrite); | 235 ASSERT(pending_write_->operation() == IOBuffer::kWrite); |
234 | 236 |
235 IOBuffer* buffer = pending_write_; | 237 IOBuffer* buffer = pending_write_; |
236 BOOL ok = WriteFile(handle_, | 238 BOOL ok = WriteFile(handle_, |
237 buffer->GetBufferStart(), | 239 buffer->GetBufferStart(), |
238 buffer->GetBufferSize(), | 240 buffer->GetBufferSize(), |
239 NULL, | 241 NULL, |
240 buffer->GetCleanOverlapped()); | 242 buffer->GetCleanOverlapped()); |
241 if (ok || GetLastError() == ERROR_IO_PENDING) { | 243 if (ok || GetLastError() == ERROR_IO_PENDING) { |
242 // Completing asynchronously. | 244 // Completing asynchronously. |
243 pending_write_ = buffer; | 245 pending_write_ = buffer; |
244 return true; | 246 return true; |
245 } | 247 } |
246 | 248 |
247 fprintf(stderr, "WriteFile failed: %d\n", GetLastError()); | 249 if (GetLastError() != ERROR_BROKEN_PIPE) { |
| 250 fprintf(stderr, "WriteFile failed: %d\n", GetLastError()); |
| 251 } |
248 event_handler_->HandleClosed(this); | 252 event_handler_->HandleClosed(this); |
249 IOBuffer::DisposeBuffer(buffer); | 253 IOBuffer::DisposeBuffer(buffer); |
250 return false; | 254 return false; |
251 } | 255 } |
252 | 256 |
253 | 257 |
| 258 void FileHandle::EnsureInitialized(EventHandlerImplementation* event_handler) { |
| 259 ScopedLock lock(this); |
| 260 if (completion_port_ == INVALID_HANDLE_VALUE) { |
| 261 ASSERT(event_handler_ == NULL); |
| 262 event_handler_ = event_handler; |
| 263 CreateCompletionPort(event_handler_->completion_port()); |
| 264 } |
| 265 } |
| 266 |
| 267 |
| 268 bool FileHandle::IsClosed() { |
| 269 return false; |
| 270 } |
| 271 |
| 272 |
| 273 void FileHandle::AfterClose() { |
| 274 } |
| 275 |
| 276 |
254 bool ListenSocket::LoadAcceptEx() { | 277 bool ListenSocket::LoadAcceptEx() { |
255 // Load the AcceptEx function into memory using WSAIoctl. | 278 // Load the AcceptEx function into memory using WSAIoctl. |
256 // The WSAIoctl function is an extension of the ioctlsocket() | 279 // The WSAIoctl function is an extension of the ioctlsocket() |
257 // function that can use overlapped I/O. The function's 3rd | 280 // function that can use overlapped I/O. The function's 3rd |
258 // through 6th parameters are input and output buffers where | 281 // through 6th parameters are input and output buffers where |
259 // we pass the pointer to our AcceptEx function. This is used | 282 // we pass the pointer to our AcceptEx function. This is used |
260 // so that we can call the AcceptEx function directly, rather | 283 // so that we can call the AcceptEx function directly, rather |
261 // than refer to the Mswsock.lib library. | 284 // than refer to the Mswsock.lib library. |
262 GUID guid_accept_ex = WSAID_ACCEPTEX; | 285 GUID guid_accept_ex = WSAID_ACCEPTEX; |
263 DWORD bytes; | 286 DWORD bytes; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 395 } |
373 } | 396 } |
374 } | 397 } |
375 | 398 |
376 | 399 |
377 bool ListenSocket::IsClosed() { | 400 bool ListenSocket::IsClosed() { |
378 return closing_ && !HasPendingAccept(); | 401 return closing_ && !HasPendingAccept(); |
379 } | 402 } |
380 | 403 |
381 | 404 |
382 int ClientSocket::Available() { | 405 int Handle::Available() { |
383 ScopedLock lock(this); | 406 ScopedLock lock(this); |
384 if (data_ready_ == NULL) return 0; | 407 if (data_ready_ == NULL) return 0; |
385 ASSERT(!data_ready_->IsEmpty()); | 408 ASSERT(!data_ready_->IsEmpty()); |
386 return data_ready_->GetRemainingLength(); | 409 return data_ready_->GetRemainingLength(); |
387 } | 410 } |
388 | 411 |
389 | 412 |
390 int ClientSocket::Read(void* buffer, int num_bytes) { | 413 int Handle::Read(void* buffer, int num_bytes) { |
391 ScopedLock lock(this); | 414 ScopedLock lock(this); |
392 if (data_ready_ == NULL) return 0; | 415 if (data_ready_ == NULL) return 0; |
393 num_bytes = data_ready_->Read(buffer, num_bytes); | 416 num_bytes = data_ready_->Read(buffer, num_bytes); |
394 if (data_ready_->IsEmpty()) { | 417 if (data_ready_->IsEmpty()) { |
395 IOBuffer::DisposeBuffer(data_ready_); | 418 IOBuffer::DisposeBuffer(data_ready_); |
396 data_ready_ = NULL; | 419 data_ready_ = NULL; |
397 } | 420 } |
398 return num_bytes; | 421 return num_bytes; |
399 } | 422 } |
400 | 423 |
401 | 424 |
402 int ClientSocket::Write(const void* buffer, int num_bytes) { | 425 int Handle::Write(const void* buffer, int num_bytes) { |
403 ScopedLock lock(this); | 426 ScopedLock lock(this); |
404 if (pending_write_ != NULL) return 0; | 427 if (pending_write_ != NULL) return 0; |
405 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; | 428 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; |
406 if (num_bytes > 4096) num_bytes = 4096; | 429 if (num_bytes > 4096) num_bytes = 4096; |
407 pending_write_ = IOBuffer::AllocateWriteBuffer(num_bytes); | 430 pending_write_ = IOBuffer::AllocateWriteBuffer(num_bytes); |
408 pending_write_->Write(buffer, num_bytes); | 431 pending_write_->Write(buffer, num_bytes); |
409 IssueWrite(); | 432 IssueWrite(); |
410 return num_bytes; | 433 return num_bytes; |
411 } | 434 } |
412 | 435 |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 // not NULL then it did dequeue a request which failed. | 760 // not NULL then it did dequeue a request which failed. |
738 | 761 |
739 // Treat ERROR_CONNECTION_ABORTED as connection closed. | 762 // Treat ERROR_CONNECTION_ABORTED as connection closed. |
740 // The error ERROR_OPERATION_ABORTED is set for pending | 763 // The error ERROR_OPERATION_ABORTED is set for pending |
741 // accept requests for a listen socket which is closed. | 764 // accept requests for a listen socket which is closed. |
742 // ERROR_NETNAME_DELETED occurs when the client closes | 765 // ERROR_NETNAME_DELETED occurs when the client closes |
743 // the socket it is reading from. | 766 // the socket it is reading from. |
744 DWORD last_error = GetLastError(); | 767 DWORD last_error = GetLastError(); |
745 if (last_error == ERROR_CONNECTION_ABORTED || | 768 if (last_error == ERROR_CONNECTION_ABORTED || |
746 last_error == ERROR_OPERATION_ABORTED || | 769 last_error == ERROR_OPERATION_ABORTED || |
747 last_error == ERROR_NETNAME_DELETED) { | 770 last_error == ERROR_NETNAME_DELETED || |
| 771 last_error == ERROR_BROKEN_PIPE) { |
748 ASSERT(bytes == 0); | 772 ASSERT(bytes == 0); |
749 handler->HandleIOCompletion(bytes, key, overlapped); | 773 handler->HandleIOCompletion(bytes, key, overlapped); |
750 } else { | 774 } else { |
751 printf("After GetQueuedCompletionStatus %d\n", GetLastError()); | |
752 UNREACHABLE(); | 775 UNREACHABLE(); |
753 } | 776 } |
754 } else if (key == NULL) { | 777 } else if (key == NULL) { |
755 // A key of NULL signals an interrupt message. | 778 // A key of NULL signals an interrupt message. |
756 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(overlapped); | 779 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(overlapped); |
757 handler->HandleInterrupt(msg); | 780 handler->HandleInterrupt(msg); |
758 delete msg; | 781 delete msg; |
759 } else { | 782 } else { |
760 handler->HandleIOCompletion(bytes, key, overlapped); | 783 handler->HandleIOCompletion(bytes, key, overlapped); |
761 } | 784 } |
762 } | 785 } |
763 } | 786 } |
764 | 787 |
765 | 788 |
766 void EventHandlerImplementation::StartEventHandler() { | 789 void EventHandlerImplementation::StartEventHandler() { |
767 uint32_t tid; | 790 uint32_t tid; |
768 uintptr_t thread_handle = | 791 uintptr_t thread_handle = |
769 _beginthreadex(NULL, 32 * 1024, EventHandlerThread, this, 0, &tid); | 792 _beginthreadex(NULL, 32 * 1024, EventHandlerThread, this, 0, &tid); |
770 if (thread_handle == -1) { | 793 if (thread_handle == -1) { |
771 FATAL("Failed to start event handler thread"); | 794 FATAL("Failed to start event handler thread"); |
772 } | 795 } |
773 | 796 |
774 // Initialize Winsock32 | 797 // Initialize Winsock32 |
775 if (!Socket::Initialize()) { | 798 if (!Socket::Initialize()) { |
776 FATAL("Failed to initialized Windows sockets"); | 799 FATAL("Failed to initialized Windows sockets"); |
777 } | 800 } |
778 } | 801 } |
OLD | NEW |