| 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(TARGET_OS_WINDOWS) | 8 #if defined(TARGET_OS_WINDOWS) |
| 9 | 9 |
| 10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
| 11 #include "bin/eventhandler_win.h" | 11 #include "bin/eventhandler_win.h" |
| 12 | 12 |
| 13 #include <fcntl.h> // NOLINT | 13 #include <fcntl.h> // NOLINT |
| 14 #include <io.h> // NOLINT | 14 #include <io.h> // NOLINT |
| 15 #include <mswsock.h> // NOLINT | 15 #include <mswsock.h> // NOLINT |
| 16 #include <winsock2.h> // NOLINT | 16 #include <winsock2.h> // NOLINT |
| 17 #include <ws2tcpip.h> // NOLINT | 17 #include <ws2tcpip.h> // NOLINT |
| 18 | 18 |
| 19 #include "bin/builtin.h" | 19 #include "bin/builtin.h" |
| 20 #include "bin/dartutils.h" | 20 #include "bin/dartutils.h" |
| 21 #include "bin/lockers.h" | 21 #include "bin/lockers.h" |
| 22 #include "bin/log.h" | 22 #include "bin/log.h" |
| 23 #include "bin/socket.h" | 23 #include "bin/socket.h" |
| 24 #include "bin/thread.h" | 24 #include "bin/thread.h" |
| 25 #include "bin/utils.h" | 25 #include "bin/utils.h" |
| 26 | 26 |
| 27 #include "platform/utils.h" | 27 #include "platform/utils.h" |
| 28 | 28 |
| 29 namespace dart { | 29 namespace dart { |
| 30 namespace bin { | 30 namespace bin { |
| 31 | 31 |
| 32 static const int kBufferSize = 64 * 1024; | 32 static const int kBufferSize = 64 * 1024; |
| 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 | 43 |
| 44 OverlappedBuffer* OverlappedBuffer::AllocateAcceptBuffer(int buffer_size) { | 44 OverlappedBuffer* OverlappedBuffer::AllocateAcceptBuffer(int buffer_size) { |
| 45 OverlappedBuffer* buffer = AllocateBuffer(buffer_size, kAccept); | 45 OverlappedBuffer* buffer = AllocateBuffer(buffer_size, kAccept); |
| 46 return buffer; | 46 return buffer; |
| 47 } | 47 } |
| 48 | 48 |
| 49 | 49 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 event_handler_(NULL), | 122 event_handler_(NULL), |
| 123 data_ready_(NULL), | 123 data_ready_(NULL), |
| 124 pending_read_(NULL), | 124 pending_read_(NULL), |
| 125 pending_write_(NULL), | 125 pending_write_(NULL), |
| 126 last_error_(NOERROR), | 126 last_error_(NOERROR), |
| 127 flags_(0), | 127 flags_(0), |
| 128 read_thread_id_(Thread::kInvalidThreadId), | 128 read_thread_id_(Thread::kInvalidThreadId), |
| 129 read_thread_handle_(NULL), | 129 read_thread_handle_(NULL), |
| 130 read_thread_starting_(false), | 130 read_thread_starting_(false), |
| 131 read_thread_finished_(false), | 131 read_thread_finished_(false), |
| 132 monitor_(new Monitor()) { | 132 monitor_(new Monitor()) {} |
| 133 } | |
| 134 | 133 |
| 135 | 134 |
| 136 Handle::~Handle() { | 135 Handle::~Handle() { |
| 137 delete monitor_; | 136 delete monitor_; |
| 138 } | 137 } |
| 139 | 138 |
| 140 | 139 |
| 141 bool Handle::CreateCompletionPort(HANDLE completion_port) { | 140 bool Handle::CreateCompletionPort(HANDLE completion_port) { |
| 142 completion_port_ = CreateIoCompletionPort(handle(), | 141 completion_port_ = CreateIoCompletionPort( |
| 143 completion_port, | 142 handle(), completion_port, reinterpret_cast<ULONG_PTR>(this), 0); |
| 144 reinterpret_cast<ULONG_PTR>(this), | |
| 145 0); | |
| 146 return (completion_port_ != NULL); | 143 return (completion_port_ != NULL); |
| 147 } | 144 } |
| 148 | 145 |
| 149 | 146 |
| 150 void Handle::Close() { | 147 void Handle::Close() { |
| 151 MonitorLocker ml(monitor_); | 148 MonitorLocker ml(monitor_); |
| 152 if (!IsClosing()) { | 149 if (!IsClosing()) { |
| 153 // Close the socket and set the closing state. This close method can be | 150 // Close the socket and set the closing state. This close method can be |
| 154 // called again if this socket has pending IO operations in flight. | 151 // called again if this socket has pending IO operations in flight. |
| 155 MarkClosing(); | 152 MarkClosing(); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 NotifyReadThreadStarted(); | 270 NotifyReadThreadStarted(); |
| 274 ASSERT(pending_read_ != NULL); | 271 ASSERT(pending_read_ != NULL); |
| 275 ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize); | 272 ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize); |
| 276 | 273 |
| 277 DWORD buffer_size = pending_read_->GetBufferSize(); | 274 DWORD buffer_size = pending_read_->GetBufferSize(); |
| 278 if (GetFileType(handle_) == FILE_TYPE_CHAR) { | 275 if (GetFileType(handle_) == FILE_TYPE_CHAR) { |
| 279 buffer_size = kStdOverlappedBufferSize; | 276 buffer_size = kStdOverlappedBufferSize; |
| 280 } | 277 } |
| 281 char* buffer_start = pending_read_->GetBufferStart(); | 278 char* buffer_start = pending_read_->GetBufferStart(); |
| 282 DWORD bytes_read = 0; | 279 DWORD bytes_read = 0; |
| 283 BOOL ok = ReadFile(handle_, | 280 BOOL ok = ReadFile(handle_, buffer_start, buffer_size, &bytes_read, NULL); |
| 284 buffer_start, | |
| 285 buffer_size, | |
| 286 &bytes_read, | |
| 287 NULL); | |
| 288 if (!ok) { | 281 if (!ok) { |
| 289 bytes_read = 0; | 282 bytes_read = 0; |
| 290 } | 283 } |
| 291 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); | 284 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); |
| 292 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), | 285 ok = |
| 293 bytes_read, | 286 PostQueuedCompletionStatus(event_handler_->completion_port(), bytes_read, |
| 294 reinterpret_cast<ULONG_PTR>(this), | 287 reinterpret_cast<ULONG_PTR>(this), overlapped); |
| 295 overlapped); | |
| 296 if (!ok) { | 288 if (!ok) { |
| 297 FATAL("PostQueuedCompletionStatus failed"); | 289 FATAL("PostQueuedCompletionStatus failed"); |
| 298 } | 290 } |
| 299 NotifyReadThreadFinished(); | 291 NotifyReadThreadFinished(); |
| 300 } | 292 } |
| 301 | 293 |
| 302 | 294 |
| 303 bool Handle::IssueRead() { | 295 bool Handle::IssueRead() { |
| 304 ASSERT(type_ != kListenSocket); | 296 ASSERT(type_ != kListenSocket); |
| 305 ASSERT(pending_read_ == NULL); | 297 ASSERT(pending_read_ == NULL); |
| 306 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); | 298 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); |
| 307 if (SupportsOverlappedIO()) { | 299 if (SupportsOverlappedIO()) { |
| 308 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 300 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 309 | 301 |
| 310 BOOL ok = ReadFile(handle_, | 302 BOOL ok = |
| 311 buffer->GetBufferStart(), | 303 ReadFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), |
| 312 buffer->GetBufferSize(), | 304 NULL, buffer->GetCleanOverlapped()); |
| 313 NULL, | |
| 314 buffer->GetCleanOverlapped()); | |
| 315 if (ok || (GetLastError() == ERROR_IO_PENDING)) { | 305 if (ok || (GetLastError() == ERROR_IO_PENDING)) { |
| 316 // Completing asynchronously. | 306 // Completing asynchronously. |
| 317 pending_read_ = buffer; | 307 pending_read_ = buffer; |
| 318 return true; | 308 return true; |
| 319 } | 309 } |
| 320 OverlappedBuffer::DisposeBuffer(buffer); | 310 OverlappedBuffer::DisposeBuffer(buffer); |
| 321 HandleIssueError(); | 311 HandleIssueError(); |
| 322 return false; | 312 return false; |
| 323 } else { | 313 } else { |
| 324 // Completing asynchronously through thread. | 314 // Completing asynchronously through thread. |
| 325 pending_read_ = buffer; | 315 pending_read_ = buffer; |
| 326 read_thread_starting_ = true; | 316 read_thread_starting_ = true; |
| 327 int result = Thread::Start(ReadFileThread, | 317 int result = Thread::Start(ReadFileThread, reinterpret_cast<uword>(this)); |
| 328 reinterpret_cast<uword>(this)); | |
| 329 if (result != 0) { | 318 if (result != 0) { |
| 330 FATAL1("Failed to start read file thread %d", result); | 319 FATAL1("Failed to start read file thread %d", result); |
| 331 } | 320 } |
| 332 return true; | 321 return true; |
| 333 } | 322 } |
| 334 } | 323 } |
| 335 | 324 |
| 336 | 325 |
| 337 bool Handle::IssueRecvFrom() { | 326 bool Handle::IssueRecvFrom() { |
| 338 return false; | 327 return false; |
| 339 } | 328 } |
| 340 | 329 |
| 341 | 330 |
| 342 bool Handle::IssueWrite() { | 331 bool Handle::IssueWrite() { |
| 343 MonitorLocker ml(monitor_); | 332 MonitorLocker ml(monitor_); |
| 344 ASSERT(type_ != kListenSocket); | 333 ASSERT(type_ != kListenSocket); |
| 345 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 334 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 346 ASSERT(pending_write_ != NULL); | 335 ASSERT(pending_write_ != NULL); |
| 347 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); | 336 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); |
| 348 | 337 |
| 349 OverlappedBuffer* buffer = pending_write_; | 338 OverlappedBuffer* buffer = pending_write_; |
| 350 BOOL ok = WriteFile(handle_, | 339 BOOL ok = |
| 351 buffer->GetBufferStart(), | 340 WriteFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), |
| 352 buffer->GetBufferSize(), | 341 NULL, buffer->GetCleanOverlapped()); |
| 353 NULL, | |
| 354 buffer->GetCleanOverlapped()); | |
| 355 if (ok || (GetLastError() == ERROR_IO_PENDING)) { | 342 if (ok || (GetLastError() == ERROR_IO_PENDING)) { |
| 356 // Completing asynchronously. | 343 // Completing asynchronously. |
| 357 pending_write_ = buffer; | 344 pending_write_ = buffer; |
| 358 return true; | 345 return true; |
| 359 } | 346 } |
| 360 OverlappedBuffer::DisposeBuffer(buffer); | 347 OverlappedBuffer::DisposeBuffer(buffer); |
| 361 HandleIssueError(); | 348 HandleIssueError(); |
| 362 return false; | 349 return false; |
| 363 } | 350 } |
| 364 | 351 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 | 413 |
| 427 | 414 |
| 428 bool DirectoryWatchHandle::IssueRead() { | 415 bool DirectoryWatchHandle::IssueRead() { |
| 429 // It may have been started before, as we start the directory-handler when | 416 // It may have been started before, as we start the directory-handler when |
| 430 // we create it. | 417 // we create it. |
| 431 if ((pending_read_ != NULL) || (data_ready_ != NULL)) { | 418 if ((pending_read_ != NULL) || (data_ready_ != NULL)) { |
| 432 return true; | 419 return true; |
| 433 } | 420 } |
| 434 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); | 421 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); |
| 435 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 422 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 436 BOOL ok = ReadDirectoryChangesW(handle_, | 423 BOOL ok = ReadDirectoryChangesW(handle_, buffer->GetBufferStart(), |
| 437 buffer->GetBufferStart(), | 424 buffer->GetBufferSize(), recursive_, events_, |
| 438 buffer->GetBufferSize(), | 425 NULL, buffer->GetCleanOverlapped(), NULL); |
| 439 recursive_, | |
| 440 events_, | |
| 441 NULL, | |
| 442 buffer->GetCleanOverlapped(), | |
| 443 NULL); | |
| 444 if (ok || (GetLastError() == ERROR_IO_PENDING)) { | 426 if (ok || (GetLastError() == ERROR_IO_PENDING)) { |
| 445 // Completing asynchronously. | 427 // Completing asynchronously. |
| 446 pending_read_ = buffer; | 428 pending_read_ = buffer; |
| 447 return true; | 429 return true; |
| 448 } | 430 } |
| 449 OverlappedBuffer::DisposeBuffer(buffer); | 431 OverlappedBuffer::DisposeBuffer(buffer); |
| 450 return false; | 432 return false; |
| 451 } | 433 } |
| 452 | 434 |
| 453 | 435 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 472 HandleError(this); | 454 HandleError(this); |
| 473 } | 455 } |
| 474 WSASetLastError(error); | 456 WSASetLastError(error); |
| 475 } | 457 } |
| 476 | 458 |
| 477 | 459 |
| 478 bool ListenSocket::LoadAcceptEx() { | 460 bool ListenSocket::LoadAcceptEx() { |
| 479 // Load the AcceptEx function into memory using WSAIoctl. | 461 // Load the AcceptEx function into memory using WSAIoctl. |
| 480 GUID guid_accept_ex = WSAID_ACCEPTEX; | 462 GUID guid_accept_ex = WSAID_ACCEPTEX; |
| 481 DWORD bytes; | 463 DWORD bytes; |
| 482 int status = WSAIoctl(socket(), | 464 int status = WSAIoctl(socket(), SIO_GET_EXTENSION_FUNCTION_POINTER, |
| 483 SIO_GET_EXTENSION_FUNCTION_POINTER, | 465 &guid_accept_ex, sizeof(guid_accept_ex), &AcceptEx_, |
| 484 &guid_accept_ex, | 466 sizeof(AcceptEx_), &bytes, NULL, NULL); |
| 485 sizeof(guid_accept_ex), | |
| 486 &AcceptEx_, | |
| 487 sizeof(AcceptEx_), | |
| 488 &bytes, | |
| 489 NULL, | |
| 490 NULL); | |
| 491 return (status != SOCKET_ERROR); | 467 return (status != SOCKET_ERROR); |
| 492 } | 468 } |
| 493 | 469 |
| 494 | 470 |
| 495 bool ListenSocket::IssueAccept() { | 471 bool ListenSocket::IssueAccept() { |
| 496 MonitorLocker ml(monitor_); | 472 MonitorLocker ml(monitor_); |
| 497 | 473 |
| 498 // For AcceptEx there needs to be buffer storage for address | 474 // For AcceptEx there needs to be buffer storage for address |
| 499 // information for two addresses (local and remote address). The | 475 // information for two addresses (local and remote address). The |
| 500 // AcceptEx documentation says: "This value must be at least 16 | 476 // AcceptEx documentation says: "This value must be at least 16 |
| 501 // bytes more than the maximum address length for the transport | 477 // bytes more than the maximum address length for the transport |
| 502 // protocol in use." | 478 // protocol in use." |
| 503 static const int kAcceptExAddressAdditionalBytes = 16; | 479 static const int kAcceptExAddressAdditionalBytes = 16; |
| 504 static const int kAcceptExAddressStorageSize = | 480 static const int kAcceptExAddressStorageSize = |
| 505 sizeof(SOCKADDR_STORAGE) + kAcceptExAddressAdditionalBytes; | 481 sizeof(SOCKADDR_STORAGE) + kAcceptExAddressAdditionalBytes; |
| 506 OverlappedBuffer* buffer = | 482 OverlappedBuffer* buffer = |
| 507 OverlappedBuffer::AllocateAcceptBuffer(2 * kAcceptExAddressStorageSize); | 483 OverlappedBuffer::AllocateAcceptBuffer(2 * kAcceptExAddressStorageSize); |
| 508 DWORD received; | 484 DWORD received; |
| 509 BOOL ok; | 485 BOOL ok; |
| 510 ok = AcceptEx_(socket(), | 486 ok = AcceptEx_(socket(), buffer->client(), buffer->GetBufferStart(), |
| 511 buffer->client(), | |
| 512 buffer->GetBufferStart(), | |
| 513 0, // For now don't receive data with accept. | 487 0, // For now don't receive data with accept. |
| 514 kAcceptExAddressStorageSize, | 488 kAcceptExAddressStorageSize, kAcceptExAddressStorageSize, |
| 515 kAcceptExAddressStorageSize, | 489 &received, buffer->GetCleanOverlapped()); |
| 516 &received, | |
| 517 buffer->GetCleanOverlapped()); | |
| 518 if (!ok) { | 490 if (!ok) { |
| 519 if (WSAGetLastError() != WSA_IO_PENDING) { | 491 if (WSAGetLastError() != WSA_IO_PENDING) { |
| 520 int error = WSAGetLastError(); | 492 int error = WSAGetLastError(); |
| 521 closesocket(buffer->client()); | 493 closesocket(buffer->client()); |
| 522 OverlappedBuffer::DisposeBuffer(buffer); | 494 OverlappedBuffer::DisposeBuffer(buffer); |
| 523 WSASetLastError(error); | 495 WSASetLastError(error); |
| 524 return false; | 496 return false; |
| 525 } | 497 } |
| 526 } | 498 } |
| 527 | 499 |
| 528 pending_accept_count_++; | 500 pending_accept_count_++; |
| 529 | 501 |
| 530 return true; | 502 return true; |
| 531 } | 503 } |
| 532 | 504 |
| 533 | 505 |
| 534 void ListenSocket::AcceptComplete(OverlappedBuffer* buffer, | 506 void ListenSocket::AcceptComplete(OverlappedBuffer* buffer, |
| 535 HANDLE completion_port) { | 507 HANDLE completion_port) { |
| 536 MonitorLocker ml(monitor_); | 508 MonitorLocker ml(monitor_); |
| 537 if (!IsClosing()) { | 509 if (!IsClosing()) { |
| 538 // Update the accepted socket to support the full range of API calls. | 510 // Update the accepted socket to support the full range of API calls. |
| 539 SOCKET s = socket(); | 511 SOCKET s = socket(); |
| 540 int rc = setsockopt(buffer->client(), | 512 int rc = setsockopt(buffer->client(), SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, |
| 541 SOL_SOCKET, | |
| 542 SO_UPDATE_ACCEPT_CONTEXT, | |
| 543 reinterpret_cast<char*>(&s), sizeof(s)); | 513 reinterpret_cast<char*>(&s), sizeof(s)); |
| 544 if (rc == NO_ERROR) { | 514 if (rc == NO_ERROR) { |
| 545 // Insert the accepted socket into the list. | 515 // Insert the accepted socket into the list. |
| 546 ClientSocket* client_socket = new ClientSocket(buffer->client()); | 516 ClientSocket* client_socket = new ClientSocket(buffer->client()); |
| 547 client_socket->mark_connected(); | 517 client_socket->mark_connected(); |
| 548 client_socket->CreateCompletionPort(completion_port); | 518 client_socket->CreateCompletionPort(completion_port); |
| 549 if (accepted_head_ == NULL) { | 519 if (accepted_head_ == NULL) { |
| 550 accepted_head_ = client_socket; | 520 accepted_head_ = client_socket; |
| 551 accepted_tail_ = client_socket; | 521 accepted_tail_ = client_socket; |
| 552 } else { | 522 } else { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 575 delete handle; | 545 delete handle; |
| 576 } | 546 } |
| 577 } | 547 } |
| 578 | 548 |
| 579 | 549 |
| 580 void ListenSocket::DoClose() { | 550 void ListenSocket::DoClose() { |
| 581 closesocket(socket()); | 551 closesocket(socket()); |
| 582 handle_ = INVALID_HANDLE_VALUE; | 552 handle_ = INVALID_HANDLE_VALUE; |
| 583 while (CanAccept()) { | 553 while (CanAccept()) { |
| 584 // Get rid of connections already accepted. | 554 // Get rid of connections already accepted. |
| 585 ClientSocket *client = Accept(); | 555 ClientSocket* client = Accept(); |
| 586 if (client != NULL) { | 556 if (client != NULL) { |
| 587 client->Close(); | 557 client->Close(); |
| 588 DeleteIfClosed(client); | 558 DeleteIfClosed(client); |
| 589 } else { | 559 } else { |
| 590 break; | 560 break; |
| 591 } | 561 } |
| 592 } | 562 } |
| 593 } | 563 } |
| 594 | 564 |
| 595 | 565 |
| 596 bool ListenSocket::CanAccept() { | 566 bool ListenSocket::CanAccept() { |
| 597 MonitorLocker ml(monitor_); | 567 MonitorLocker ml(monitor_); |
| 598 return accepted_head_ != NULL; | 568 return accepted_head_ != NULL; |
| 599 } | 569 } |
| 600 | 570 |
| 601 | 571 |
| 602 ClientSocket* ListenSocket::Accept() { | 572 ClientSocket* ListenSocket::Accept() { |
| 603 MonitorLocker ml(monitor_); | 573 MonitorLocker ml(monitor_); |
| 604 | 574 |
| 605 ClientSocket *result = NULL; | 575 ClientSocket* result = NULL; |
| 606 | 576 |
| 607 if (accepted_head_ != NULL) { | 577 if (accepted_head_ != NULL) { |
| 608 result = accepted_head_; | 578 result = accepted_head_; |
| 609 accepted_head_ = accepted_head_->next(); | 579 accepted_head_ = accepted_head_->next(); |
| 610 if (accepted_head_ == NULL) { | 580 if (accepted_head_ == NULL) { |
| 611 accepted_tail_ = NULL; | 581 accepted_tail_ = NULL; |
| 612 } | 582 } |
| 613 result->set_next(NULL); | 583 result->set_next(NULL); |
| 614 accepted_count_--; | 584 accepted_count_--; |
| 615 } | 585 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 ASSERT(!data_ready_->IsEmpty()); | 623 ASSERT(!data_ready_->IsEmpty()); |
| 654 return data_ready_->GetRemainingLength(); | 624 return data_ready_->GetRemainingLength(); |
| 655 } | 625 } |
| 656 | 626 |
| 657 | 627 |
| 658 intptr_t Handle::Read(void* buffer, intptr_t num_bytes) { | 628 intptr_t Handle::Read(void* buffer, intptr_t num_bytes) { |
| 659 MonitorLocker ml(monitor_); | 629 MonitorLocker ml(monitor_); |
| 660 if (data_ready_ == NULL) { | 630 if (data_ready_ == NULL) { |
| 661 return 0; | 631 return 0; |
| 662 } | 632 } |
| 663 num_bytes = data_ready_->Read( | 633 num_bytes = |
| 664 buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); | 634 data_ready_->Read(buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); |
| 665 if (data_ready_->IsEmpty()) { | 635 if (data_ready_->IsEmpty()) { |
| 666 OverlappedBuffer::DisposeBuffer(data_ready_); | 636 OverlappedBuffer::DisposeBuffer(data_ready_); |
| 667 data_ready_ = NULL; | 637 data_ready_ = NULL; |
| 668 if (!IsClosing() && !IsClosedRead()) { | 638 if (!IsClosing() && !IsClosedRead()) { |
| 669 IssueRead(); | 639 IssueRead(); |
| 670 } | 640 } |
| 671 } | 641 } |
| 672 return num_bytes; | 642 return num_bytes; |
| 673 } | 643 } |
| 674 | 644 |
| 675 | 645 |
| 676 intptr_t Handle::RecvFrom( | 646 intptr_t Handle::RecvFrom(void* buffer, |
| 677 void* buffer, intptr_t num_bytes, struct sockaddr* sa, socklen_t sa_len) { | 647 intptr_t num_bytes, |
| 648 struct sockaddr* sa, |
| 649 socklen_t sa_len) { |
| 678 MonitorLocker ml(monitor_); | 650 MonitorLocker ml(monitor_); |
| 679 if (data_ready_ == NULL) { | 651 if (data_ready_ == NULL) { |
| 680 return 0; | 652 return 0; |
| 681 } | 653 } |
| 682 num_bytes = data_ready_->Read( | 654 num_bytes = |
| 683 buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); | 655 data_ready_->Read(buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); |
| 684 if (data_ready_->from()->sa_family == AF_INET) { | 656 if (data_ready_->from()->sa_family == AF_INET) { |
| 685 ASSERT(sa_len >= sizeof(struct sockaddr_in)); | 657 ASSERT(sa_len >= sizeof(struct sockaddr_in)); |
| 686 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); | 658 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); |
| 687 } else { | 659 } else { |
| 688 ASSERT(data_ready_->from()->sa_family == AF_INET6); | 660 ASSERT(data_ready_->from()->sa_family == AF_INET6); |
| 689 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); | 661 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); |
| 690 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); | 662 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); |
| 691 } | 663 } |
| 692 // Always dispose of the buffer, as UDP messages must be read in their | 664 // Always dispose of the buffer, as UDP messages must be read in their |
| 693 // entirety to match how recvfrom works in a socket. | 665 // entirety to match how recvfrom works in a socket. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 | 742 |
| 771 write_thread_exists_ = false; | 743 write_thread_exists_ = false; |
| 772 ml.Notify(); | 744 ml.Notify(); |
| 773 } | 745 } |
| 774 | 746 |
| 775 | 747 |
| 776 void StdHandle::WriteSyncCompleteAsync() { | 748 void StdHandle::WriteSyncCompleteAsync() { |
| 777 ASSERT(pending_write_ != NULL); | 749 ASSERT(pending_write_ != NULL); |
| 778 | 750 |
| 779 DWORD bytes_written = -1; | 751 DWORD bytes_written = -1; |
| 780 BOOL ok = WriteFile(handle_, | 752 BOOL ok = WriteFile(handle_, pending_write_->GetBufferStart(), |
| 781 pending_write_->GetBufferStart(), | 753 pending_write_->GetBufferSize(), &bytes_written, NULL); |
| 782 pending_write_->GetBufferSize(), | |
| 783 &bytes_written, | |
| 784 NULL); | |
| 785 if (!ok) { | 754 if (!ok) { |
| 786 bytes_written = 0; | 755 bytes_written = 0; |
| 787 } | 756 } |
| 788 thread_wrote_ += bytes_written; | 757 thread_wrote_ += bytes_written; |
| 789 OVERLAPPED* overlapped = pending_write_->GetCleanOverlapped(); | 758 OVERLAPPED* overlapped = pending_write_->GetCleanOverlapped(); |
| 790 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), | 759 ok = PostQueuedCompletionStatus( |
| 791 bytes_written, | 760 event_handler_->completion_port(), bytes_written, |
| 792 reinterpret_cast<ULONG_PTR>(this), | 761 reinterpret_cast<ULONG_PTR>(this), overlapped); |
| 793 overlapped); | |
| 794 if (!ok) { | 762 if (!ok) { |
| 795 FATAL("PostQueuedCompletionStatus failed"); | 763 FATAL("PostQueuedCompletionStatus failed"); |
| 796 } | 764 } |
| 797 } | 765 } |
| 798 | 766 |
| 799 intptr_t StdHandle::Write(const void* buffer, intptr_t num_bytes) { | 767 intptr_t StdHandle::Write(const void* buffer, intptr_t num_bytes) { |
| 800 MonitorLocker ml(monitor_); | 768 MonitorLocker ml(monitor_); |
| 801 if (pending_write_ != NULL) { | 769 if (pending_write_ != NULL) { |
| 802 return 0; | 770 return 0; |
| 803 } | 771 } |
| 804 if (num_bytes > kBufferSize) { | 772 if (num_bytes > kBufferSize) { |
| 805 num_bytes = kBufferSize; | 773 num_bytes = kBufferSize; |
| 806 } | 774 } |
| 807 // In the case of stdout and stderr, OverlappedIO is not supported. | 775 // In the case of stdout and stderr, OverlappedIO is not supported. |
| 808 // Here we'll instead use a thread, to make it async. | 776 // Here we'll instead use a thread, to make it async. |
| 809 // This code is actually never exposed to the user, as stdout and stderr is | 777 // This code is actually never exposed to the user, as stdout and stderr is |
| 810 // not available as a RawSocket, but only wrapped in a Socket. | 778 // not available as a RawSocket, but only wrapped in a Socket. |
| 811 // Note that we return '0', unless a thread have already completed a write. | 779 // Note that we return '0', unless a thread have already completed a write. |
| 812 if (thread_wrote_ > 0) { | 780 if (thread_wrote_ > 0) { |
| 813 if (num_bytes > thread_wrote_) { | 781 if (num_bytes > thread_wrote_) { |
| 814 num_bytes = thread_wrote_; | 782 num_bytes = thread_wrote_; |
| 815 } | 783 } |
| 816 thread_wrote_ -= num_bytes; | 784 thread_wrote_ -= num_bytes; |
| 817 return num_bytes; | 785 return num_bytes; |
| 818 } | 786 } |
| 819 if (!write_thread_exists_) { | 787 if (!write_thread_exists_) { |
| 820 write_thread_exists_ = true; | 788 write_thread_exists_ = true; |
| 821 int result = Thread::Start( | 789 int result = Thread::Start(WriteFileThread, reinterpret_cast<uword>(this)); |
| 822 WriteFileThread, reinterpret_cast<uword>(this)); | |
| 823 if (result != 0) { | 790 if (result != 0) { |
| 824 FATAL1("Failed to start write file thread %d", result); | 791 FATAL1("Failed to start write file thread %d", result); |
| 825 } | 792 } |
| 826 while (!write_thread_running_) { | 793 while (!write_thread_running_) { |
| 827 // Wait until we the thread is running. | 794 // Wait until we the thread is running. |
| 828 ml.Wait(Monitor::kNoTimeout); | 795 ml.Wait(Monitor::kNoTimeout); |
| 829 } | 796 } |
| 830 } | 797 } |
| 831 // Only queue up to INT_MAX bytes. | 798 // Only queue up to INT_MAX bytes. |
| 832 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); | 799 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 852 ASSERT(res == WAIT_OBJECT_0); | 819 ASSERT(res == WAIT_OBJECT_0); |
| 853 } | 820 } |
| 854 Handle::DoClose(); | 821 Handle::DoClose(); |
| 855 } | 822 } |
| 856 | 823 |
| 857 | 824 |
| 858 bool ClientSocket::LoadDisconnectEx() { | 825 bool ClientSocket::LoadDisconnectEx() { |
| 859 // Load the DisconnectEx function into memory using WSAIoctl. | 826 // Load the DisconnectEx function into memory using WSAIoctl. |
| 860 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; | 827 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; |
| 861 DWORD bytes; | 828 DWORD bytes; |
| 862 int status = WSAIoctl(socket(), | 829 int status = |
| 863 SIO_GET_EXTENSION_FUNCTION_POINTER, | 830 WSAIoctl(socket(), SIO_GET_EXTENSION_FUNCTION_POINTER, |
| 864 &guid_disconnect_ex, | 831 &guid_disconnect_ex, sizeof(guid_disconnect_ex), &DisconnectEx_, |
| 865 sizeof(guid_disconnect_ex), | 832 sizeof(DisconnectEx_), &bytes, NULL, NULL); |
| 866 &DisconnectEx_, | |
| 867 sizeof(DisconnectEx_), | |
| 868 &bytes, | |
| 869 NULL, | |
| 870 NULL); | |
| 871 return (status != SOCKET_ERROR); | 833 return (status != SOCKET_ERROR); |
| 872 } | 834 } |
| 873 | 835 |
| 874 | 836 |
| 875 void ClientSocket::Shutdown(int how) { | 837 void ClientSocket::Shutdown(int how) { |
| 876 int rc = shutdown(socket(), how); | 838 int rc = shutdown(socket(), how); |
| 877 if (how == SD_RECEIVE) { | 839 if (how == SD_RECEIVE) { |
| 878 MarkClosedRead(); | 840 MarkClosedRead(); |
| 879 } | 841 } |
| 880 if (how == SD_SEND) { | 842 if (how == SD_SEND) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 899 MonitorLocker ml(monitor_); | 861 MonitorLocker ml(monitor_); |
| 900 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 862 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 901 ASSERT(pending_read_ == NULL); | 863 ASSERT(pending_read_ == NULL); |
| 902 | 864 |
| 903 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can | 865 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can |
| 904 // handle 64k datagrams. | 866 // handle 64k datagrams. |
| 905 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(65536); | 867 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(65536); |
| 906 | 868 |
| 907 DWORD flags; | 869 DWORD flags; |
| 908 flags = 0; | 870 flags = 0; |
| 909 int rc = WSARecv(socket(), | 871 int rc = WSARecv(socket(), buffer->GetWASBUF(), 1, NULL, &flags, |
| 910 buffer->GetWASBUF(), | 872 buffer->GetCleanOverlapped(), NULL); |
| 911 1, | |
| 912 NULL, | |
| 913 &flags, | |
| 914 buffer->GetCleanOverlapped(), | |
| 915 NULL); | |
| 916 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 873 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
| 917 pending_read_ = buffer; | 874 pending_read_ = buffer; |
| 918 return true; | 875 return true; |
| 919 } | 876 } |
| 920 OverlappedBuffer::DisposeBuffer(buffer); | 877 OverlappedBuffer::DisposeBuffer(buffer); |
| 921 pending_read_ = NULL; | 878 pending_read_ = NULL; |
| 922 HandleIssueError(); | 879 HandleIssueError(); |
| 923 return false; | 880 return false; |
| 924 } | 881 } |
| 925 | 882 |
| 926 | 883 |
| 927 bool ClientSocket::IssueWrite() { | 884 bool ClientSocket::IssueWrite() { |
| 928 MonitorLocker ml(monitor_); | 885 MonitorLocker ml(monitor_); |
| 929 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 886 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 930 ASSERT(pending_write_ != NULL); | 887 ASSERT(pending_write_ != NULL); |
| 931 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); | 888 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); |
| 932 | 889 |
| 933 int rc = WSASend(socket(), | 890 int rc = WSASend(socket(), pending_write_->GetWASBUF(), 1, NULL, 0, |
| 934 pending_write_->GetWASBUF(), | 891 pending_write_->GetCleanOverlapped(), NULL); |
| 935 1, | |
| 936 NULL, | |
| 937 0, | |
| 938 pending_write_->GetCleanOverlapped(), | |
| 939 NULL); | |
| 940 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 892 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
| 941 return true; | 893 return true; |
| 942 } | 894 } |
| 943 OverlappedBuffer::DisposeBuffer(pending_write_); | 895 OverlappedBuffer::DisposeBuffer(pending_write_); |
| 944 pending_write_ = NULL; | 896 pending_write_ = NULL; |
| 945 HandleIssueError(); | 897 HandleIssueError(); |
| 946 return false; | 898 return false; |
| 947 } | 899 } |
| 948 | 900 |
| 949 | 901 |
| 950 void ClientSocket::IssueDisconnect() { | 902 void ClientSocket::IssueDisconnect() { |
| 951 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); | 903 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); |
| 952 BOOL ok = DisconnectEx_( | 904 BOOL ok = |
| 953 socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); | 905 DisconnectEx_(socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); |
| 954 // DisconnectEx works like other OverlappedIO APIs, where we can get either an | 906 // DisconnectEx works like other OverlappedIO APIs, where we can get either an |
| 955 // immediate success or delayed operation by WSA_IO_PENDING being set. | 907 // immediate success or delayed operation by WSA_IO_PENDING being set. |
| 956 if (ok || (WSAGetLastError() != WSA_IO_PENDING)) { | 908 if (ok || (WSAGetLastError() != WSA_IO_PENDING)) { |
| 957 DisconnectComplete(buffer); | 909 DisconnectComplete(buffer); |
| 958 } | 910 } |
| 959 NotifyAllDartPorts(1 << kDestroyedEvent); | 911 NotifyAllDartPorts(1 << kDestroyedEvent); |
| 960 RemoveAllPorts(); | 912 RemoveAllPorts(); |
| 961 } | 913 } |
| 962 | 914 |
| 963 | 915 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1002 return connected_ && closed_; | 954 return connected_ && closed_; |
| 1003 } | 955 } |
| 1004 | 956 |
| 1005 | 957 |
| 1006 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { | 958 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { |
| 1007 MonitorLocker ml(monitor_); | 959 MonitorLocker ml(monitor_); |
| 1008 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 960 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 1009 ASSERT(pending_write_ != NULL); | 961 ASSERT(pending_write_ != NULL); |
| 1010 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); | 962 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); |
| 1011 | 963 |
| 1012 int rc = WSASendTo(socket(), | 964 int rc = WSASendTo(socket(), pending_write_->GetWASBUF(), 1, NULL, 0, sa, |
| 1013 pending_write_->GetWASBUF(), | 965 sa_len, pending_write_->GetCleanOverlapped(), NULL); |
| 1014 1, | |
| 1015 NULL, | |
| 1016 0, | |
| 1017 sa, | |
| 1018 sa_len, | |
| 1019 pending_write_->GetCleanOverlapped(), | |
| 1020 NULL); | |
| 1021 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 966 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
| 1022 return true; | 967 return true; |
| 1023 } | 968 } |
| 1024 OverlappedBuffer::DisposeBuffer(pending_write_); | 969 OverlappedBuffer::DisposeBuffer(pending_write_); |
| 1025 pending_write_ = NULL; | 970 pending_write_ = NULL; |
| 1026 HandleIssueError(); | 971 HandleIssueError(); |
| 1027 return false; | 972 return false; |
| 1028 } | 973 } |
| 1029 | 974 |
| 1030 | 975 |
| 1031 bool DatagramSocket::IssueRecvFrom() { | 976 bool DatagramSocket::IssueRecvFrom() { |
| 1032 MonitorLocker ml(monitor_); | 977 MonitorLocker ml(monitor_); |
| 1033 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 978 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 1034 ASSERT(pending_read_ == NULL); | 979 ASSERT(pending_read_ == NULL); |
| 1035 | 980 |
| 1036 OverlappedBuffer* buffer = | 981 OverlappedBuffer* buffer = |
| 1037 OverlappedBuffer::AllocateRecvFromBuffer(kMaxUDPPackageLength); | 982 OverlappedBuffer::AllocateRecvFromBuffer(kMaxUDPPackageLength); |
| 1038 | 983 |
| 1039 DWORD flags; | 984 DWORD flags; |
| 1040 flags = 0; | 985 flags = 0; |
| 1041 int rc = WSARecvFrom(socket(), | 986 int rc = WSARecvFrom(socket(), buffer->GetWASBUF(), 1, NULL, &flags, |
| 1042 buffer->GetWASBUF(), | 987 buffer->from(), buffer->from_len_addr(), |
| 1043 1, | 988 buffer->GetCleanOverlapped(), NULL); |
| 1044 NULL, | |
| 1045 &flags, | |
| 1046 buffer->from(), | |
| 1047 buffer->from_len_addr(), | |
| 1048 buffer->GetCleanOverlapped(), | |
| 1049 NULL); | |
| 1050 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 989 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
| 1051 pending_read_ = buffer; | 990 pending_read_ = buffer; |
| 1052 return true; | 991 return true; |
| 1053 } | 992 } |
| 1054 OverlappedBuffer::DisposeBuffer(buffer); | 993 OverlappedBuffer::DisposeBuffer(buffer); |
| 1055 pending_read_ = NULL; | 994 pending_read_ = NULL; |
| 1056 HandleIssueError(); | 995 HandleIssueError(); |
| 1057 return false; | 996 return false; |
| 1058 } | 997 } |
| 1059 | 998 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1089 // Change of timeout request. Just set the new timeout and port as the | 1028 // Change of timeout request. Just set the new timeout and port as the |
| 1090 // completion thread will use the new timeout value for its next wait. | 1029 // completion thread will use the new timeout value for its next wait. |
| 1091 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); | 1030 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); |
| 1092 } else if (msg->id == kShutdownId) { | 1031 } else if (msg->id == kShutdownId) { |
| 1093 shutdown_ = true; | 1032 shutdown_ = true; |
| 1094 } else { | 1033 } else { |
| 1095 Handle* handle = reinterpret_cast<Handle*>(msg->id); | 1034 Handle* handle = reinterpret_cast<Handle*>(msg->id); |
| 1096 ASSERT(handle != NULL); | 1035 ASSERT(handle != NULL); |
| 1097 | 1036 |
| 1098 if (handle->is_listen_socket()) { | 1037 if (handle->is_listen_socket()) { |
| 1099 ListenSocket* listen_socket = | 1038 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(handle); |
| 1100 reinterpret_cast<ListenSocket*>(handle); | |
| 1101 listen_socket->EnsureInitialized(this); | 1039 listen_socket->EnsureInitialized(this); |
| 1102 | 1040 |
| 1103 MonitorLocker ml(listen_socket->monitor_); | 1041 MonitorLocker ml(listen_socket->monitor_); |
| 1104 | 1042 |
| 1105 if (IS_COMMAND(msg->data, kReturnTokenCommand)) { | 1043 if (IS_COMMAND(msg->data, kReturnTokenCommand)) { |
| 1106 listen_socket->ReturnTokens(msg->dart_port, TOKEN_COUNT(msg->data)); | 1044 listen_socket->ReturnTokens(msg->dart_port, TOKEN_COUNT(msg->data)); |
| 1107 } else if (IS_COMMAND(msg->data, kSetEventMaskCommand)) { | 1045 } else if (IS_COMMAND(msg->data, kSetEventMaskCommand)) { |
| 1108 // `events` can only have kInEvent/kOutEvent flags set. | 1046 // `events` can only have kInEvent/kOutEvent flags set. |
| 1109 intptr_t events = msg->data & EVENT_MASK; | 1047 intptr_t events = msg->data & EVENT_MASK; |
| 1110 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent))); | 1048 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent))); |
| 1111 listen_socket->SetPortAndMask(msg->dart_port, events); | 1049 listen_socket->SetPortAndMask(msg->dart_port, events); |
| 1112 TryDispatchingPendingAccepts(listen_socket); | 1050 TryDispatchingPendingAccepts(listen_socket); |
| 1113 } else if (IS_COMMAND(msg->data, kCloseCommand)) { | 1051 } else if (IS_COMMAND(msg->data, kCloseCommand)) { |
| 1114 listen_socket->RemovePort(msg->dart_port); | 1052 listen_socket->RemovePort(msg->dart_port); |
| 1115 | 1053 |
| 1116 // We only close the socket file descriptor from the operating | 1054 // We only close the socket file descriptor from the operating |
| 1117 // system if there are no other dart socket objects which | 1055 // system if there are no other dart socket objects which |
| 1118 // are listening on the same (address, port) combination. | 1056 // are listening on the same (address, port) combination. |
| 1119 ListeningSocketRegistry *registry = | 1057 ListeningSocketRegistry* registry = ListeningSocketRegistry::Instance(); |
| 1120 ListeningSocketRegistry::Instance(); | |
| 1121 MutexLocker locker(registry->mutex()); | 1058 MutexLocker locker(registry->mutex()); |
| 1122 if (registry->CloseSafe(reinterpret_cast<intptr_t>(listen_socket))) { | 1059 if (registry->CloseSafe(reinterpret_cast<intptr_t>(listen_socket))) { |
| 1123 ASSERT(listen_socket->Mask() == 0); | 1060 ASSERT(listen_socket->Mask() == 0); |
| 1124 listen_socket->Close(); | 1061 listen_socket->Close(); |
| 1125 } | 1062 } |
| 1126 | 1063 |
| 1127 DartUtils::PostInt32(msg->dart_port, 1 << kDestroyedEvent); | 1064 DartUtils::PostInt32(msg->dart_port, 1 << kDestroyedEvent); |
| 1128 } else { | 1065 } else { |
| 1129 UNREACHABLE(); | 1066 UNREACHABLE(); |
| 1130 } | 1067 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 { | 1143 { |
| 1207 MonitorLocker ml(listen_socket->monitor_); | 1144 MonitorLocker ml(listen_socket->monitor_); |
| 1208 TryDispatchingPendingAccepts(listen_socket); | 1145 TryDispatchingPendingAccepts(listen_socket); |
| 1209 } | 1146 } |
| 1210 | 1147 |
| 1211 DeleteIfClosed(listen_socket); | 1148 DeleteIfClosed(listen_socket); |
| 1212 } | 1149 } |
| 1213 | 1150 |
| 1214 | 1151 |
| 1215 void EventHandlerImplementation::TryDispatchingPendingAccepts( | 1152 void EventHandlerImplementation::TryDispatchingPendingAccepts( |
| 1216 ListenSocket *listen_socket) { | 1153 ListenSocket* listen_socket) { |
| 1217 if (!listen_socket->IsClosing() && listen_socket->CanAccept()) { | 1154 if (!listen_socket->IsClosing() && listen_socket->CanAccept()) { |
| 1218 intptr_t event_mask = 1 << kInEvent; | 1155 intptr_t event_mask = 1 << kInEvent; |
| 1219 for (int i = 0; | 1156 for (int i = 0; (i < listen_socket->accepted_count()) && |
| 1220 (i < listen_socket->accepted_count()) && | 1157 (listen_socket->Mask() == event_mask); |
| 1221 (listen_socket->Mask() == event_mask); | |
| 1222 i++) { | 1158 i++) { |
| 1223 Dart_Port port = listen_socket->NextNotifyDartPort(event_mask); | 1159 Dart_Port port = listen_socket->NextNotifyDartPort(event_mask); |
| 1224 DartUtils::PostInt32(port, event_mask); | 1160 DartUtils::PostInt32(port, event_mask); |
| 1225 } | 1161 } |
| 1226 } | 1162 } |
| 1227 } | 1163 } |
| 1228 | 1164 |
| 1229 | 1165 |
| 1230 void EventHandlerImplementation::HandleRead(Handle* handle, | 1166 void EventHandlerImplementation::HandleRead(Handle* handle, |
| 1231 int bytes, | 1167 int bytes, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 } | 1227 } |
| 1292 } | 1228 } |
| 1293 } else { | 1229 } else { |
| 1294 HandleError(handle); | 1230 HandleError(handle); |
| 1295 } | 1231 } |
| 1296 | 1232 |
| 1297 DeleteIfClosed(handle); | 1233 DeleteIfClosed(handle); |
| 1298 } | 1234 } |
| 1299 | 1235 |
| 1300 | 1236 |
| 1301 void EventHandlerImplementation::HandleDisconnect( | 1237 void EventHandlerImplementation::HandleDisconnect(ClientSocket* client_socket, |
| 1302 ClientSocket* client_socket, | 1238 int bytes, |
| 1303 int bytes, | 1239 OverlappedBuffer* buffer) { |
| 1304 OverlappedBuffer* buffer) { | |
| 1305 client_socket->DisconnectComplete(buffer); | 1240 client_socket->DisconnectComplete(buffer); |
| 1306 DeleteIfClosed(client_socket); | 1241 DeleteIfClosed(client_socket); |
| 1307 } | 1242 } |
| 1308 | 1243 |
| 1309 | 1244 |
| 1310 void EventHandlerImplementation::HandleConnect( | 1245 void EventHandlerImplementation::HandleConnect(ClientSocket* client_socket, |
| 1311 ClientSocket* client_socket, | 1246 int bytes, |
| 1312 int bytes, | 1247 OverlappedBuffer* buffer) { |
| 1313 OverlappedBuffer* buffer) { | |
| 1314 if (bytes < 0) { | 1248 if (bytes < 0) { |
| 1315 HandleError(client_socket); | 1249 HandleError(client_socket); |
| 1316 OverlappedBuffer::DisposeBuffer(buffer); | 1250 OverlappedBuffer::DisposeBuffer(buffer); |
| 1317 } else { | 1251 } else { |
| 1318 client_socket->ConnectComplete(buffer); | 1252 client_socket->ConnectComplete(buffer); |
| 1319 } | 1253 } |
| 1320 client_socket->mark_connected(); | 1254 client_socket->mark_connected(); |
| 1321 DeleteIfClosed(client_socket); | 1255 DeleteIfClosed(client_socket); |
| 1322 } | 1256 } |
| 1323 | 1257 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1393 ASSERT(res == WAIT_OBJECT_0); | 1327 ASSERT(res == WAIT_OBJECT_0); |
| 1394 delete startup_monitor_; | 1328 delete startup_monitor_; |
| 1395 CloseHandle(completion_port_); | 1329 CloseHandle(completion_port_); |
| 1396 } | 1330 } |
| 1397 | 1331 |
| 1398 | 1332 |
| 1399 int64_t EventHandlerImplementation::GetTimeout() { | 1333 int64_t EventHandlerImplementation::GetTimeout() { |
| 1400 if (!timeout_queue_.HasTimeout()) { | 1334 if (!timeout_queue_.HasTimeout()) { |
| 1401 return kInfinityTimeout; | 1335 return kInfinityTimeout; |
| 1402 } | 1336 } |
| 1403 int64_t millis = timeout_queue_.CurrentTimeout() - | 1337 int64_t millis = |
| 1404 TimerUtils::GetCurrentMonotonicMillis(); | 1338 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); |
| 1405 return (millis < 0) ? 0 : millis; | 1339 return (millis < 0) ? 0 : millis; |
| 1406 } | 1340 } |
| 1407 | 1341 |
| 1408 | 1342 |
| 1409 void EventHandlerImplementation::SendData(intptr_t id, | 1343 void EventHandlerImplementation::SendData(intptr_t id, |
| 1410 Dart_Port dart_port, | 1344 Dart_Port dart_port, |
| 1411 int64_t data) { | 1345 int64_t data) { |
| 1412 InterruptMessage* msg = new InterruptMessage; | 1346 InterruptMessage* msg = new InterruptMessage; |
| 1413 msg->id = id; | 1347 msg->id = id; |
| 1414 msg->dart_port = dart_port; | 1348 msg->dart_port = dart_port; |
| 1415 msg->data = data; | 1349 msg->data = data; |
| 1416 BOOL ok = PostQueuedCompletionStatus( | 1350 BOOL ok = PostQueuedCompletionStatus(completion_port_, 0, NULL, |
| 1417 completion_port_, 0, NULL, reinterpret_cast<OVERLAPPED*>(msg)); | 1351 reinterpret_cast<OVERLAPPED*>(msg)); |
| 1418 if (!ok) { | 1352 if (!ok) { |
| 1419 FATAL("PostQueuedCompletionStatus failed"); | 1353 FATAL("PostQueuedCompletionStatus failed"); |
| 1420 } | 1354 } |
| 1421 } | 1355 } |
| 1422 | 1356 |
| 1423 | 1357 |
| 1424 void EventHandlerImplementation::EventHandlerEntry(uword args) { | 1358 void EventHandlerImplementation::EventHandlerEntry(uword args) { |
| 1425 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 1359 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
| 1426 EventHandlerImplementation* handler_impl = &handler->delegate_; | 1360 EventHandlerImplementation* handler_impl = &handler->delegate_; |
| 1427 ASSERT(handler_impl != NULL); | 1361 ASSERT(handler_impl != NULL); |
| 1428 | 1362 |
| 1429 { | 1363 { |
| 1430 MonitorLocker ml(handler_impl->startup_monitor_); | 1364 MonitorLocker ml(handler_impl->startup_monitor_); |
| 1431 handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId(); | 1365 handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId(); |
| 1432 handler_impl->handler_thread_handle_ = | 1366 handler_impl->handler_thread_handle_ = |
| 1433 OpenThread(SYNCHRONIZE, false, handler_impl->handler_thread_id_); | 1367 OpenThread(SYNCHRONIZE, false, handler_impl->handler_thread_id_); |
| 1434 ml.Notify(); | 1368 ml.Notify(); |
| 1435 } | 1369 } |
| 1436 | 1370 |
| 1437 while (!handler_impl->shutdown_) { | 1371 while (!handler_impl->shutdown_) { |
| 1438 DWORD bytes; | 1372 DWORD bytes; |
| 1439 ULONG_PTR key; | 1373 ULONG_PTR key; |
| 1440 OVERLAPPED* overlapped; | 1374 OVERLAPPED* overlapped; |
| 1441 int64_t millis = handler_impl->GetTimeout(); | 1375 int64_t millis = handler_impl->GetTimeout(); |
| 1442 ASSERT(millis == kInfinityTimeout || millis >= 0); | 1376 ASSERT(millis == kInfinityTimeout || millis >= 0); |
| 1443 if (millis > kMaxInt32) { | 1377 if (millis > kMaxInt32) { |
| 1444 millis = kMaxInt32; | 1378 millis = kMaxInt32; |
| 1445 } | 1379 } |
| 1446 ASSERT(sizeof(int32_t) == sizeof(DWORD)); | 1380 ASSERT(sizeof(int32_t) == sizeof(DWORD)); |
| 1447 BOOL ok = GetQueuedCompletionStatus(handler_impl->completion_port(), | 1381 BOOL ok = |
| 1448 &bytes, | 1382 GetQueuedCompletionStatus(handler_impl->completion_port(), &bytes, &key, |
| 1449 &key, | 1383 &overlapped, static_cast<DWORD>(millis)); |
| 1450 &overlapped, | |
| 1451 static_cast<DWORD>(millis)); | |
| 1452 | 1384 |
| 1453 if (!ok && (overlapped == NULL)) { | 1385 if (!ok && (overlapped == NULL)) { |
| 1454 if (GetLastError() == ERROR_ABANDONED_WAIT_0) { | 1386 if (GetLastError() == ERROR_ABANDONED_WAIT_0) { |
| 1455 // The completion port should never be closed. | 1387 // The completion port should never be closed. |
| 1456 Log::Print("Completion port closed\n"); | 1388 Log::Print("Completion port closed\n"); |
| 1457 UNREACHABLE(); | 1389 UNREACHABLE(); |
| 1458 } else { | 1390 } else { |
| 1459 // Timeout is signalled by false result and NULL in overlapped. | 1391 // Timeout is signalled by false result and NULL in overlapped. |
| 1460 handler_impl->HandleTimeout(); | 1392 handler_impl->HandleTimeout(); |
| 1461 } | 1393 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1488 delete msg; | 1420 delete msg; |
| 1489 } else { | 1421 } else { |
| 1490 handler_impl->HandleIOCompletion(bytes, key, overlapped); | 1422 handler_impl->HandleIOCompletion(bytes, key, overlapped); |
| 1491 } | 1423 } |
| 1492 } | 1424 } |
| 1493 handler->NotifyShutdownDone(); | 1425 handler->NotifyShutdownDone(); |
| 1494 } | 1426 } |
| 1495 | 1427 |
| 1496 | 1428 |
| 1497 void EventHandlerImplementation::Start(EventHandler* handler) { | 1429 void EventHandlerImplementation::Start(EventHandler* handler) { |
| 1498 int result = Thread::Start(EventHandlerEntry, | 1430 int result = |
| 1499 reinterpret_cast<uword>(handler)); | 1431 Thread::Start(EventHandlerEntry, reinterpret_cast<uword>(handler)); |
| 1500 if (result != 0) { | 1432 if (result != 0) { |
| 1501 FATAL1("Failed to start event handler thread %d", result); | 1433 FATAL1("Failed to start event handler thread %d", result); |
| 1502 } | 1434 } |
| 1503 | 1435 |
| 1504 { | 1436 { |
| 1505 MonitorLocker ml(startup_monitor_); | 1437 MonitorLocker ml(startup_monitor_); |
| 1506 while (handler_thread_id_ == Thread::kInvalidThreadId) { | 1438 while (handler_thread_id_ == Thread::kInvalidThreadId) { |
| 1507 ml.Wait(); | 1439 ml.Wait(); |
| 1508 } | 1440 } |
| 1509 } | 1441 } |
| 1510 | 1442 |
| 1511 // Initialize Winsock32 | 1443 // Initialize Winsock32 |
| 1512 if (!Socket::Initialize()) { | 1444 if (!Socket::Initialize()) { |
| 1513 FATAL("Failed to initialized Windows sockets"); | 1445 FATAL("Failed to initialized Windows sockets"); |
| 1514 } | 1446 } |
| 1515 } | 1447 } |
| 1516 | 1448 |
| 1517 | 1449 |
| 1518 void EventHandlerImplementation::Shutdown() { | 1450 void EventHandlerImplementation::Shutdown() { |
| 1519 SendData(kShutdownId, 0, 0); | 1451 SendData(kShutdownId, 0, 0); |
| 1520 } | 1452 } |
| 1521 | 1453 |
| 1522 } // namespace bin | 1454 } // namespace bin |
| 1523 } // namespace dart | 1455 } // namespace dart |
| 1524 | 1456 |
| 1525 #endif // defined(TARGET_OS_WINDOWS) | 1457 #endif // defined(TARGET_OS_WINDOWS) |
| 1526 | 1458 |
| 1527 #endif // !defined(DART_IO_DISABLED) | 1459 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |