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

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

Issue 169383003: Make event-handlers edge-triggered and move socket-state to Dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 | « runtime/bin/eventhandler_macos.cc ('k') | runtime/bin/file_patch.dart » ('j') | 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 9
10 #include <winsock2.h> // NOLINT 10 #include <winsock2.h> // NOLINT
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 } 366 }
367 367
368 368
369 bool DirectoryWatchHandle::IsClosed() { 369 bool DirectoryWatchHandle::IsClosed() {
370 return IsClosing() && pending_read_ == NULL; 370 return IsClosing() && pending_read_ == NULL;
371 } 371 }
372 372
373 373
374 bool DirectoryWatchHandle::IssueRead() { 374 bool DirectoryWatchHandle::IssueRead() {
375 ScopedLock lock(this); 375 ScopedLock lock(this);
376 // It may have been started before, as we start the directory-handler when
377 // we create it.
378 if (pending_read_ != NULL) return true;
376 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); 379 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize);
377 380
378 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); 381 ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
379 382
380 BOOL ok = ReadDirectoryChangesW(handle_, 383 BOOL ok = ReadDirectoryChangesW(handle_,
381 buffer->GetBufferStart(), 384 buffer->GetBufferStart(),
382 buffer->GetBufferSize(), 385 buffer->GetBufferSize(),
383 recursive_, 386 recursive_,
384 events_, 387 events_,
385 NULL, 388 NULL,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 } 525 }
523 526
524 527
525 ClientSocket* ListenSocket::Accept() { 528 ClientSocket* ListenSocket::Accept() {
526 ScopedLock lock(this); 529 ScopedLock lock(this);
527 if (accepted_head_ == NULL) return NULL; 530 if (accepted_head_ == NULL) return NULL;
528 ClientSocket* result = accepted_head_; 531 ClientSocket* result = accepted_head_;
529 accepted_head_ = accepted_head_->next(); 532 accepted_head_ = accepted_head_->next();
530 if (accepted_head_ == NULL) accepted_tail_ = NULL; 533 if (accepted_head_ == NULL) accepted_tail_ = NULL;
531 result->set_next(NULL); 534 result->set_next(NULL);
535 if (!IsClosing()) {
536 while (pending_accept_count() < 5) {
537 if (!IssueAccept()) {
538 event_handler_->HandleError(this);
539 }
540 }
541 }
532 return result; 542 return result;
533 } 543 }
534 544
535 545
536 void ListenSocket::EnsureInitialized( 546 void ListenSocket::EnsureInitialized(
537 EventHandlerImplementation* event_handler) { 547 EventHandlerImplementation* event_handler) {
538 ScopedLock lock(this); 548 ScopedLock lock(this);
539 if (AcceptEx_ == NULL) { 549 if (AcceptEx_ == NULL) {
540 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); 550 ASSERT(completion_port_ == INVALID_HANDLE_VALUE);
541 ASSERT(event_handler_ == NULL); 551 ASSERT(event_handler_ == NULL);
(...skipping 17 matching lines...) Expand all
559 } 569 }
560 570
561 571
562 int Handle::Read(void* buffer, int num_bytes) { 572 int Handle::Read(void* buffer, int num_bytes) {
563 ScopedLock lock(this); 573 ScopedLock lock(this);
564 if (data_ready_ == NULL) return 0; 574 if (data_ready_ == NULL) return 0;
565 num_bytes = data_ready_->Read(buffer, num_bytes); 575 num_bytes = data_ready_->Read(buffer, num_bytes);
566 if (data_ready_->IsEmpty()) { 576 if (data_ready_->IsEmpty()) {
567 OverlappedBuffer::DisposeBuffer(data_ready_); 577 OverlappedBuffer::DisposeBuffer(data_ready_);
568 data_ready_ = NULL; 578 data_ready_ = NULL;
579 if (!IsClosing() && !IsClosedRead()) IssueRead();
569 } 580 }
570 return num_bytes; 581 return num_bytes;
571 } 582 }
572 583
573 584
574 int Handle::RecvFrom( 585 int Handle::RecvFrom(
575 void* buffer, int num_bytes, struct sockaddr* sa, socklen_t sa_len) { 586 void* buffer, int num_bytes, struct sockaddr* sa, socklen_t sa_len) {
576 ScopedLock lock(this); 587 ScopedLock lock(this);
577 if (data_ready_ == NULL) return 0; 588 if (data_ready_ == NULL) return 0;
578 num_bytes = data_ready_->Read(buffer, num_bytes); 589 num_bytes = data_ready_->Read(buffer, num_bytes);
579 if (data_ready_->from()->sa_family == AF_INET) { 590 if (data_ready_->from()->sa_family == AF_INET) {
580 ASSERT(sa_len >= sizeof(struct sockaddr_in)); 591 ASSERT(sa_len >= sizeof(struct sockaddr_in));
581 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); 592 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in));
582 } else { 593 } else {
583 ASSERT(data_ready_->from()->sa_family == AF_INET6); 594 ASSERT(data_ready_->from()->sa_family == AF_INET6);
584 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); 595 ASSERT(sa_len >= sizeof(struct sockaddr_in6));
585 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); 596 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6));
586 } 597 }
587 // Always dispose of the buffer, as UDP messages must be read in their 598 // Always dispose of the buffer, as UDP messages must be read in their
588 // entirety to match how recvfrom works in a socket. 599 // entirety to match how recvfrom works in a socket.
589 OverlappedBuffer::DisposeBuffer(data_ready_); 600 OverlappedBuffer::DisposeBuffer(data_ready_);
590 data_ready_ = NULL; 601 data_ready_ = NULL;
602 if (!IsClosing() && !IsClosedRead()) IssueRecvFrom();
591 return num_bytes; 603 return num_bytes;
592 } 604 }
593 605
594 606
595 int Handle::Write(const void* buffer, int num_bytes) { 607 int Handle::Write(const void* buffer, int num_bytes) {
596 ScopedLock lock(this); 608 ScopedLock lock(this);
597 if (pending_write_ != NULL) return 0; 609 if (pending_write_ != NULL) return 0;
598 if (num_bytes > kBufferSize) num_bytes = kBufferSize; 610 if (num_bytes > kBufferSize) num_bytes = kBufferSize;
599 ASSERT(SupportsOverlappedIO()); 611 ASSERT(SupportsOverlappedIO());
600 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; 612 if (completion_port_ == INVALID_HANDLE_VALUE) return 0;
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 } 986 }
975 987
976 if ((msg->data & (1 << kCloseCommand)) != 0) { 988 if ((msg->data & (1 << kCloseCommand)) != 0) {
977 listen_socket->Close(); 989 listen_socket->Close();
978 } 990 }
979 } else { 991 } else {
980 handle->EnsureInitialized(this); 992 handle->EnsureInitialized(this);
981 993
982 Handle::ScopedLock lock(handle); 994 Handle::ScopedLock lock(handle);
983 995
984 if (handle->IsError()) { 996 // Only set mask if we turned on kInEvent or kOutEvent.
985 DartUtils::PostInt32(msg->dart_port, 1 << kErrorEvent); 997 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) {
986 } else { 998 handle->SetPortAndMask(msg->dart_port, msg->data);
987 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) { 999 }
988 // Only set mask if we turned on kInEvent or kOutEvent.
989 handle->SetPortAndMask(msg->dart_port, msg->data);
990 1000
991 // If in events (data available events) have been requested, and data 1001 // Issue a read.
992 // is available, post an in event immediately. Otherwise make sure 1002 if ((msg->data & (1 << kInEvent)) != 0) {
993 // that a pending read is issued, unless the socket is already closed 1003 handle->SetPortAndMask(msg->dart_port, msg->data);
994 // for read. 1004 if (handle->is_datagram_socket()) {
995 if ((msg->data & (1 << kInEvent)) != 0) { 1005 handle->IssueRecvFrom();
996 if (handle->Available() > 0) { 1006 } else {
997 int event_mask = (1 << kInEvent); 1007 handle->IssueRead();
998 handle->set_mask(handle->mask() & ~event_mask);
999 DartUtils::PostInt32(handle->port(), event_mask);
1000 } else if (handle->IsClosedRead()) {
1001 int event_mask = (1 << kCloseEvent);
1002 DartUtils::PostInt32(handle->port(), event_mask);
1003 } else if (!handle->HasPendingRead()) {
1004 if (handle->is_datagram_socket()) {
1005 handle->IssueRecvFrom();
1006 } else {
1007 handle->IssueRead();
1008 }
1009 }
1010 }
1011
1012 // If out events (can write events) have been requested, and there
1013 // are no pending writes, post an out event immediately.
1014 if ((msg->data & (1 << kOutEvent)) != 0) {
1015 if (!handle->HasPendingWrite()) {
1016 int event_mask = (1 << kOutEvent);
1017 handle->set_mask(handle->mask() & ~event_mask);
1018 DartUtils::PostInt32(handle->port(), event_mask);
1019 }
1020 }
1021 }
1022
1023 if (handle->is_client_socket()) {
1024 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
1025 if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
1026 client_socket->Shutdown(SD_RECEIVE);
1027 }
1028
1029 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
1030 client_socket->Shutdown(SD_SEND);
1031 }
1032 } 1008 }
1033 } 1009 }
1034 1010
1035 if ((msg->data & (1 << kCloseCommand)) != 0) { 1011 // If out events (can write events) have been requested, and there
1012 // are no pending writes, meaning any writes are already complete,
1013 // post an out event immediately.
1014 if ((msg->data & (1 << kOutEvent)) != 0) {
1036 handle->SetPortAndMask(msg->dart_port, msg->data); 1015 handle->SetPortAndMask(msg->dart_port, msg->data);
1037 handle->Close(); 1016 if (!handle->HasPendingWrite()) {
1017 int event_mask = (1 << kOutEvent);
1018 DartUtils::PostInt32(handle->port(), event_mask);
1019 }
1020 }
1021
1022 if (handle->is_client_socket()) {
1023 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
1024 if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
1025 client_socket->Shutdown(SD_RECEIVE);
1026 }
1027
1028 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
1029 client_socket->Shutdown(SD_SEND);
1030 }
1038 } 1031 }
1039 } 1032 }
1033
1034 if ((msg->data & (1 << kCloseCommand)) != 0) {
1035 handle->SetPortAndMask(msg->dart_port, msg->data);
1036 handle->Close();
1037 }
1038
1040 DeleteIfClosed(handle); 1039 DeleteIfClosed(handle);
1041 } 1040 }
1042 } 1041 }
1043 1042
1044 1043
1045 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket, 1044 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket,
1046 OverlappedBuffer* buffer) { 1045 OverlappedBuffer* buffer) {
1047 listen_socket->AcceptComplete(buffer, completion_port_); 1046 listen_socket->AcceptComplete(buffer, completion_port_);
1048 1047
1049 if (!listen_socket->IsClosing()) { 1048 if (!listen_socket->IsClosing()) {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 1301
1303 1302
1304 void EventHandlerImplementation::Shutdown() { 1303 void EventHandlerImplementation::Shutdown() {
1305 SendData(kShutdownId, 0, 0); 1304 SendData(kShutdownId, 0, 0);
1306 } 1305 }
1307 1306
1308 } // namespace bin 1307 } // namespace bin
1309 } // namespace dart 1308 } // namespace dart
1310 1309
1311 #endif // defined(TARGET_OS_WINDOWS) 1310 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_macos.cc ('k') | runtime/bin/file_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698