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

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: Mac os X support. 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
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 if (pending_read_ != NULL) return true;
Søren Gjesse 2014/02/18 14:28:00 Should this ever happen?
Anders Johnsen 2014/02/19 09:43:03 Yes, in this case only. Will add comment.
376 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); 377 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize);
377 378
378 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); 379 ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
379 380
380 BOOL ok = ReadDirectoryChangesW(handle_, 381 BOOL ok = ReadDirectoryChangesW(handle_,
381 buffer->GetBufferStart(), 382 buffer->GetBufferStart(),
382 buffer->GetBufferSize(), 383 buffer->GetBufferSize(),
383 recursive_, 384 recursive_,
384 events_, 385 events_,
385 NULL, 386 NULL,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 } 523 }
523 524
524 525
525 ClientSocket* ListenSocket::Accept() { 526 ClientSocket* ListenSocket::Accept() {
526 ScopedLock lock(this); 527 ScopedLock lock(this);
527 if (accepted_head_ == NULL) return NULL; 528 if (accepted_head_ == NULL) return NULL;
528 ClientSocket* result = accepted_head_; 529 ClientSocket* result = accepted_head_;
529 accepted_head_ = accepted_head_->next(); 530 accepted_head_ = accepted_head_->next();
530 if (accepted_head_ == NULL) accepted_tail_ = NULL; 531 if (accepted_head_ == NULL) accepted_tail_ = NULL;
531 result->set_next(NULL); 532 result->set_next(NULL);
533 if (!IsClosing()) {
534 while (pending_accept_count() < 5) {
535 if (!IssueAccept()) {
536 event_handler_->HandleError(this);
537 }
538 }
539 }
532 return result; 540 return result;
533 } 541 }
534 542
535 543
536 void ListenSocket::EnsureInitialized( 544 void ListenSocket::EnsureInitialized(
537 EventHandlerImplementation* event_handler) { 545 EventHandlerImplementation* event_handler) {
538 ScopedLock lock(this); 546 ScopedLock lock(this);
539 if (AcceptEx_ == NULL) { 547 if (AcceptEx_ == NULL) {
540 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); 548 ASSERT(completion_port_ == INVALID_HANDLE_VALUE);
541 ASSERT(event_handler_ == NULL); 549 ASSERT(event_handler_ == NULL);
(...skipping 17 matching lines...) Expand all
559 } 567 }
560 568
561 569
562 int Handle::Read(void* buffer, int num_bytes) { 570 int Handle::Read(void* buffer, int num_bytes) {
563 ScopedLock lock(this); 571 ScopedLock lock(this);
564 if (data_ready_ == NULL) return 0; 572 if (data_ready_ == NULL) return 0;
565 num_bytes = data_ready_->Read(buffer, num_bytes); 573 num_bytes = data_ready_->Read(buffer, num_bytes);
566 if (data_ready_->IsEmpty()) { 574 if (data_ready_->IsEmpty()) {
567 OverlappedBuffer::DisposeBuffer(data_ready_); 575 OverlappedBuffer::DisposeBuffer(data_ready_);
568 data_ready_ = NULL; 576 data_ready_ = NULL;
577 if (!IsClosing() && !IsClosedRead()) IssueRead();
569 } 578 }
570 return num_bytes; 579 return num_bytes;
571 } 580 }
572 581
573 582
574 int Handle::RecvFrom( 583 int Handle::RecvFrom(
575 void* buffer, int num_bytes, struct sockaddr* sa, socklen_t sa_len) { 584 void* buffer, int num_bytes, struct sockaddr* sa, socklen_t sa_len) {
576 ScopedLock lock(this); 585 ScopedLock lock(this);
577 if (data_ready_ == NULL) return 0; 586 if (data_ready_ == NULL) return 0;
578 num_bytes = data_ready_->Read(buffer, num_bytes); 587 num_bytes = data_ready_->Read(buffer, num_bytes);
579 if (data_ready_->from()->sa_family == AF_INET) { 588 if (data_ready_->from()->sa_family == AF_INET) {
580 ASSERT(sa_len >= sizeof(struct sockaddr_in)); 589 ASSERT(sa_len >= sizeof(struct sockaddr_in));
581 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); 590 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in));
582 } else { 591 } else {
583 ASSERT(data_ready_->from()->sa_family == AF_INET6); 592 ASSERT(data_ready_->from()->sa_family == AF_INET6);
584 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); 593 ASSERT(sa_len >= sizeof(struct sockaddr_in6));
585 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); 594 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6));
586 } 595 }
587 // Always dispose of the buffer, as UDP messages must be read in their 596 // Always dispose of the buffer, as UDP messages must be read in their
588 // entirety to match how recvfrom works in a socket. 597 // entirety to match how recvfrom works in a socket.
589 OverlappedBuffer::DisposeBuffer(data_ready_); 598 OverlappedBuffer::DisposeBuffer(data_ready_);
590 data_ready_ = NULL; 599 data_ready_ = NULL;
600 if (!IsClosing() && !IsClosedRead()) IssueRecvFrom();
591 return num_bytes; 601 return num_bytes;
592 } 602 }
593 603
594 604
595 int Handle::Write(const void* buffer, int num_bytes) { 605 int Handle::Write(const void* buffer, int num_bytes) {
596 ScopedLock lock(this); 606 ScopedLock lock(this);
597 if (pending_write_ != NULL) return 0; 607 if (pending_write_ != NULL) return 0;
598 if (num_bytes > kBufferSize) num_bytes = kBufferSize; 608 if (num_bytes > kBufferSize) num_bytes = kBufferSize;
599 ASSERT(SupportsOverlappedIO()); 609 ASSERT(SupportsOverlappedIO());
600 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; 610 if (completion_port_ == INVALID_HANDLE_VALUE) return 0;
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 } 984 }
975 985
976 if ((msg->data & (1 << kCloseCommand)) != 0) { 986 if ((msg->data & (1 << kCloseCommand)) != 0) {
977 listen_socket->Close(); 987 listen_socket->Close();
978 } 988 }
979 } else { 989 } else {
980 handle->EnsureInitialized(this); 990 handle->EnsureInitialized(this);
981 991
982 Handle::ScopedLock lock(handle); 992 Handle::ScopedLock lock(handle);
983 993
984 if (handle->IsError()) { 994 // Only set mask if we turned on kInEvent or kOutEvent.
Søren Gjesse 2014/02/18 14:28:00 What are the cases where neither in nor out events
Anders Johnsen 2014/02/19 09:43:03 close/shutdown before we listen for data. An examp
985 DartUtils::PostInt32(msg->dart_port, 1 << kErrorEvent); 995 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) {
986 } else { 996 handle->SetPortAndMask(msg->dart_port, msg->data);
987 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) { 997 }
988 // Only set mask if we turned on kInEvent or kOutEvent.
989 handle->SetPortAndMask(msg->dart_port, msg->data);
990 998
991 // If in events (data available events) have been requested, and data 999 // Issue a read.
992 // is available, post an in event immediately. Otherwise make sure 1000 if ((msg->data & (1 << kInEvent)) != 0) {
993 // that a pending read is issued, unless the socket is already closed 1001 handle->SetPortAndMask(msg->dart_port, msg->data);
994 // for read. 1002 if (handle->is_datagram_socket()) {
995 if ((msg->data & (1 << kInEvent)) != 0) { 1003 handle->IssueRecvFrom();
996 if (handle->Available() > 0) { 1004 } else {
997 int event_mask = (1 << kInEvent); 1005 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 } 1006 }
1033 } 1007 }
1034 1008
1035 if ((msg->data & (1 << kCloseCommand)) != 0) { 1009 // If out events (can write events) have been requested, and there
1010 // are no pending writes, post an out event immediately.
Søren Gjesse 2014/02/18 14:28:00 You should probably explain that no pending write
Anders Johnsen 2014/02/19 09:43:03 Done.
1011 if ((msg->data & (1 << kOutEvent)) != 0) {
1036 handle->SetPortAndMask(msg->dart_port, msg->data); 1012 handle->SetPortAndMask(msg->dart_port, msg->data);
1037 handle->Close(); 1013 if (!handle->HasPendingWrite()) {
1014 int event_mask = (1 << kOutEvent);
1015 DartUtils::PostInt32(handle->port(), event_mask);
1016 }
1017 }
1018
1019 if (handle->is_client_socket()) {
1020 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
1021 if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
1022 client_socket->Shutdown(SD_RECEIVE);
1023 }
1024
1025 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
1026 client_socket->Shutdown(SD_SEND);
1027 }
1038 } 1028 }
1039 } 1029 }
1030
1031 if ((msg->data & (1 << kCloseCommand)) != 0) {
1032 handle->SetPortAndMask(msg->dart_port, msg->data);
1033 handle->Close();
1034 }
1035
1040 DeleteIfClosed(handle); 1036 DeleteIfClosed(handle);
1041 } 1037 }
1042 } 1038 }
1043 1039
1044 1040
1045 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket, 1041 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket,
1046 OverlappedBuffer* buffer) { 1042 OverlappedBuffer* buffer) {
1047 listen_socket->AcceptComplete(buffer, completion_port_); 1043 listen_socket->AcceptComplete(buffer, completion_port_);
1048 1044
1049 if (!listen_socket->IsClosing()) { 1045 if (!listen_socket->IsClosing()) {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 1298
1303 1299
1304 void EventHandlerImplementation::Shutdown() { 1300 void EventHandlerImplementation::Shutdown() {
1305 SendData(kShutdownId, 0, 0); 1301 SendData(kShutdownId, 0, 0);
1306 } 1302 }
1307 1303
1308 } // namespace bin 1304 } // namespace bin
1309 } // namespace dart 1305 } // namespace dart
1310 1306
1311 #endif // defined(TARGET_OS_WINDOWS) 1307 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698