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

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

Issue 8437090: Change the handling of closing sockets (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Windows port and frog patch Created 9 years, 1 month 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/input_stream.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 <process.h> 5 #include <process.h>
6 #include <winsock2.h> 6 #include <winsock2.h>
7 #include <ws2tcpip.h> 7 #include <ws2tcpip.h>
8 #include <mswsock.h> 8 #include <mswsock.h>
9 9
10 #include "bin/builtin.h" 10 #include "bin/builtin.h"
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 335
336 pending_accept_count_++; 336 pending_accept_count_++;
337 337
338 return true; 338 return true;
339 } 339 }
340 340
341 341
342 void ListenSocket::AcceptComplete(IOBuffer* buffer, HANDLE completion_port) { 342 void ListenSocket::AcceptComplete(IOBuffer* buffer, HANDLE completion_port) {
343 ScopedLock lock(this); 343 ScopedLock lock(this);
344 if (!closing_) { 344 if (!closing_) {
345 ClientSocket* client_socket = new ClientSocket(buffer->client(), 0); 345 // Update the accepted socket to support the full range of API calls.
346 client_socket->CreateCompletionPort(completion_port); 346 SOCKET s = socket();
347 if (accepted_head_ == NULL) { 347 int rc = setsockopt(buffer->client(),
348 accepted_head_ = client_socket; 348 SOL_SOCKET,
349 accepted_tail_ = client_socket; 349 SO_UPDATE_ACCEPT_CONTEXT,
350 reinterpret_cast<char *>(&s), sizeof(s));
Mads Ager (google) 2011/11/04 12:21:36 char * -> char*
Søren Gjesse 2011/11/04 12:33:02 Done.
351 if (rc == NO_ERROR) {
352 // Insert the accepted socket into the list.
353 ClientSocket* client_socket = new ClientSocket(buffer->client(), 0);
354 client_socket->CreateCompletionPort(completion_port);
355 if (accepted_head_ == NULL) {
356 accepted_head_ = client_socket;
357 accepted_tail_ = client_socket;
358 } else {
359 ASSERT(accepted_tail_ != NULL);
360 accepted_tail_->set_next(client_socket);
361 accepted_tail_ = client_socket;
362 }
350 } else { 363 } else {
351 ASSERT(accepted_tail_ != NULL); 364 fprintf(stderr, "setsockopt failed: %d\n", WSAGetLastError());
352 accepted_tail_->set_next(client_socket); 365 closesocket(buffer->client());
353 accepted_tail_ = client_socket;
354 } 366 }
355 } else {
356 closesocket(buffer->client());
357 } 367 }
368
358 pending_accept_count_--; 369 pending_accept_count_--;
359 IOBuffer::DisposeBuffer(buffer); 370 IOBuffer::DisposeBuffer(buffer);
360 } 371 }
361 372
362 373
363 ClientSocket* ListenSocket::Accept() { 374 ClientSocket* ListenSocket::Accept() {
364 ScopedLock lock(this); 375 ScopedLock lock(this);
365 if (accepted_head_ == NULL) return NULL; 376 if (accepted_head_ == NULL) return NULL;
366 ClientSocket* result = accepted_head_; 377 ClientSocket* result = accepted_head_;
367 accepted_head_ = accepted_head_->next(); 378 accepted_head_ = accepted_head_->next();
368 if (accepted_head_ == NULL) accepted_tail_ = NULL; 379 if (accepted_head_ == NULL) accepted_tail_ = NULL;
380 result->set_next(NULL);
369 return result; 381 return result;
370 } 382 }
371 383
372 384
373 void ListenSocket::EnsureInitialized( 385 void ListenSocket::EnsureInitialized(
374 EventHandlerImplementation* event_handler) { 386 EventHandlerImplementation* event_handler) {
375 ScopedLock lock(this); 387 ScopedLock lock(this);
376 if (AcceptEx_ == NULL) { 388 if (AcceptEx_ == NULL) {
377 ASSERT(completion_port_ == INVALID_HANDLE_VALUE); 389 ASSERT(completion_port_ == INVALID_HANDLE_VALUE);
378 ASSERT(event_handler_ == NULL); 390 ASSERT(event_handler_ == NULL);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 ScopedLock lock(this); 438 ScopedLock lock(this);
427 if (pending_write_ != NULL) return 0; 439 if (pending_write_ != NULL) return 0;
428 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; 440 if (completion_port_ == INVALID_HANDLE_VALUE) return 0;
429 if (num_bytes > 4096) num_bytes = 4096; 441 if (num_bytes > 4096) num_bytes = 4096;
430 pending_write_ = IOBuffer::AllocateWriteBuffer(num_bytes); 442 pending_write_ = IOBuffer::AllocateWriteBuffer(num_bytes);
431 pending_write_->Write(buffer, num_bytes); 443 pending_write_->Write(buffer, num_bytes);
432 IssueWrite(); 444 IssueWrite();
433 return num_bytes; 445 return num_bytes;
434 } 446 }
435 447
448 void ClientSocket::Shutdown(int how) {
449 int rc = shutdown(socket(), how);
450 if (rc == SOCKET_ERROR) {
451 fprintf(stderr, "shutdown failed: %d %d\n", socket(), WSAGetLastError());
452 }
453 if (how == SD_RECEIVE) MarkClosedRead();
454 if (how == SD_SEND) MarkClosedWrite();
455 if (how == SD_BOTH) {
456 MarkClosedRead();
457 MarkClosedWrite();
458 }
459 }
460
436 461
437 bool ClientSocket::IssueRead() { 462 bool ClientSocket::IssueRead() {
438 ScopedLock lock(this); 463 ScopedLock lock(this);
439 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); 464 ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
440 ASSERT(pending_read_ == NULL); 465 ASSERT(pending_read_ == NULL);
441 466
442 IOBuffer* buffer = IOBuffer::AllocateReadBuffer(1024); 467 IOBuffer* buffer = IOBuffer::AllocateReadBuffer(1024);
443 468
444 DWORD flags; 469 DWORD flags;
445 flags = 0; 470 flags = 0;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 } 572 }
548 } 573 }
549 } else { 574 } else {
550 ClientSocket* client_socket = 575 ClientSocket* client_socket =
551 reinterpret_cast<ClientSocket*>(socket_desc); 576 reinterpret_cast<ClientSocket*>(socket_desc);
552 client_socket->SetPortAndMask(msg->dart_port, msg->data); 577 client_socket->SetPortAndMask(msg->dart_port, msg->data);
553 client_socket->EnsureInitialized(this); 578 client_socket->EnsureInitialized(this);
554 579
555 Handle::ScopedLock lock(client_socket); 580 Handle::ScopedLock lock(client_socket);
556 581
557 // If data available callback has been requested and data are 582 // If the data available callback has been requested and data are
558 // available post it immediately. Otherwise make sure that a pending 583 // available post it immediately. Otherwise make sure that a pending
559 // read is issued. 584 // read is issued unless the socket is already closed for read.
560 if ((msg->data & (1 << kInEvent)) != 0) { 585 if ((msg->data & (1 << kInEvent)) != 0) {
561 if (client_socket->Available() > 0) { 586 if (client_socket->Available() > 0) {
562 int event_mask = (1 << kInEvent); 587 int event_mask = (1 << kInEvent);
563 Dart_PostIntArray(client_socket->port(), 1, &event_mask); 588 Dart_PostIntArray(client_socket->port(), 1, &event_mask);
564 } else if (!client_socket->HasPendingRead()) { 589 } else if (!client_socket->HasPendingRead() &&
590 !client_socket->IsClosedRead()) {
565 client_socket->IssueRead(); 591 client_socket->IssueRead();
566 } 592 }
567 } 593 }
568 594
569 // If can send callback had been requested and there is no pending 595 // If can send callback had been requested and there is no pending
570 // send post it immediately. 596 // send post it immediately.
571 if ((msg->data & (1 << kOutEvent)) != 0) { 597 if ((msg->data & (1 << kOutEvent)) != 0) {
572 if (!client_socket->HasPendingWrite()) { 598 if (!client_socket->HasPendingWrite()) {
573 int event_mask = (1 << kOutEvent); 599 int event_mask = (1 << kOutEvent);
574 Dart_PostIntArray(client_socket->port(), 1, &event_mask); 600 Dart_PostIntArray(client_socket->port(), 1, &event_mask);
575 } 601 }
576 } 602 }
577 603
604 if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
605 client_socket->Shutdown(SD_RECEIVE);
606 }
607
608 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
609 client_socket->Shutdown(SD_SEND);
610 }
611
578 if ((msg->data & (1 << kCloseCommand)) != 0) { 612 if ((msg->data & (1 << kCloseCommand)) != 0) {
579 client_socket->close(); 613 client_socket->close();
580 if (client_socket->IsClosed()) { 614 if (client_socket->IsClosed()) {
581 delete_socket = true; 615 delete_socket = true;
582 } 616 }
583 } 617 }
584 } 618 }
585 if (delete_socket) { 619 if (delete_socket) {
586 delete socket_desc; 620 delete socket_desc;
587 } 621 }
(...skipping 26 matching lines...) Expand all
614 } 648 }
615 } 649 }
616 } 650 }
617 651
618 652
619 void EventHandlerImplementation::HandleRead(ClientSocket* client_socket, 653 void EventHandlerImplementation::HandleRead(ClientSocket* client_socket,
620 int bytes, 654 int bytes,
621 IOBuffer* buffer) { 655 IOBuffer* buffer) {
622 buffer->set_data_length(bytes); 656 buffer->set_data_length(bytes);
623 client_socket->ReadComplete(buffer); 657 client_socket->ReadComplete(buffer);
624
625 if (bytes > 0) { 658 if (bytes > 0) {
626 if (!client_socket->is_closing()) { 659 if (!client_socket->is_closing()) {
627 int event_mask = 1 << kInEvent; 660 int event_mask = 1 << kInEvent;
628 if ((client_socket->mask() & event_mask) != 0) { 661 if ((client_socket->mask() & event_mask) != 0) {
629 Dart_PostIntArray(client_socket->port(), 1, &event_mask); 662 Dart_PostIntArray(client_socket->port(), 1, &event_mask);
630 } 663 }
631 } 664 }
632 } else { 665 } else {
633 ASSERT(bytes == 0); 666 ASSERT(bytes == 0);
667 client_socket->MarkClosedRead();
634 HandleClosed(client_socket); 668 HandleClosed(client_socket);
635 } 669 }
636 670
637 if (client_socket->IsClosed()) { 671 if (client_socket->IsClosed()) {
638 delete client_socket; 672 delete client_socket;
639 } 673 }
640 } 674 }
641 675
642 676
643 void EventHandlerImplementation::HandleWrite(ClientSocket* client_socket, 677 void EventHandlerImplementation::HandleWrite(ClientSocket* client_socket,
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 _beginthreadex(NULL, 32 * 1024, EventHandlerThread, this, 0, &tid); 826 _beginthreadex(NULL, 32 * 1024, EventHandlerThread, this, 0, &tid);
793 if (thread_handle == -1) { 827 if (thread_handle == -1) {
794 FATAL("Failed to start event handler thread"); 828 FATAL("Failed to start event handler thread");
795 } 829 }
796 830
797 // Initialize Winsock32 831 // Initialize Winsock32
798 if (!Socket::Initialize()) { 832 if (!Socket::Initialize()) {
799 FATAL("Failed to initialized Windows sockets"); 833 FATAL("Failed to initialized Windows sockets");
800 } 834 }
801 } 835 }
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_win.h ('k') | runtime/bin/input_stream.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698