Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1346)

Side by Side Diff: dart/runtime/bin/eventhandler_win.cc

Issue 910863003: Implement windows support for having multiple Dart_Port's registered on one OS socket (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed indentation Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « dart/runtime/bin/eventhandler_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « dart/runtime/bin/eventhandler_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698