| 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 | 
|---|