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