| 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 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "bin/eventhandler.h" | 8 #include "bin/eventhandler.h" |
| 9 #include "bin/eventhandler_win.h" |
| 9 | 10 |
| 10 #include <winsock2.h> // NOLINT | 11 #include <winsock2.h> // NOLINT |
| 11 #include <ws2tcpip.h> // NOLINT | 12 #include <ws2tcpip.h> // NOLINT |
| 12 #include <mswsock.h> // NOLINT | 13 #include <mswsock.h> // NOLINT |
| 13 #include <io.h> // NOLINT | 14 #include <io.h> // NOLINT |
| 14 #include <fcntl.h> // NOLINT | 15 #include <fcntl.h> // NOLINT |
| 15 | 16 |
| 16 #include "bin/builtin.h" | 17 #include "bin/builtin.h" |
| 17 #include "bin/dartutils.h" | 18 #include "bin/dartutils.h" |
| 18 #include "bin/lockers.h" | 19 #include "bin/lockers.h" |
| 19 #include "bin/log.h" | 20 #include "bin/log.h" |
| 20 #include "bin/socket.h" | 21 #include "bin/socket.h" |
| 21 #include "bin/thread.h" | 22 #include "bin/thread.h" |
| 22 #include "bin/utils.h" | 23 #include "bin/utils.h" |
| 23 | 24 |
| 24 #include "platform/utils.h" | 25 #include "platform/utils.h" |
| 25 | 26 |
| 26 namespace dart { | 27 namespace dart { |
| 27 namespace bin { | 28 namespace bin { |
| 28 | 29 |
| 29 static const int kBufferSize = 64 * 1024; | 30 static const int kBufferSize = 64 * 1024; |
| 30 static const int kStdOverlappedBufferSize = 16 * 1024; | 31 static const int kStdOverlappedBufferSize = 16 * 1024; |
| 31 | 32 |
| 32 static const int kInfinityTimeout = -1; | |
| 33 static const int kTimeoutId = -1; | |
| 34 static const int kShutdownId = -2; | |
| 35 | |
| 36 OverlappedBuffer* OverlappedBuffer::AllocateBuffer(int buffer_size, | 33 OverlappedBuffer* OverlappedBuffer::AllocateBuffer(int buffer_size, |
| 37 Operation operation) { | 34 Operation operation) { |
| 38 OverlappedBuffer* buffer = | 35 OverlappedBuffer* buffer = |
| 39 new(buffer_size) OverlappedBuffer(buffer_size, operation); | 36 new(buffer_size) OverlappedBuffer(buffer_size, operation); |
| 40 return buffer; | 37 return buffer; |
| 41 } | 38 } |
| 42 | 39 |
| 43 | 40 |
| 44 OverlappedBuffer* OverlappedBuffer::AllocateAcceptBuffer(int buffer_size) { | 41 OverlappedBuffer* OverlappedBuffer::AllocateAcceptBuffer(int buffer_size) { |
| 45 OverlappedBuffer* buffer = AllocateBuffer(buffer_size, kAccept); | 42 OverlappedBuffer* buffer = AllocateBuffer(buffer_size, kAccept); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 data_length_ = num_bytes; | 105 data_length_ = num_bytes; |
| 109 return num_bytes; | 106 return num_bytes; |
| 110 } | 107 } |
| 111 | 108 |
| 112 | 109 |
| 113 int OverlappedBuffer::GetRemainingLength() { | 110 int OverlappedBuffer::GetRemainingLength() { |
| 114 ASSERT(operation_ == kRead || operation_ == kRecvFrom); | 111 ASSERT(operation_ == kRead || operation_ == kRecvFrom); |
| 115 return data_length_ - index_; | 112 return data_length_ - index_; |
| 116 } | 113 } |
| 117 | 114 |
| 118 | 115 Handle::Handle(intptr_t handle) |
| 119 Handle::Handle(HANDLE handle) | 116 : DescriptorInfoBase(handle), |
| 120 : handle_(reinterpret_cast<HANDLE>(handle)), | 117 handle_(reinterpret_cast<HANDLE>(handle)), |
| 121 port_(0), | |
| 122 mask_(0), | |
| 123 completion_port_(INVALID_HANDLE_VALUE), | 118 completion_port_(INVALID_HANDLE_VALUE), |
| 124 event_handler_(NULL), | 119 event_handler_(NULL), |
| 125 data_ready_(NULL), | 120 data_ready_(NULL), |
| 126 pending_read_(NULL), | |
| 127 pending_write_(NULL), | |
| 128 last_error_(NOERROR), | |
| 129 flags_(0) { | |
| 130 InitializeCriticalSection(&cs_); | |
| 131 } | |
| 132 | |
| 133 | |
| 134 Handle::Handle(HANDLE handle, Dart_Port port) | |
| 135 : handle_(reinterpret_cast<HANDLE>(handle)), | |
| 136 port_(port), | |
| 137 mask_(0), | |
| 138 completion_port_(INVALID_HANDLE_VALUE), | |
| 139 event_handler_(NULL), | |
| 140 data_ready_(NULL), | |
| 141 pending_read_(NULL), | 121 pending_read_(NULL), |
| 142 pending_write_(NULL), | 122 pending_write_(NULL), |
| 143 last_error_(NOERROR), | 123 last_error_(NOERROR), |
| 144 flags_(0) { | 124 flags_(0) { |
| 145 InitializeCriticalSection(&cs_); | 125 InitializeCriticalSection(&cs_); |
| 146 } | 126 } |
| 147 | 127 |
| 148 | 128 |
| 149 Handle::~Handle() { | 129 Handle::~Handle() { |
| 150 DeleteCriticalSection(&cs_); | 130 DeleteCriticalSection(&cs_); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 pending_read_ = buffer; | 266 pending_read_ = buffer; |
| 287 return true; | 267 return true; |
| 288 } | 268 } |
| 289 OverlappedBuffer::DisposeBuffer(buffer); | 269 OverlappedBuffer::DisposeBuffer(buffer); |
| 290 HandleIssueError(); | 270 HandleIssueError(); |
| 291 return false; | 271 return false; |
| 292 } else { | 272 } else { |
| 293 // Completing asynchronously through thread. | 273 // Completing asynchronously through thread. |
| 294 pending_read_ = buffer; | 274 pending_read_ = buffer; |
| 295 int result = Thread::Start(ReadFileThread, | 275 int result = Thread::Start(ReadFileThread, |
| 296 reinterpret_cast<uword>(this)); | 276 reinterpret_cast<uword>(this)); |
| 297 if (result != 0) { | 277 if (result != 0) { |
| 298 FATAL1("Failed to start read file thread %d", result); | 278 FATAL1("Failed to start read file thread %d", result); |
| 299 } | 279 } |
| 300 return true; | 280 return true; |
| 301 } | 281 } |
| 302 } | 282 } |
| 303 | 283 |
| 304 | 284 |
| 305 bool Handle::IssueRecvFrom() { | 285 bool Handle::IssueRecvFrom() { |
| 306 return false; | 286 return false; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 332 | 312 |
| 333 | 313 |
| 334 bool Handle::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { | 314 bool Handle::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { |
| 335 return false; | 315 return false; |
| 336 } | 316 } |
| 337 | 317 |
| 338 | 318 |
| 339 static void HandleClosed(Handle* handle) { | 319 static void HandleClosed(Handle* handle) { |
| 340 if (!handle->IsClosing()) { | 320 if (!handle->IsClosing()) { |
| 341 int event_mask = 1 << kCloseEvent; | 321 int event_mask = 1 << kCloseEvent; |
| 342 DartUtils::PostInt32(handle->port(), event_mask); | 322 DartUtils::PostInt32(handle->NextPort(), event_mask); |
| 343 } | 323 } |
| 344 } | 324 } |
| 345 | 325 |
| 346 | 326 |
| 347 static void HandleError(Handle* handle) { | 327 static void HandleError(Handle* handle) { |
| 348 handle->set_last_error(WSAGetLastError()); | 328 handle->set_last_error(WSAGetLastError()); |
| 349 handle->MarkError(); | 329 handle->MarkError(); |
| 350 if (!handle->IsClosing()) { | 330 if (!handle->IsClosing() && handle->HasNextPort()) { |
| 351 Dart_Port port = handle->port(); | 331 DartUtils::PostInt32(handle->NextPort(), 1 << kErrorEvent); |
| 352 if (port != ILLEGAL_PORT) { | |
| 353 DartUtils::PostInt32(port, 1 << kErrorEvent); | |
| 354 } | |
| 355 } | 332 } |
| 356 } | 333 } |
| 357 | 334 |
| 358 | 335 |
| 359 void Handle::HandleIssueError() { | 336 void Handle::HandleIssueError() { |
| 360 DWORD error = GetLastError(); | 337 DWORD error = GetLastError(); |
| 361 if (error == ERROR_BROKEN_PIPE) { | 338 if (error == ERROR_BROKEN_PIPE) { |
| 362 HandleClosed(this); | 339 HandleClosed(this); |
| 363 } else { | 340 } else { |
| 364 HandleError(this); | 341 HandleError(this); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 NULL); | 437 NULL); |
| 461 if (status == SOCKET_ERROR) { | 438 if (status == SOCKET_ERROR) { |
| 462 return false; | 439 return false; |
| 463 } | 440 } |
| 464 return true; | 441 return true; |
| 465 } | 442 } |
| 466 | 443 |
| 467 | 444 |
| 468 bool ListenSocket::IssueAccept() { | 445 bool ListenSocket::IssueAccept() { |
| 469 ScopedLock lock(this); | 446 ScopedLock lock(this); |
| 447 |
| 470 // For AcceptEx there needs to be buffer storage for address | 448 // For AcceptEx there needs to be buffer storage for address |
| 471 // information for two addresses (local and remote address). The | 449 // information for two addresses (local and remote address). The |
| 472 // AcceptEx documentation says: "This value must be at least 16 | 450 // AcceptEx documentation says: "This value must be at least 16 |
| 473 // bytes more than the maximum address length for the transport | 451 // bytes more than the maximum address length for the transport |
| 474 // protocol in use." | 452 // protocol in use." |
| 475 static const int kAcceptExAddressAdditionalBytes = 16; | 453 static const int kAcceptExAddressAdditionalBytes = 16; |
| 476 static const int kAcceptExAddressStorageSize = | 454 static const int kAcceptExAddressStorageSize = |
| 477 sizeof(SOCKADDR_STORAGE) + kAcceptExAddressAdditionalBytes; | 455 sizeof(SOCKADDR_STORAGE) + kAcceptExAddressAdditionalBytes; |
| 478 OverlappedBuffer* buffer = | 456 OverlappedBuffer* buffer = |
| 479 OverlappedBuffer::AllocateAcceptBuffer(2 * kAcceptExAddressStorageSize); | 457 OverlappedBuffer::AllocateAcceptBuffer(2 * kAcceptExAddressStorageSize); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 508 ScopedLock lock(this); | 486 ScopedLock lock(this); |
| 509 if (!IsClosing()) { | 487 if (!IsClosing()) { |
| 510 // Update the accepted socket to support the full range of API calls. | 488 // Update the accepted socket to support the full range of API calls. |
| 511 SOCKET s = socket(); | 489 SOCKET s = socket(); |
| 512 int rc = setsockopt(buffer->client(), | 490 int rc = setsockopt(buffer->client(), |
| 513 SOL_SOCKET, | 491 SOL_SOCKET, |
| 514 SO_UPDATE_ACCEPT_CONTEXT, | 492 SO_UPDATE_ACCEPT_CONTEXT, |
| 515 reinterpret_cast<char*>(&s), sizeof(s)); | 493 reinterpret_cast<char*>(&s), sizeof(s)); |
| 516 if (rc == NO_ERROR) { | 494 if (rc == NO_ERROR) { |
| 517 // Insert the accepted socket into the list. | 495 // Insert the accepted socket into the list. |
| 518 ClientSocket* client_socket = new ClientSocket(buffer->client(), 0); | 496 ClientSocket* client_socket = new ClientSocket(buffer->client()); |
| 519 client_socket->mark_connected(); | 497 client_socket->mark_connected(); |
| 520 client_socket->CreateCompletionPort(completion_port); | 498 client_socket->CreateCompletionPort(completion_port); |
| 521 if (accepted_head_ == NULL) { | 499 if (accepted_head_ == NULL) { |
| 522 accepted_head_ = client_socket; | 500 accepted_head_ = client_socket; |
| 523 accepted_tail_ = client_socket; | 501 accepted_tail_ = client_socket; |
| 524 } else { | 502 } else { |
| 525 ASSERT(accepted_tail_ != NULL); | 503 ASSERT(accepted_tail_ != NULL); |
| 526 accepted_tail_->set_next(client_socket); | 504 accepted_tail_->set_next(client_socket); |
| 527 accepted_tail_ = client_socket; | 505 accepted_tail_ = client_socket; |
| 528 } | 506 } |
| 507 accepted_count_++; |
| 529 } else { | 508 } else { |
| 530 closesocket(buffer->client()); | 509 closesocket(buffer->client()); |
| 531 } | 510 } |
| 532 } else { | 511 } else { |
| 533 // Close the socket, as it's already accepted. | 512 // Close the socket, as it's already accepted. |
| 534 closesocket(buffer->client()); | 513 closesocket(buffer->client()); |
| 535 } | 514 } |
| 536 | 515 |
| 537 pending_accept_count_--; | 516 pending_accept_count_--; |
| 538 OverlappedBuffer::DisposeBuffer(buffer); | 517 OverlappedBuffer::DisposeBuffer(buffer); |
| 539 } | 518 } |
| 540 | 519 |
| 541 | 520 |
| 542 static void DeleteIfClosed(Handle* handle) { | 521 static void DeleteIfClosed(Handle* handle) { |
| 543 if (handle->IsClosed()) { | 522 if (handle->IsClosed()) { |
| 544 Dart_Port port = handle->port(); | 523 handle->SendToAll(1 << kDestroyedEvent); |
| 545 delete handle; | 524 delete handle; |
| 546 if (port != ILLEGAL_PORT) { | |
| 547 DartUtils::PostInt32(port, 1 << kDestroyedEvent); | |
| 548 } | |
| 549 } | 525 } |
| 550 } | 526 } |
| 551 | 527 |
| 552 | 528 |
| 553 void ListenSocket::DoClose() { | 529 void ListenSocket::DoClose() { |
| 554 closesocket(socket()); | 530 closesocket(socket()); |
| 555 handle_ = INVALID_HANDLE_VALUE; | 531 handle_ = INVALID_HANDLE_VALUE; |
| 556 while (CanAccept()) { | 532 while (CanAccept()) { |
| 557 // Get rid of connections already accepted. | 533 // Get rid of connections already accepted. |
| 558 ClientSocket *client = Accept(); | 534 ClientSocket *client = Accept(); |
| 559 if (client != NULL) { | 535 if (client != NULL) { |
| 560 client->Close(); | 536 client->Close(); |
| 561 DeleteIfClosed(client); | 537 DeleteIfClosed(client); |
| 562 } else { | 538 } else { |
| 563 break; | 539 break; |
| 564 } | 540 } |
| 565 } | 541 } |
| 566 } | 542 } |
| 567 | 543 |
| 568 | 544 |
| 569 bool ListenSocket::CanAccept() { | 545 bool ListenSocket::CanAccept() { |
| 570 ScopedLock lock(this); | 546 ScopedLock lock(this); |
| 571 return accepted_head_ != NULL; | 547 return accepted_head_ != NULL; |
| 572 } | 548 } |
| 573 | 549 |
| 574 | 550 |
| 575 ClientSocket* ListenSocket::Accept() { | 551 ClientSocket* ListenSocket::Accept() { |
| 576 ScopedLock lock(this); | 552 ScopedLock lock(this); |
| 577 if (accepted_head_ == NULL) return NULL; | 553 |
| 578 ClientSocket* result = accepted_head_; | 554 ClientSocket *result = NULL; |
| 579 accepted_head_ = accepted_head_->next(); | 555 |
| 580 if (accepted_head_ == NULL) accepted_tail_ = NULL; | 556 if (accepted_head_ != NULL) { |
| 581 result->set_next(NULL); | 557 result = accepted_head_; |
| 558 accepted_head_ = accepted_head_->next(); |
| 559 if (accepted_head_ == NULL) accepted_tail_ = NULL; |
| 560 result->set_next(NULL); |
| 561 accepted_count_--; |
| 562 } |
| 563 |
| 582 if (!IsClosing()) { | 564 if (!IsClosing()) { |
| 583 if (!IssueAccept()) { | 565 if (!IssueAccept()) { |
| 584 HandleError(this); | 566 HandleError(this); |
| 585 } | 567 } |
| 586 } | 568 } |
| 569 |
| 587 return result; | 570 return result; |
| 588 } | 571 } |
| 589 | 572 |
| 590 | 573 |
| 591 void ListenSocket::EnsureInitialized( | 574 void ListenSocket::EnsureInitialized( |
| 592 EventHandlerImplementation* event_handler) { | 575 EventHandlerImplementation* event_handler) { |
| 593 ScopedLock lock(this); | 576 ScopedLock lock(this); |
| 594 if (AcceptEx_ == NULL) { | 577 if (AcceptEx_ == NULL) { |
| 595 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); | 578 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); |
| 596 ASSERT(event_handler_ == NULL); | 579 ASSERT(event_handler_ == NULL); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 | 856 |
| 874 void ClientSocket::IssueDisconnect() { | 857 void ClientSocket::IssueDisconnect() { |
| 875 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); | 858 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); |
| 876 BOOL ok = DisconnectEx_( | 859 BOOL ok = DisconnectEx_( |
| 877 socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); | 860 socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); |
| 878 // DisconnectEx works like other OverlappedIO APIs, where we can get either an | 861 // DisconnectEx works like other OverlappedIO APIs, where we can get either an |
| 879 // immediate success or delayed operation by WSA_IO_PENDING being set. | 862 // immediate success or delayed operation by WSA_IO_PENDING being set. |
| 880 if (ok || WSAGetLastError() != WSA_IO_PENDING) { | 863 if (ok || WSAGetLastError() != WSA_IO_PENDING) { |
| 881 DisconnectComplete(buffer); | 864 DisconnectComplete(buffer); |
| 882 } | 865 } |
| 883 Dart_Port p = port(); | 866 if (HasNextPort()) { |
| 884 if (p != ILLEGAL_PORT) DartUtils::PostInt32(p, 1 << kDestroyedEvent); | 867 Dart_Port p = NextPort(); |
| 885 port_ = ILLEGAL_PORT; | 868 DartUtils::PostInt32(p, 1 << kDestroyedEvent); |
| 869 RemovePort(p); |
| 870 } |
| 886 } | 871 } |
| 887 | 872 |
| 888 | 873 |
| 889 void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { | 874 void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { |
| 890 OverlappedBuffer::DisposeBuffer(buffer); | 875 OverlappedBuffer::DisposeBuffer(buffer); |
| 891 closesocket(socket()); | 876 closesocket(socket()); |
| 892 if (data_ready_ != NULL) { | 877 if (data_ready_ != NULL) { |
| 893 OverlappedBuffer::DisposeBuffer(data_ready_); | 878 OverlappedBuffer::DisposeBuffer(data_ready_); |
| 894 } | 879 } |
| 895 closed_ = true; | 880 closed_ = true; |
| 896 } | 881 } |
| 897 | 882 |
| 898 | 883 |
| 899 void ClientSocket::ConnectComplete(OverlappedBuffer* buffer) { | 884 void ClientSocket::ConnectComplete(OverlappedBuffer* buffer) { |
| 900 OverlappedBuffer::DisposeBuffer(buffer); | 885 OverlappedBuffer::DisposeBuffer(buffer); |
| 901 // Update socket to support full socket API, after ConnectEx completed. | 886 // Update socket to support full socket API, after ConnectEx completed. |
| 902 setsockopt(socket(), SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0); | 887 setsockopt(socket(), SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0); |
| 903 Dart_Port p = port(); | 888 if (HasNextPort()) { |
| 904 if (p != ILLEGAL_PORT) { | |
| 905 // If the port is set, we already listen for this socket in Dart. | 889 // If the port is set, we already listen for this socket in Dart. |
| 906 // Handle the cases here. | 890 // Handle the cases here. |
| 907 if (!IsClosedRead()) { | 891 if (!IsClosedRead()) { |
| 908 IssueRead(); | 892 IssueRead(); |
| 909 } | 893 } |
| 910 if (!IsClosedWrite()) { | 894 if (!IsClosedWrite()) { |
| 911 DartUtils::PostInt32(p, 1 << kOutEvent); | 895 DartUtils::PostInt32(NextPort(), 1 << kOutEvent); |
| 912 } | 896 } |
| 913 } | 897 } |
| 914 } | 898 } |
| 915 | 899 |
| 916 | 900 |
| 917 void ClientSocket::EnsureInitialized( | 901 void ClientSocket::EnsureInitialized( |
| 918 EventHandlerImplementation* event_handler) { | 902 EventHandlerImplementation* event_handler) { |
| 919 ScopedLock lock(this); | 903 ScopedLock lock(this); |
| 920 if (completion_port_ == INVALID_HANDLE_VALUE) { | 904 if (completion_port_ == INVALID_HANDLE_VALUE) { |
| 921 ASSERT(event_handler_ == NULL); | 905 ASSERT(event_handler_ == NULL); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 // Just close the socket. This will cause any queued requests to be aborted. | 988 // Just close the socket. This will cause any queued requests to be aborted. |
| 1005 closesocket(socket()); | 989 closesocket(socket()); |
| 1006 MarkClosedRead(); | 990 MarkClosedRead(); |
| 1007 MarkClosedWrite(); | 991 MarkClosedWrite(); |
| 1008 handle_ = INVALID_HANDLE_VALUE; | 992 handle_ = INVALID_HANDLE_VALUE; |
| 1009 } | 993 } |
| 1010 | 994 |
| 1011 | 995 |
| 1012 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { | 996 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { |
| 1013 ASSERT(this != NULL); | 997 ASSERT(this != NULL); |
| 1014 if (msg->id == kTimeoutId) { | 998 if (msg->id == kTimerId) { |
| 1015 // Change of timeout request. Just set the new timeout and port as the | 999 // Change of timeout request. Just set the new timeout and port as the |
| 1016 // completion thread will use the new timeout value for its next wait. | 1000 // completion thread will use the new timeout value for its next wait. |
| 1017 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); | 1001 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); |
| 1018 } else if (msg->id == kShutdownId) { | 1002 } else if (msg->id == kShutdownId) { |
| 1019 shutdown_ = true; | 1003 shutdown_ = true; |
| 1020 } else { | 1004 } else { |
| 1021 // No tokens to return on Windows. | |
| 1022 if ((msg->data & (1 << kReturnTokenCommand)) != 0) return; | |
| 1023 Handle* handle = reinterpret_cast<Handle*>(msg->id); | 1005 Handle* handle = reinterpret_cast<Handle*>(msg->id); |
| 1024 ASSERT(handle != NULL); | 1006 ASSERT(handle != NULL); |
| 1007 |
| 1025 if (handle->is_listen_socket()) { | 1008 if (handle->is_listen_socket()) { |
| 1026 ListenSocket* listen_socket = | 1009 ListenSocket* listen_socket = |
| 1027 reinterpret_cast<ListenSocket*>(handle); | 1010 reinterpret_cast<ListenSocket*>(handle); |
| 1028 listen_socket->EnsureInitialized(this); | 1011 listen_socket->EnsureInitialized(this); |
| 1029 listen_socket->SetPortAndMask(msg->dart_port, msg->data); | |
| 1030 | 1012 |
| 1031 Handle::ScopedLock lock(listen_socket); | 1013 Handle::ScopedLock lock(listen_socket); |
| 1032 | 1014 |
| 1033 // If incoming connections are requested make sure to post already | 1015 // If incoming connections are requested make sure to post already |
| 1034 // accepted connections. | 1016 // accepted connections. |
| 1035 if ((msg->data & (1 << kInEvent)) != 0) { | 1017 if ((msg->data & (1 << kInEvent)) != 0) { |
| 1036 if (listen_socket->CanAccept()) { | 1018 listen_socket->SetPortAndMask(msg->dart_port, msg->data & EVENT_MASK); |
| 1037 int event_mask = (1 << kInEvent); | 1019 TryDispatchingPendingAccepts(listen_socket); |
| 1038 handle->set_mask(handle->mask() & ~event_mask); | 1020 } |
| 1039 DartUtils::PostInt32(handle->port(), event_mask); | 1021 |
| 1022 if (IS_COMMAND(msg->data, kReturnTokenCommand)) { |
| 1023 int count = TOKEN_COUNT(msg->data); |
| 1024 listen_socket->ReturnTokens(msg->dart_port, count); |
| 1025 TryDispatchingPendingAccepts(listen_socket); |
| 1026 return; |
| 1027 } else if (IS_COMMAND(msg->data, kCloseCommand)) { |
| 1028 Dart_Port port = msg->dart_port; |
| 1029 listen_socket->RemovePort(port); |
| 1030 |
| 1031 MutexLocker locker(globalTcpListeningSocketRegistry.mutex()); |
| 1032 if (globalTcpListeningSocketRegistry.CloseSafe( |
| 1033 reinterpret_cast<intptr_t>(listen_socket))) { |
| 1034 handle->Close(); |
| 1040 } | 1035 } |
| 1036 DartUtils::PostInt32(port, 1 << kDestroyedEvent); |
| 1041 } | 1037 } |
| 1042 } else { | 1038 } else { |
| 1043 handle->EnsureInitialized(this); | 1039 handle->EnsureInitialized(this); |
| 1044 | 1040 |
| 1045 Handle::ScopedLock lock(handle); | 1041 Handle::ScopedLock lock(handle); |
| 1046 | 1042 |
| 1043 if (IS_COMMAND(msg->data, kReturnTokenCommand)) { |
| 1044 int count = TOKEN_COUNT(msg->data); |
| 1045 handle->ReturnTokens(msg->dart_port, count); |
| 1046 // TODO(kustermann): How can we continue with sending events |
| 1047 // to dart from here? |
| 1048 return; |
| 1049 } |
| 1050 |
| 1047 // Only set mask if we turned on kInEvent or kOutEvent. | 1051 // Only set mask if we turned on kInEvent or kOutEvent. |
| 1048 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) { | 1052 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) { |
| 1049 handle->SetPortAndMask(msg->dart_port, msg->data); | 1053 handle->SetPortAndMask(msg->dart_port, msg->data & EVENT_MASK); |
| 1050 } | 1054 } |
| 1051 | 1055 |
| 1052 // Issue a read. | 1056 // Issue a read. |
| 1053 if ((msg->data & (1 << kInEvent)) != 0) { | 1057 if ((msg->data & (1 << kInEvent)) != 0) { |
| 1054 if (handle->is_datagram_socket()) { | 1058 if (handle->is_datagram_socket()) { |
| 1055 handle->IssueRecvFrom(); | 1059 handle->IssueRecvFrom(); |
| 1056 } else if (handle->is_client_socket()) { | 1060 } else if (handle->is_client_socket()) { |
| 1057 if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { | 1061 if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { |
| 1058 handle->IssueRead(); | 1062 handle->IssueRead(); |
| 1059 } | 1063 } |
| 1060 } else { | 1064 } else { |
| 1061 handle->IssueRead(); | 1065 handle->IssueRead(); |
| 1062 } | 1066 } |
| 1063 } | 1067 } |
| 1064 | 1068 |
| 1065 // If out events (can write events) have been requested, and there | 1069 // If out events (can write events) have been requested, and there |
| 1066 // are no pending writes, meaning any writes are already complete, | 1070 // are no pending writes, meaning any writes are already complete, |
| 1067 // post an out event immediately. | 1071 // post an out event immediately. |
| 1068 if ((msg->data & (1 << kOutEvent)) != 0) { | 1072 if ((msg->data & (1 << kOutEvent)) != 0) { |
| 1069 if (!handle->HasPendingWrite()) { | 1073 if (!handle->HasPendingWrite()) { |
| 1070 if (handle->is_client_socket()) { | 1074 if (handle->is_client_socket()) { |
| 1071 if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { | 1075 if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { |
| 1072 DartUtils::PostInt32(handle->port(), 1 << kOutEvent); | 1076 DartUtils::PostInt32(handle->NextPort(), 1 << kOutEvent); |
| 1073 } | 1077 } |
| 1074 } else { | 1078 } else { |
| 1075 DartUtils::PostInt32(handle->port(), 1 << kOutEvent); | 1079 DartUtils::PostInt32(handle->NextPort(), 1 << kOutEvent); |
| 1076 } | 1080 } |
| 1077 } | 1081 } |
| 1078 } | 1082 } |
| 1079 | 1083 |
| 1080 if (handle->is_client_socket()) { | 1084 if (handle->is_client_socket()) { |
| 1081 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle); | 1085 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle); |
| 1082 if ((msg->data & (1 << kShutdownReadCommand)) != 0) { | 1086 if ((msg->data & (1 << kShutdownReadCommand)) != 0) { |
| 1083 client_socket->Shutdown(SD_RECEIVE); | 1087 client_socket->Shutdown(SD_RECEIVE); |
| 1084 } | 1088 } |
| 1085 | 1089 |
| 1086 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) { | 1090 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) { |
| 1087 client_socket->Shutdown(SD_SEND); | 1091 client_socket->Shutdown(SD_SEND); |
| 1088 } | 1092 } |
| 1089 } | 1093 } |
| 1094 |
| 1095 if ((msg->data & (1 << kCloseCommand)) != 0) { |
| 1096 handle->SetPortAndMask(msg->dart_port, msg->data & EVENT_MASK); |
| 1097 handle->Close(); |
| 1098 } |
| 1090 } | 1099 } |
| 1091 | |
| 1092 if ((msg->data & (1 << kCloseCommand)) != 0) { | |
| 1093 handle->SetPortAndMask(msg->dart_port, msg->data); | |
| 1094 handle->Close(); | |
| 1095 } | |
| 1096 | |
| 1097 DeleteIfClosed(handle); | 1100 DeleteIfClosed(handle); |
| 1098 } | 1101 } |
| 1099 } | 1102 } |
| 1100 | 1103 |
| 1101 | 1104 |
| 1102 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket, | 1105 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket, |
| 1103 OverlappedBuffer* buffer) { | 1106 OverlappedBuffer* buffer) { |
| 1104 listen_socket->AcceptComplete(buffer, completion_port_); | 1107 listen_socket->AcceptComplete(buffer, completion_port_); |
| 1105 | 1108 |
| 1106 if (!listen_socket->IsClosing()) { | 1109 TryDispatchingPendingAccepts(listen_socket); |
| 1107 int event_mask = 1 << kInEvent; | 1110 |
| 1108 if ((listen_socket->mask() & event_mask) != 0) { | 1111 DeleteIfClosed(listen_socket); |
| 1109 DartUtils::PostInt32(listen_socket->port(), event_mask); | 1112 } |
| 1113 |
| 1114 |
| 1115 void EventHandlerImplementation::TryDispatchingPendingAccepts( |
| 1116 ListenSocket *listen_socket) { |
| 1117 Handle::ScopedLock lock(listen_socket); |
| 1118 |
| 1119 if (!listen_socket->IsClosing() && listen_socket->CanAccept()) { |
| 1120 for (int i = 0; |
| 1121 i < listen_socket->accepted_count() && listen_socket->HasNextPort(); |
| 1122 i++) { |
| 1123 Dart_Port port = listen_socket->NextPort(); |
| 1124 DartUtils::PostInt32(port, 1 << kInEvent); |
| 1125 if (listen_socket->TakeToken()) { |
| 1126 break; |
| 1127 } |
| 1110 } | 1128 } |
| 1111 } | 1129 } |
| 1112 | |
| 1113 DeleteIfClosed(listen_socket); | |
| 1114 } | 1130 } |
| 1115 | 1131 |
| 1116 | 1132 |
| 1117 void EventHandlerImplementation::HandleRead(Handle* handle, | 1133 void EventHandlerImplementation::HandleRead(Handle* handle, |
| 1118 int bytes, | 1134 int bytes, |
| 1119 OverlappedBuffer* buffer) { | 1135 OverlappedBuffer* buffer) { |
| 1120 buffer->set_data_length(bytes); | 1136 buffer->set_data_length(bytes); |
| 1121 handle->ReadComplete(buffer); | 1137 handle->ReadComplete(buffer); |
| 1122 if (bytes > 0) { | 1138 if (bytes > 0) { |
| 1123 if (!handle->IsClosing()) { | 1139 if (!handle->IsClosing()) { |
| 1124 int event_mask = 1 << kInEvent; | 1140 int event_mask = 1 << kInEvent; |
| 1125 if ((handle->mask() & event_mask) != 0) { | 1141 if ((handle->Mask() & event_mask) != 0) { |
| 1126 DartUtils::PostInt32(handle->port(), event_mask); | 1142 DartUtils::PostInt32(handle->NextPort(), event_mask); |
| 1127 } | 1143 } |
| 1128 } | 1144 } |
| 1129 } else { | 1145 } else { |
| 1130 handle->MarkClosedRead(); | 1146 handle->MarkClosedRead(); |
| 1131 if (bytes == 0) { | 1147 if (bytes == 0) { |
| 1132 HandleClosed(handle); | 1148 HandleClosed(handle); |
| 1133 } else { | 1149 } else { |
| 1134 HandleError(handle); | 1150 HandleError(handle); |
| 1135 } | 1151 } |
| 1136 } | 1152 } |
| 1137 | 1153 |
| 1138 DeleteIfClosed(handle); | 1154 DeleteIfClosed(handle); |
| 1139 } | 1155 } |
| 1140 | 1156 |
| 1141 | 1157 |
| 1142 void EventHandlerImplementation::HandleRecvFrom(Handle* handle, | 1158 void EventHandlerImplementation::HandleRecvFrom(Handle* handle, |
| 1143 int bytes, | 1159 int bytes, |
| 1144 OverlappedBuffer* buffer) { | 1160 OverlappedBuffer* buffer) { |
| 1145 ASSERT(handle->is_datagram_socket()); | 1161 ASSERT(handle->is_datagram_socket()); |
| 1146 buffer->set_data_length(bytes); | 1162 buffer->set_data_length(bytes); |
| 1147 handle->ReadComplete(buffer); | 1163 handle->ReadComplete(buffer); |
| 1148 if (!handle->IsClosing()) { | 1164 if (!handle->IsClosing()) { |
| 1149 int event_mask = 1 << kInEvent; | 1165 int event_mask = 1 << kInEvent; |
| 1150 if ((handle->mask() & event_mask) != 0) { | 1166 if ((handle->Mask() & event_mask) != 0) { |
| 1151 DartUtils::PostInt32(handle->port(), event_mask); | 1167 DartUtils::PostInt32(handle->NextPort(), event_mask); |
| 1152 } | 1168 } |
| 1153 } | 1169 } |
| 1154 | 1170 |
| 1155 DeleteIfClosed(handle); | 1171 DeleteIfClosed(handle); |
| 1156 } | 1172 } |
| 1157 | 1173 |
| 1158 | 1174 |
| 1159 void EventHandlerImplementation::HandleWrite(Handle* handle, | 1175 void EventHandlerImplementation::HandleWrite(Handle* handle, |
| 1160 int bytes, | 1176 int bytes, |
| 1161 OverlappedBuffer* buffer) { | 1177 OverlappedBuffer* buffer) { |
| 1162 handle->WriteComplete(buffer); | 1178 handle->WriteComplete(buffer); |
| 1163 | 1179 |
| 1164 if (bytes >= 0) { | 1180 if (bytes >= 0) { |
| 1165 if (!handle->IsError() && !handle->IsClosing()) { | 1181 if (!handle->IsError() && !handle->IsClosing()) { |
| 1166 int event_mask = 1 << kOutEvent; | 1182 int event_mask = 1 << kOutEvent; |
| 1167 ASSERT(!handle->is_client_socket() || | 1183 ASSERT(!handle->is_client_socket() || |
| 1168 reinterpret_cast<ClientSocket*>(handle)->is_connected()); | 1184 reinterpret_cast<ClientSocket*>(handle)->is_connected()); |
| 1169 if ((handle->mask() & event_mask) != 0) { | 1185 if ((handle->Mask() & event_mask) != 0) { |
| 1170 DartUtils::PostInt32(handle->port(), event_mask); | 1186 DartUtils::PostInt32(handle->NextPort(), event_mask); |
| 1171 } | 1187 } |
| 1172 } | 1188 } |
| 1173 } else { | 1189 } else { |
| 1174 HandleError(handle); | 1190 HandleError(handle); |
| 1175 } | 1191 } |
| 1176 | 1192 |
| 1177 DeleteIfClosed(handle); | 1193 DeleteIfClosed(handle); |
| 1178 } | 1194 } |
| 1179 | 1195 |
| 1180 | 1196 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1343 } else { | 1359 } else { |
| 1344 handler_impl->HandleIOCompletion(bytes, key, overlapped); | 1360 handler_impl->HandleIOCompletion(bytes, key, overlapped); |
| 1345 } | 1361 } |
| 1346 } | 1362 } |
| 1347 delete handler; | 1363 delete handler; |
| 1348 } | 1364 } |
| 1349 | 1365 |
| 1350 | 1366 |
| 1351 void EventHandlerImplementation::Start(EventHandler* handler) { | 1367 void EventHandlerImplementation::Start(EventHandler* handler) { |
| 1352 int result = Thread::Start(EventHandlerEntry, | 1368 int result = Thread::Start(EventHandlerEntry, |
| 1353 reinterpret_cast<uword>(handler)); | 1369 reinterpret_cast<uword>(handler)); |
| 1354 if (result != 0) { | 1370 if (result != 0) { |
| 1355 FATAL1("Failed to start event handler thread %d", result); | 1371 FATAL1("Failed to start event handler thread %d", result); |
| 1356 } | 1372 } |
| 1357 | 1373 |
| 1358 // Initialize Winsock32 | 1374 // Initialize Winsock32 |
| 1359 if (!Socket::Initialize()) { | 1375 if (!Socket::Initialize()) { |
| 1360 FATAL("Failed to initialized Windows sockets"); | 1376 FATAL("Failed to initialized Windows sockets"); |
| 1361 } | 1377 } |
| 1362 } | 1378 } |
| 1363 | 1379 |
| 1364 | 1380 |
| 1365 void EventHandlerImplementation::Shutdown() { | 1381 void EventHandlerImplementation::Shutdown() { |
| 1366 SendData(kShutdownId, 0, 0); | 1382 SendData(kShutdownId, 0, 0); |
| 1367 } | 1383 } |
| 1368 | 1384 |
| 1369 } // namespace bin | 1385 } // namespace bin |
| 1370 } // namespace dart | 1386 } // namespace dart |
| 1371 | 1387 |
| 1372 #endif // defined(TARGET_OS_WINDOWS) | 1388 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |