OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |