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

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

Issue 12316036: Merge IO v2 branch to bleeding edge (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased to r18818 Created 7 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_win.h ('k') | runtime/bin/file.h » ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 <process.h> // NOLINT 10 #include <process.h> // NOLINT
11 #include <winsock2.h> // NOLINT 11 #include <winsock2.h> // NOLINT
12 #include <ws2tcpip.h> // NOLINT 12 #include <ws2tcpip.h> // NOLINT
13 #include <mswsock.h> // NOLINT 13 #include <mswsock.h> // NOLINT
14 14
15 #include "bin/builtin.h" 15 #include "bin/builtin.h"
16 #include "bin/dartutils.h" 16 #include "bin/dartutils.h"
17 #include "bin/log.h" 17 #include "bin/log.h"
18 #include "bin/socket.h" 18 #include "bin/socket.h"
19 #include "bin/utils.h" 19 #include "bin/utils.h"
20 #include "platform/thread.h" 20 #include "platform/thread.h"
21 21
22 22
23 static const int kInfinityTimeout = -1; 23 static const int kInfinityTimeout = -1;
24 static const int kTimeoutId = -1; 24 static const int kTimeoutId = -1;
25 static const int kShutdownId = -2; 25 static const int kShutdownId = -2;
26 26
27
28 IOBuffer* IOBuffer::AllocateBuffer(int buffer_size, Operation operation) { 27 IOBuffer* IOBuffer::AllocateBuffer(int buffer_size, Operation operation) {
29 IOBuffer* buffer = new(buffer_size) IOBuffer(buffer_size, operation); 28 IOBuffer* buffer = new(buffer_size) IOBuffer(buffer_size, operation);
30 return buffer; 29 return buffer;
31 } 30 }
32 31
33 32
34 IOBuffer* IOBuffer::AllocateAcceptBuffer(int buffer_size) { 33 IOBuffer* IOBuffer::AllocateAcceptBuffer(int buffer_size) {
35 IOBuffer* buffer = AllocateBuffer(buffer_size, kAccept); 34 IOBuffer* buffer = AllocateBuffer(buffer_size, kAccept);
36 return buffer; 35 return buffer;
37 } 36 }
38 37
39 38
40 IOBuffer* IOBuffer::AllocateReadBuffer(int buffer_size) { 39 IOBuffer* IOBuffer::AllocateReadBuffer(int buffer_size) {
41 return AllocateBuffer(buffer_size, kRead); 40 return AllocateBuffer(buffer_size, kRead);
42 } 41 }
43 42
44 43
45 IOBuffer* IOBuffer::AllocateWriteBuffer(int buffer_size) { 44 IOBuffer* IOBuffer::AllocateWriteBuffer(int buffer_size) {
46 return AllocateBuffer(buffer_size, kWrite); 45 return AllocateBuffer(buffer_size, kWrite);
47 } 46 }
48 47
49 48
49 IOBuffer* IOBuffer::AllocateDisconnectBuffer() {
50 return AllocateBuffer(0, kDisconnect);
51 }
52
53
50 void IOBuffer::DisposeBuffer(IOBuffer* buffer) { 54 void IOBuffer::DisposeBuffer(IOBuffer* buffer) {
51 delete buffer; 55 delete buffer;
52 } 56 }
53 57
54 58
55 IOBuffer* IOBuffer::GetFromOverlapped(OVERLAPPED* overlapped) { 59 IOBuffer* IOBuffer::GetFromOverlapped(OVERLAPPED* overlapped) {
56 IOBuffer* buffer = CONTAINING_RECORD(overlapped, IOBuffer, overlapped_); 60 IOBuffer* buffer = CONTAINING_RECORD(overlapped, IOBuffer, overlapped_);
57 return buffer; 61 return buffer;
58 } 62 }
59 63
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 reinterpret_cast<ULONG_PTR>(this), 137 reinterpret_cast<ULONG_PTR>(this),
134 0); 138 0);
135 if (completion_port_ == NULL) { 139 if (completion_port_ == NULL) {
136 Log::PrintErr("Error CreateIoCompletionPort: %d\n", GetLastError()); 140 Log::PrintErr("Error CreateIoCompletionPort: %d\n", GetLastError());
137 return false; 141 return false;
138 } 142 }
139 return true; 143 return true;
140 } 144 }
141 145
142 146
143 void Handle::close() { 147 void Handle::Close() {
144 ScopedLock lock(this); 148 ScopedLock lock(this);
145 if (!IsClosing()) { 149 if (!IsClosing()) {
146 // Close the socket and set the closing state. This close method can be 150 // Close the socket and set the closing state. This close method can be
147 // called again if this socket has pending IO operations in flight. 151 // called again if this socket has pending IO operations in flight.
148 ASSERT(handle_ != INVALID_HANDLE_VALUE); 152 ASSERT(handle_ != INVALID_HANDLE_VALUE);
149 MarkClosing(); 153 MarkClosing();
150 // According to the documentation from Microsoft socket handles should 154 // Perform handle type specific closing.
151 // not be closed using CloseHandle but using closesocket. 155 DoClose();
152 if (is_socket()) {
153 closesocket(reinterpret_cast<SOCKET>(handle_));
154 } else {
155 CloseHandle(handle_);
156 }
157 handle_ = INVALID_HANDLE_VALUE;
158 } 156 }
159
160 // Perform socket type specific close handling.
161 AfterClose();
162 } 157 }
163 158
164 159
160 void Handle::DoClose() {
161 CloseHandle(handle_);
162 handle_ = INVALID_HANDLE_VALUE;
163 }
164
165
165 bool Handle::HasPendingRead() { 166 bool Handle::HasPendingRead() {
166 ScopedLock lock(this); 167 ScopedLock lock(this);
167 return pending_read_ != NULL; 168 return pending_read_ != NULL;
168 } 169 }
169 170
170 171
171 bool Handle::HasPendingWrite() { 172 bool Handle::HasPendingWrite() {
172 ScopedLock lock(this); 173 ScopedLock lock(this);
173 return pending_write_ != NULL; 174 return pending_write_ != NULL;
174 } 175 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 CreateCompletionPort(event_handler_->completion_port()); 307 CreateCompletionPort(event_handler_->completion_port());
307 } 308 }
308 } 309 }
309 310
310 311
311 bool FileHandle::IsClosed() { 312 bool FileHandle::IsClosed() {
312 return false; 313 return false;
313 } 314 }
314 315
315 316
316 void FileHandle::AfterClose() {
317 }
318
319
320 void SocketHandle::HandleIssueError() { 317 void SocketHandle::HandleIssueError() {
321 int error = WSAGetLastError(); 318 int error = WSAGetLastError();
322 if (error == WSAECONNRESET) { 319 if (error == WSAECONNRESET) {
323 event_handler_->HandleClosed(this); 320 event_handler_->HandleClosed(this);
324 } else { 321 } else {
325 event_handler_->HandleError(this); 322 event_handler_->HandleError(this);
326 } 323 }
327 WSASetLastError(error); 324 WSASetLastError(error);
328 } 325 }
329 326
330 327
331 bool ListenSocket::LoadAcceptEx() { 328 bool ListenSocket::LoadAcceptEx() {
332 // Load the AcceptEx function into memory using WSAIoctl. 329 // Load the AcceptEx function into memory using WSAIoctl.
333 // The WSAIoctl function is an extension of the ioctlsocket()
334 // function that can use overlapped I/O. The function's 3rd
335 // through 6th parameters are input and output buffers where
336 // we pass the pointer to our AcceptEx function. This is used
337 // so that we can call the AcceptEx function directly, rather
338 // than refer to the Mswsock.lib library.
339 GUID guid_accept_ex = WSAID_ACCEPTEX; 330 GUID guid_accept_ex = WSAID_ACCEPTEX;
340 DWORD bytes; 331 DWORD bytes;
341 int status = WSAIoctl(socket(), 332 int status = WSAIoctl(socket(),
342 SIO_GET_EXTENSION_FUNCTION_POINTER, 333 SIO_GET_EXTENSION_FUNCTION_POINTER,
343 &guid_accept_ex, 334 &guid_accept_ex,
344 sizeof(guid_accept_ex), 335 sizeof(guid_accept_ex),
345 &AcceptEx_, 336 &AcceptEx_,
346 sizeof(AcceptEx_), 337 sizeof(AcceptEx_),
347 &bytes, 338 &bytes,
348 NULL, 339 NULL,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 void ListenSocket::AcceptComplete(IOBuffer* buffer, HANDLE completion_port) { 387 void ListenSocket::AcceptComplete(IOBuffer* buffer, HANDLE completion_port) {
397 ScopedLock lock(this); 388 ScopedLock lock(this);
398 if (!IsClosing()) { 389 if (!IsClosing()) {
399 // Update the accepted socket to support the full range of API calls. 390 // Update the accepted socket to support the full range of API calls.
400 SOCKET s = socket(); 391 SOCKET s = socket();
401 int rc = setsockopt(buffer->client(), 392 int rc = setsockopt(buffer->client(),
402 SOL_SOCKET, 393 SOL_SOCKET,
403 SO_UPDATE_ACCEPT_CONTEXT, 394 SO_UPDATE_ACCEPT_CONTEXT,
404 reinterpret_cast<char*>(&s), sizeof(s)); 395 reinterpret_cast<char*>(&s), sizeof(s));
405 if (rc == NO_ERROR) { 396 if (rc == NO_ERROR) {
406 linger l;
407 l.l_onoff = 1;
408 l.l_linger = 10;
409 int status = setsockopt(buffer->client(),
410 SOL_SOCKET,
411 SO_LINGER,
412 reinterpret_cast<char*>(&l),
413 sizeof(l));
414 if (status != NO_ERROR) {
415 FATAL("Failed setting SO_LINGER on socket");
416 }
417 // Insert the accepted socket into the list. 397 // Insert the accepted socket into the list.
418 ClientSocket* client_socket = new ClientSocket(buffer->client(), 0); 398 ClientSocket* client_socket = new ClientSocket(buffer->client(), 0);
419 client_socket->CreateCompletionPort(completion_port); 399 client_socket->CreateCompletionPort(completion_port);
420 if (accepted_head_ == NULL) { 400 if (accepted_head_ == NULL) {
421 accepted_head_ = client_socket; 401 accepted_head_ = client_socket;
422 accepted_tail_ = client_socket; 402 accepted_tail_ = client_socket;
423 } else { 403 } else {
424 ASSERT(accepted_tail_ != NULL); 404 ASSERT(accepted_tail_ != NULL);
425 accepted_tail_->set_next(client_socket); 405 accepted_tail_->set_next(client_socket);
426 accepted_tail_ = client_socket; 406 accepted_tail_ = client_socket;
427 } 407 }
428 } else { 408 } else {
429 Log::PrintErr("setsockopt failed: %d\n", WSAGetLastError()); 409 Log::PrintErr("setsockopt failed: %d\n", WSAGetLastError());
430 closesocket(buffer->client()); 410 closesocket(buffer->client());
431 } 411 }
432 } 412 }
433 413
434 pending_accept_count_--; 414 pending_accept_count_--;
435 IOBuffer::DisposeBuffer(buffer); 415 IOBuffer::DisposeBuffer(buffer);
436 } 416 }
437 417
438 418
419 void ListenSocket::DoClose() {
420 closesocket(socket());
421 handle_ = INVALID_HANDLE_VALUE;
422 while (CanAccept()) {
423 // Get rid of connections already accepted.
424 ClientSocket *client = Accept();
425 if (client != NULL) {
426 client->Close();
427 } else {
428 break;
429 }
430 }
431 }
432
433
434 bool ListenSocket::CanAccept() {
435 ScopedLock lock(this);
436 return accepted_head_ != NULL;
437 }
438
439
439 ClientSocket* ListenSocket::Accept() { 440 ClientSocket* ListenSocket::Accept() {
440 ScopedLock lock(this); 441 ScopedLock lock(this);
441 if (accepted_head_ == NULL) return NULL; 442 if (accepted_head_ == NULL) return NULL;
442 ClientSocket* result = accepted_head_; 443 ClientSocket* result = accepted_head_;
443 accepted_head_ = accepted_head_->next(); 444 accepted_head_ = accepted_head_->next();
444 if (accepted_head_ == NULL) accepted_tail_ = NULL; 445 if (accepted_head_ == NULL) accepted_tail_ = NULL;
445 result->set_next(NULL); 446 result->set_next(NULL);
446 return result; 447 return result;
447 } 448 }
448 449
449 450
450 void ListenSocket::EnsureInitialized( 451 void ListenSocket::EnsureInitialized(
451 EventHandlerImplementation* event_handler) { 452 EventHandlerImplementation* event_handler) {
452 ScopedLock lock(this); 453 ScopedLock lock(this);
453 if (AcceptEx_ == NULL) { 454 if (AcceptEx_ == NULL) {
454 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); 455 ASSERT(completion_port_ == INVALID_HANDLE_VALUE);
455 ASSERT(event_handler_ == NULL); 456 ASSERT(event_handler_ == NULL);
456 event_handler_ = event_handler; 457 event_handler_ = event_handler;
457 CreateCompletionPort(event_handler_->completion_port()); 458 CreateCompletionPort(event_handler_->completion_port());
458 LoadAcceptEx(); 459 LoadAcceptEx();
459 } 460 }
460 } 461 }
461 462
462 463
463 void ListenSocket::AfterClose() {
464 ScopedLock lock(this);
465 while (true) {
466 // Get rid of connections already accepted.
467 ClientSocket *client = Accept();
468 if (client != NULL) {
469 client->close();
470 } else {
471 break;
472 }
473 }
474 }
475
476
477 bool ListenSocket::IsClosed() { 464 bool ListenSocket::IsClosed() {
478 return IsClosing() && !HasPendingAccept(); 465 return IsClosing() && !HasPendingAccept();
479 } 466 }
480 467
481 468
482 int Handle::Available() { 469 int Handle::Available() {
483 ScopedLock lock(this); 470 ScopedLock lock(this);
484 if (data_ready_ == NULL) return 0; 471 if (data_ready_ == NULL) return 0;
485 ASSERT(!data_ready_->IsEmpty()); 472 ASSERT(!data_ready_->IsEmpty());
486 return data_ready_->GetRemainingLength(); 473 return data_ready_->GetRemainingLength();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 if (GetLastError() != ERROR_BROKEN_PIPE) { 507 if (GetLastError() != ERROR_BROKEN_PIPE) {
521 Log::PrintErr("WriteFile failed: %d\n", GetLastError()); 508 Log::PrintErr("WriteFile failed: %d\n", GetLastError());
522 } 509 }
523 event_handler_->HandleClosed(this); 510 event_handler_->HandleClosed(this);
524 } 511 }
525 return bytes_written; 512 return bytes_written;
526 } 513 }
527 } 514 }
528 515
529 516
517 bool ClientSocket::LoadDisconnectEx() {
518 // Load the DisconnectEx function into memory using WSAIoctl.
519 GUID guid_disconnect_ex = WSAID_DISCONNECTEX;
520 DWORD bytes;
521 int status = WSAIoctl(socket(),
522 SIO_GET_EXTENSION_FUNCTION_POINTER,
523 &guid_disconnect_ex,
524 sizeof(guid_disconnect_ex),
525 &DisconnectEx_,
526 sizeof(DisconnectEx_),
527 &bytes,
528 NULL,
529 NULL);
530 if (status == SOCKET_ERROR) {
531 Log::PrintErr("Error WSAIoctl failed: %d\n", WSAGetLastError());
532 return false;
533 }
534 return true;
535 }
536
537
530 void ClientSocket::Shutdown(int how) { 538 void ClientSocket::Shutdown(int how) {
531 int rc = shutdown(socket(), how); 539 int rc = shutdown(socket(), how);
532 if (rc == SOCKET_ERROR) {
533 Log::PrintErr("shutdown failed: %d %d\n", socket(), WSAGetLastError());
534 }
535 if (how == SD_RECEIVE) MarkClosedRead(); 540 if (how == SD_RECEIVE) MarkClosedRead();
536 if (how == SD_SEND) MarkClosedWrite(); 541 if (how == SD_SEND) MarkClosedWrite();
537 if (how == SD_BOTH) { 542 if (how == SD_BOTH) {
538 MarkClosedRead(); 543 MarkClosedRead();
539 MarkClosedWrite(); 544 MarkClosedWrite();
540 } 545 }
541 } 546 }
542 547
543 548
549 void ClientSocket::DoClose() {
550 // Always do a suhtdown before initiating a disconnect.
551 shutdown(socket(), SD_BOTH);
552 IssueDisconnect();
553 }
554
555
544 bool ClientSocket::IssueRead() { 556 bool ClientSocket::IssueRead() {
545 ScopedLock lock(this); 557 ScopedLock lock(this);
546 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); 558 ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
547 ASSERT(pending_read_ == NULL); 559 ASSERT(pending_read_ == NULL);
548 560
549 IOBuffer* buffer = IOBuffer::AllocateReadBuffer(1024); 561 IOBuffer* buffer = IOBuffer::AllocateReadBuffer(1024);
550 562
551 DWORD flags; 563 DWORD flags;
552 flags = 0; 564 flags = 0;
553 int rc = WSARecv(socket(), 565 int rc = WSARecv(socket(),
(...skipping 30 matching lines...) Expand all
584 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) { 596 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) {
585 return true; 597 return true;
586 } 598 }
587 IOBuffer::DisposeBuffer(pending_write_); 599 IOBuffer::DisposeBuffer(pending_write_);
588 pending_write_ = NULL; 600 pending_write_ = NULL;
589 HandleIssueError(); 601 HandleIssueError();
590 return false; 602 return false;
591 } 603 }
592 604
593 605
606 void ClientSocket::IssueDisconnect() {
607 IOBuffer* buffer = IOBuffer::AllocateDisconnectBuffer();
608 BOOL ok = DisconnectEx_(
609 socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0);
610 if (!ok && WSAGetLastError() != WSA_IO_PENDING) {
611 DisconnectComplete(buffer);
612 }
613 }
614
615
616 void ClientSocket::DisconnectComplete(IOBuffer* buffer) {
617 IOBuffer::DisposeBuffer(buffer);
618 closesocket(socket());
619 if (data_ready_ != NULL) {
620 IOBuffer::DisposeBuffer(data_ready_);
621 }
622 // When disconnect is complete get rid of the object.
623 delete this;
624 }
625
626
594 void ClientSocket::EnsureInitialized( 627 void ClientSocket::EnsureInitialized(
595 EventHandlerImplementation* event_handler) { 628 EventHandlerImplementation* event_handler) {
596 ScopedLock lock(this); 629 ScopedLock lock(this);
597 if (completion_port_ == INVALID_HANDLE_VALUE) { 630 if (completion_port_ == INVALID_HANDLE_VALUE) {
598 ASSERT(event_handler_ == NULL); 631 ASSERT(event_handler_ == NULL);
599 event_handler_ = event_handler; 632 event_handler_ = event_handler;
600 CreateCompletionPort(event_handler_->completion_port()); 633 CreateCompletionPort(event_handler_->completion_port());
601 } 634 }
602 } 635 }
603 636
604 637
605 void ClientSocket::AfterClose() {
606 ScopedLock lock(this);
607 if (data_ready_ != NULL) {
608 IOBuffer::DisposeBuffer(data_ready_);
609 data_ready_ = NULL;
610 }
611 }
612
613
614 bool ClientSocket::IsClosed() { 638 bool ClientSocket::IsClosed() {
615 return IsClosing() && !HasPendingRead() && !HasPendingWrite(); 639 return false;
616 } 640 }
617 641
618 642
619 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { 643 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) {
620 if (msg->id == kTimeoutId) { 644 if (msg->id == kTimeoutId) {
621 // Change of timeout request. Just set the new timeout and port as the 645 // Change of timeout request. Just set the new timeout and port as the
622 // completion thread will use the new timeout value for its next wait. 646 // completion thread will use the new timeout value for its next wait.
623 timeout_ = msg->data; 647 timeout_ = msg->data;
624 timeout_port_ = msg->dart_port; 648 timeout_port_ = msg->dart_port;
625 } else if (msg->id == kShutdownId) { 649 } else if (msg->id == kShutdownId) {
626 shutdown_ = true; 650 shutdown_ = true;
627 } else { 651 } else {
628 bool delete_handle = false; 652 bool delete_handle = false;
629 Handle* handle = reinterpret_cast<Handle*>(msg->id); 653 Handle* handle = reinterpret_cast<Handle*>(msg->id);
630 ASSERT(handle != NULL); 654 ASSERT(handle != NULL);
631 if (handle->is_listen_socket()) { 655 if (handle->is_listen_socket()) {
632 ListenSocket* listen_socket = 656 ListenSocket* listen_socket =
633 reinterpret_cast<ListenSocket*>(handle); 657 reinterpret_cast<ListenSocket*>(handle);
634 listen_socket->EnsureInitialized(this); 658 listen_socket->EnsureInitialized(this);
635 listen_socket->SetPortAndMask(msg->dart_port, msg->data); 659 listen_socket->SetPortAndMask(msg->dart_port, msg->data);
636 660
637 Handle::ScopedLock lock(listen_socket); 661 Handle::ScopedLock lock(listen_socket);
638 662
639 // If incomming connections are requested make sure that pending accepts 663 // If incomming connections are requested make sure to post already
640 // are issued. 664 // accepted connections.
641 if ((msg->data & (1 << kInEvent)) != 0) { 665 if ((msg->data & (1 << kInEvent)) != 0) {
666 if (listen_socket->CanAccept()) {
667 int event_mask = (1 << kInEvent);
668 handle->set_mask(handle->mask() & ~event_mask);
669 DartUtils::PostInt32(handle->port(), event_mask);
670 }
671 // Always keep 5 outstanding accepts going, to enhance performance.
642 while (listen_socket->pending_accept_count() < 5) { 672 while (listen_socket->pending_accept_count() < 5) {
643 listen_socket->IssueAccept(); 673 listen_socket->IssueAccept();
644 } 674 }
645 } 675 }
646 676
647 if ((msg->data & (1 << kCloseCommand)) != 0) { 677 if ((msg->data & (1 << kCloseCommand)) != 0) {
648 listen_socket->close(); 678 listen_socket->Close();
649 if (listen_socket->IsClosed()) { 679 if (listen_socket->IsClosed()) {
650 delete_handle = true; 680 delete_handle = true;
651 } 681 }
652 } 682 }
653 } else { 683 } else {
654 handle->SetPortAndMask(msg->dart_port, msg->data);
655 handle->EnsureInitialized(this); 684 handle->EnsureInitialized(this);
656 685
657 Handle::ScopedLock lock(handle); 686 Handle::ScopedLock lock(handle);
658 687
659 if (!handle->IsError()) { 688 if (!handle->IsError()) {
660 // If in events (data available events) have been requested, and data 689 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) {
661 // is available, post an in event immediately. Otherwise make sure 690 // Only set mask if we turned on kInEvent or kOutEvent.
662 // that a pending read is issued, unless the socket is already closed 691 handle->SetPortAndMask(msg->dart_port, msg->data);
663 // for read. 692
664 if ((msg->data & (1 << kInEvent)) != 0) { 693 // If in events (data available events) have been requested, and data
665 if (handle->Available() > 0) { 694 // is available, post an in event immediately. Otherwise make sure
666 int event_mask = (1 << kInEvent); 695 // that a pending read is issued, unless the socket is already closed
667 handle->set_mask(handle->mask() & ~event_mask); 696 // for read.
668 DartUtils::PostInt32(handle->port(), event_mask); 697 if ((msg->data & (1 << kInEvent)) != 0) {
669 } else if (!handle->HasPendingRead() && 698 if (handle->Available() > 0) {
670 !handle->IsClosedRead()) { 699 int event_mask = (1 << kInEvent);
671 handle->IssueRead(); 700 handle->set_mask(handle->mask() & ~event_mask);
701 DartUtils::PostInt32(handle->port(), event_mask);
702 } else if (handle->IsClosedRead()) {
703 int event_mask = (1 << kCloseEvent);
704 DartUtils::PostInt32(handle->port(), event_mask);
705 } else if (!handle->HasPendingRead()) {
706 handle->IssueRead();
707 }
708 }
709
710 // If out events (can write events) have been requested, and there
711 // are no pending writes, post an out event immediately.
712 if ((msg->data & (1 << kOutEvent)) != 0) {
713 if (!handle->HasPendingWrite()) {
714 int event_mask = (1 << kOutEvent);
715 handle->set_mask(handle->mask() & ~event_mask);
716 DartUtils::PostInt32(handle->port(), event_mask);
717 }
672 } 718 }
673 } 719 }
674 720
675 // If out events (can write events) have been requested, and there
676 // are no pending writes, post an out event immediately.
677 if ((msg->data & (1 << kOutEvent)) != 0) {
678 if (!handle->HasPendingWrite()) {
679 int event_mask = (1 << kOutEvent);
680 handle->set_mask(handle->mask() & ~event_mask);
681 DartUtils::PostInt32(handle->port(), event_mask);
682 }
683 }
684
685 if (handle->is_client_socket()) { 721 if (handle->is_client_socket()) {
686 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle); 722 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
687 if ((msg->data & (1 << kShutdownReadCommand)) != 0) { 723 if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
688 client_socket->Shutdown(SD_RECEIVE); 724 client_socket->Shutdown(SD_RECEIVE);
689 } 725 }
690 726
691 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) { 727 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
692 client_socket->Shutdown(SD_SEND); 728 client_socket->Shutdown(SD_SEND);
693 } 729 }
694 } 730 }
695 } 731 }
696 732
697 if ((msg->data & (1 << kCloseCommand)) != 0) { 733 if ((msg->data & (1 << kCloseCommand)) != 0) {
698 handle->close(); 734 handle->Close();
699 if (handle->IsClosed()) { 735 if (handle->IsClosed()) {
700 delete_handle = true; 736 delete_handle = true;
701 } 737 }
702 } 738 }
703 } 739 }
704 if (delete_handle) { 740 if (delete_handle) {
705 delete handle; 741 delete handle;
706 } 742 }
707 } 743 }
708 } 744 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 } else { 823 } else {
788 HandleError(handle); 824 HandleError(handle);
789 } 825 }
790 826
791 if (handle->IsClosed()) { 827 if (handle->IsClosed()) {
792 delete handle; 828 delete handle;
793 } 829 }
794 } 830 }
795 831
796 832
833 void EventHandlerImplementation::HandleDisconnect(
834 ClientSocket* client_socket,
835 int bytes,
836 IOBuffer* buffer) {
837 client_socket->DisconnectComplete(buffer);
838 }
839
797 void EventHandlerImplementation::HandleTimeout() { 840 void EventHandlerImplementation::HandleTimeout() {
798 // TODO(sgjesse) check if there actually is a timeout. 841 // TODO(sgjesse) check if there actually is a timeout.
799 DartUtils::PostNull(timeout_port_); 842 DartUtils::PostNull(timeout_port_);
800 timeout_ = kInfinityTimeout; 843 timeout_ = kInfinityTimeout;
801 timeout_port_ = 0; 844 timeout_port_ = 0;
802 } 845 }
803 846
804 847
805 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, 848 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes,
806 ULONG_PTR key, 849 ULONG_PTR key,
807 OVERLAPPED* overlapped) { 850 OVERLAPPED* overlapped) {
808 IOBuffer* buffer = IOBuffer::GetFromOverlapped(overlapped); 851 IOBuffer* buffer = IOBuffer::GetFromOverlapped(overlapped);
809 switch (buffer->operation()) { 852 switch (buffer->operation()) {
810 case IOBuffer::kAccept: { 853 case IOBuffer::kAccept: {
811 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(key); 854 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(key);
812 HandleAccept(listen_socket, buffer); 855 HandleAccept(listen_socket, buffer);
813 break; 856 break;
814 } 857 }
815 case IOBuffer::kRead: { 858 case IOBuffer::kRead: {
816 Handle* handle = reinterpret_cast<Handle*>(key); 859 Handle* handle = reinterpret_cast<Handle*>(key);
817 HandleRead(handle, bytes, buffer); 860 HandleRead(handle, bytes, buffer);
818 break; 861 break;
819 } 862 }
820 case IOBuffer::kWrite: { 863 case IOBuffer::kWrite: {
821 Handle* handle = reinterpret_cast<Handle*>(key); 864 Handle* handle = reinterpret_cast<Handle*>(key);
822 HandleWrite(handle, bytes, buffer); 865 HandleWrite(handle, bytes, buffer);
823 break; 866 break;
824 } 867 }
868 case IOBuffer::kDisconnect: {
869 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key);
870 HandleDisconnect(client_socket, bytes, buffer);
871 break;
872 }
825 default: 873 default:
826 UNREACHABLE(); 874 UNREACHABLE();
827 } 875 }
828 } 876 }
829 877
830 878
831 EventHandlerImplementation::EventHandlerImplementation() { 879 EventHandlerImplementation::EventHandlerImplementation() {
832 intptr_t result; 880 intptr_t result;
833 completion_port_ = 881 completion_port_ =
834 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); 882 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 FATAL("Failed to initialized Windows sockets"); 977 FATAL("Failed to initialized Windows sockets");
930 } 978 }
931 } 979 }
932 980
933 981
934 void EventHandlerImplementation::Shutdown() { 982 void EventHandlerImplementation::Shutdown() {
935 SendData(kShutdownId, 0, 0); 983 SendData(kShutdownId, 0, 0);
936 } 984 }
937 985
938 #endif // defined(TARGET_OS_WINDOWS) 986 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_win.h ('k') | runtime/bin/file.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698