OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
539 return -1; | 539 return -1; |
540 case OPT_RTP_SENDTIME_EXTN_ID: | 540 case OPT_RTP_SENDTIME_EXTN_ID: |
541 return -1; // No logging is necessary as this not a OS socket option. | 541 return -1; // No logging is necessary as this not a OS socket option. |
542 default: | 542 default: |
543 ASSERT(false); | 543 ASSERT(false); |
544 return -1; | 544 return -1; |
545 } | 545 } |
546 return 0; | 546 return 0; |
547 } | 547 } |
548 | 548 |
549 SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss) | |
550 #if defined(WEBRTC_WIN) | |
551 : PhysicalSocket(ss), id_(0), signal_close_(false) | |
552 #else | |
553 : PhysicalSocket(ss) | |
554 #endif | |
555 { | |
556 } | |
557 | |
558 SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss) | |
559 #if defined(WEBRTC_WIN) | |
560 : PhysicalSocket(ss, s), id_(0), signal_close_(false) | |
561 #else | |
562 : PhysicalSocket(ss, s) | |
563 #endif | |
564 { | |
565 } | |
566 | |
567 SocketDispatcher::~SocketDispatcher() { | |
568 Close(); | |
569 } | |
570 | |
571 bool SocketDispatcher::Initialize() { | |
572 ASSERT(s_ != INVALID_SOCKET); | |
573 // Must be a non-blocking | |
574 #if defined(WEBRTC_WIN) | |
575 u_long argp = 1; | |
576 ioctlsocket(s_, FIONBIO, &argp); | |
577 #elif defined(WEBRTC_POSIX) | |
578 fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK); | |
579 #endif | |
580 ss_->Add(this); | |
581 return true; | |
582 } | |
583 | |
584 bool SocketDispatcher::Create(int type) { | |
585 return Create(AF_INET, type); | |
586 } | |
587 | |
588 bool SocketDispatcher::Create(int family, int type) { | |
589 // Change the socket to be non-blocking. | |
590 if (!PhysicalSocket::Create(family, type)) | |
591 return false; | |
592 | |
593 if (!Initialize()) | |
594 return false; | |
595 | |
596 #if defined(WEBRTC_WIN) | |
597 do { id_ = ++next_id_; } while (id_ == 0); | |
598 #endif | |
599 return true; | |
600 } | |
601 | |
602 #if defined(WEBRTC_WIN) | |
603 | |
604 WSAEVENT SocketDispatcher::GetWSAEvent() { | |
605 return WSA_INVALID_EVENT; | |
606 } | |
607 | |
608 SOCKET SocketDispatcher::GetSocket() { | |
joachim
2015/12/20 15:27:32
This could probably be further merged with GetDesc
| |
609 return s_; | |
610 } | |
611 | |
612 bool SocketDispatcher::CheckSignalClose() { | |
613 if (!signal_close_) | |
614 return false; | |
615 | |
616 char ch; | |
617 if (recv(s_, &ch, 1, MSG_PEEK) > 0) | |
618 return false; | |
619 | |
620 state_ = CS_CLOSED; | |
621 signal_close_ = false; | |
622 SignalCloseEvent(this, signal_err_); | |
623 return true; | |
624 } | |
625 | |
626 int SocketDispatcher::next_id_ = 0; | |
627 | |
628 #elif defined(WEBRTC_POSIX) | |
629 | |
630 int SocketDispatcher::GetDescriptor() { | |
631 return s_; | |
632 } | |
633 | |
634 bool SocketDispatcher::IsDescriptorClosed() { | |
635 // We don't have a reliable way of distinguishing end-of-stream | |
636 // from readability. So test on each readable call. Is this | |
637 // inefficient? Probably. | |
638 char ch; | |
639 ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK); | |
640 if (res > 0) { | |
641 // Data available, so not closed. | |
642 return false; | |
643 } else if (res == 0) { | |
644 // EOF, so closed. | |
645 return true; | |
646 } else { // error | |
647 switch (errno) { | |
648 // Returned if we've already closed s_. | |
649 case EBADF: | |
650 // Returned during ungraceful peer shutdown. | |
651 case ECONNRESET: | |
652 return true; | |
653 default: | |
654 // Assume that all other errors are just blocking errors, meaning the | |
655 // connection is still good but we just can't read from it right now. | |
656 // This should only happen when connecting (and at most once), because | |
657 // in all other cases this function is only called if the file | |
658 // descriptor is already known to be in the readable state. However, | |
659 // it's not necessary a problem if we spuriously interpret a | |
660 // "connection lost"-type error as a blocking error, because typically | |
661 // the next recv() will get EOF, so we'll still eventually notice that | |
662 // the socket is closed. | |
663 LOG_ERR(LS_WARNING) << "Assuming benign blocking error"; | |
664 return false; | |
665 } | |
666 } | |
667 } | |
668 | |
669 #endif // WEBRTC_POSIX | |
670 | |
671 uint32_t SocketDispatcher::GetRequestedEvents() { | |
672 return enabled_events_; | |
673 } | |
674 | |
675 void SocketDispatcher::OnPreEvent(uint32_t ff) { | |
676 if ((ff & DE_CONNECT) != 0) | |
677 state_ = CS_CONNECTED; | |
678 | |
679 #if defined(WEBRTC_WIN) | |
680 // We set CS_CLOSED from CheckSignalClose. | |
681 #elif defined(WEBRTC_POSIX) | |
682 if ((ff & DE_CLOSE) != 0) | |
683 state_ = CS_CLOSED; | |
684 #endif | |
685 } | |
686 | |
687 #if defined(WEBRTC_WIN) | |
688 | |
689 void SocketDispatcher::OnEvent(uint32_t ff, int err) { | |
690 int cache_id = id_; | |
691 // Make sure we deliver connect/accept first. Otherwise, consumers may see | |
692 // something like a READ followed by a CONNECT, which would be odd. | |
693 if (((ff & DE_CONNECT) != 0) && (id_ == cache_id)) { | |
694 if (ff != DE_CONNECT) | |
695 LOG(LS_VERBOSE) << "Signalled with DE_CONNECT: " << ff; | |
696 enabled_events_ &= ~DE_CONNECT; | |
697 #if !defined(NDEBUG) | |
698 dbg_addr_ = "Connected @ "; | |
699 dbg_addr_.append(GetRemoteAddress().ToString()); | |
700 #endif | |
701 SignalConnectEvent(this); | |
702 } | |
703 if (((ff & DE_ACCEPT) != 0) && (id_ == cache_id)) { | |
704 enabled_events_ &= ~DE_ACCEPT; | |
705 SignalReadEvent(this); | |
706 } | |
707 if ((ff & DE_READ) != 0) { | |
708 enabled_events_ &= ~DE_READ; | |
709 SignalReadEvent(this); | |
710 } | |
711 if (((ff & DE_WRITE) != 0) && (id_ == cache_id)) { | |
712 enabled_events_ &= ~DE_WRITE; | |
713 SignalWriteEvent(this); | |
714 } | |
715 if (((ff & DE_CLOSE) != 0) && (id_ == cache_id)) { | |
716 signal_close_ = true; | |
717 signal_err_ = err; | |
718 } | |
719 } | |
720 | |
721 #elif defined(WEBRTC_POSIX) | |
722 | |
723 void SocketDispatcher::OnEvent(uint32_t ff, int err) { | |
724 // Make sure we deliver connect/accept first. Otherwise, consumers may see | |
725 // something like a READ followed by a CONNECT, which would be odd. | |
726 if ((ff & DE_CONNECT) != 0) { | |
727 enabled_events_ &= ~DE_CONNECT; | |
728 SignalConnectEvent(this); | |
729 } | |
730 if ((ff & DE_ACCEPT) != 0) { | |
731 enabled_events_ &= ~DE_ACCEPT; | |
732 SignalReadEvent(this); | |
733 } | |
734 if ((ff & DE_READ) != 0) { | |
735 enabled_events_ &= ~DE_READ; | |
736 SignalReadEvent(this); | |
737 } | |
738 if ((ff & DE_WRITE) != 0) { | |
739 enabled_events_ &= ~DE_WRITE; | |
740 SignalWriteEvent(this); | |
741 } | |
742 if ((ff & DE_CLOSE) != 0) { | |
743 // The socket is now dead to us, so stop checking it. | |
744 enabled_events_ = 0; | |
745 SignalCloseEvent(this, err); | |
746 } | |
747 } | |
748 | |
749 #endif // WEBRTC_POSIX | |
750 | |
751 int SocketDispatcher::Close() { | |
752 if (s_ == INVALID_SOCKET) | |
753 return 0; | |
754 | |
755 #if defined(WEBRTC_WIN) | |
756 id_ = 0; | |
757 signal_close_ = false; | |
758 #endif | |
759 ss_->Remove(this); | |
760 return PhysicalSocket::Close(); | |
761 } | |
762 | |
549 #if defined(WEBRTC_POSIX) | 763 #if defined(WEBRTC_POSIX) |
550 class EventDispatcher : public Dispatcher { | 764 class EventDispatcher : public Dispatcher { |
551 public: | 765 public: |
552 EventDispatcher(PhysicalSocketServer* ss) : ss_(ss), fSignaled_(false) { | 766 EventDispatcher(PhysicalSocketServer* ss) : ss_(ss), fSignaled_(false) { |
553 if (pipe(afd_) < 0) | 767 if (pipe(afd_) < 0) |
554 LOG(LERROR) << "pipe failed"; | 768 LOG(LERROR) << "pipe failed"; |
555 ss_->Add(this); | 769 ss_->Add(this); |
556 } | 770 } |
557 | 771 |
558 ~EventDispatcher() override { | 772 ~EventDispatcher() override { |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
775 } | 989 } |
776 | 990 |
777 private: | 991 private: |
778 typedef std::map<int, void (*)(int)> HandlerMap; | 992 typedef std::map<int, void (*)(int)> HandlerMap; |
779 | 993 |
780 HandlerMap handlers_; | 994 HandlerMap handlers_; |
781 // Our owner. | 995 // Our owner. |
782 PhysicalSocketServer *owner_; | 996 PhysicalSocketServer *owner_; |
783 }; | 997 }; |
784 | 998 |
785 SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss) | |
786 : PhysicalSocket(ss) { | |
787 } | |
788 | |
789 SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss) | |
790 : PhysicalSocket(ss, s) { | |
791 } | |
792 | |
793 SocketDispatcher::~SocketDispatcher() { | |
794 Close(); | |
795 } | |
796 | |
797 bool SocketDispatcher::Initialize() { | |
798 ss_->Add(this); | |
799 fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK); | |
800 return true; | |
801 } | |
802 | |
803 bool SocketDispatcher::Create(int type) { | |
804 return Create(AF_INET, type); | |
805 } | |
806 | |
807 bool SocketDispatcher::Create(int family, int type) { | |
808 // Change the socket to be non-blocking. | |
809 if (!PhysicalSocket::Create(family, type)) | |
810 return false; | |
811 | |
812 return Initialize(); | |
813 } | |
814 | |
815 int SocketDispatcher::GetDescriptor() { | |
816 return s_; | |
817 } | |
818 | |
819 bool SocketDispatcher::IsDescriptorClosed() { | |
820 // We don't have a reliable way of distinguishing end-of-stream | |
821 // from readability. So test on each readable call. Is this | |
822 // inefficient? Probably. | |
823 char ch; | |
824 ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK); | |
825 if (res > 0) { | |
826 // Data available, so not closed. | |
827 return false; | |
828 } else if (res == 0) { | |
829 // EOF, so closed. | |
830 return true; | |
831 } else { // error | |
832 switch (errno) { | |
833 // Returned if we've already closed s_. | |
834 case EBADF: | |
835 // Returned during ungraceful peer shutdown. | |
836 case ECONNRESET: | |
837 return true; | |
838 default: | |
839 // Assume that all other errors are just blocking errors, meaning the | |
840 // connection is still good but we just can't read from it right now. | |
841 // This should only happen when connecting (and at most once), because | |
842 // in all other cases this function is only called if the file | |
843 // descriptor is already known to be in the readable state. However, | |
844 // it's not necessary a problem if we spuriously interpret a | |
845 // "connection lost"-type error as a blocking error, because typically | |
846 // the next recv() will get EOF, so we'll still eventually notice that | |
847 // the socket is closed. | |
848 LOG_ERR(LS_WARNING) << "Assuming benign blocking error"; | |
849 return false; | |
850 } | |
851 } | |
852 } | |
853 | |
854 uint32_t SocketDispatcher::GetRequestedEvents() { | |
855 return enabled_events_; | |
856 } | |
857 | |
858 void SocketDispatcher::OnPreEvent(uint32_t ff) { | |
859 if ((ff & DE_CONNECT) != 0) | |
860 state_ = CS_CONNECTED; | |
861 if ((ff & DE_CLOSE) != 0) | |
862 state_ = CS_CLOSED; | |
863 } | |
864 | |
865 void SocketDispatcher::OnEvent(uint32_t ff, int err) { | |
866 // Make sure we deliver connect/accept first. Otherwise, consumers may see | |
867 // something like a READ followed by a CONNECT, which would be odd. | |
868 if ((ff & DE_CONNECT) != 0) { | |
869 enabled_events_ &= ~DE_CONNECT; | |
870 SignalConnectEvent(this); | |
871 } | |
872 if ((ff & DE_ACCEPT) != 0) { | |
873 enabled_events_ &= ~DE_ACCEPT; | |
874 SignalReadEvent(this); | |
875 } | |
876 if ((ff & DE_READ) != 0) { | |
877 enabled_events_ &= ~DE_READ; | |
878 SignalReadEvent(this); | |
879 } | |
880 if ((ff & DE_WRITE) != 0) { | |
881 enabled_events_ &= ~DE_WRITE; | |
882 SignalWriteEvent(this); | |
883 } | |
884 if ((ff & DE_CLOSE) != 0) { | |
885 // The socket is now dead to us, so stop checking it. | |
886 enabled_events_ = 0; | |
887 SignalCloseEvent(this, err); | |
888 } | |
889 } | |
890 | |
891 int SocketDispatcher::Close() { | |
892 if (s_ == INVALID_SOCKET) | |
893 return 0; | |
894 | |
895 ss_->Remove(this); | |
896 return PhysicalSocket::Close(); | |
897 } | |
898 | |
899 class FileDispatcher: public Dispatcher, public AsyncFile { | 999 class FileDispatcher: public Dispatcher, public AsyncFile { |
900 public: | 1000 public: |
901 FileDispatcher(int fd, PhysicalSocketServer *ss) : ss_(ss), fd_(fd) { | 1001 FileDispatcher(int fd, PhysicalSocketServer *ss) : ss_(ss), fd_(fd) { |
902 set_readable(true); | 1002 set_readable(true); |
903 | 1003 |
904 ss_->Add(this); | 1004 ss_->Add(this); |
905 | 1005 |
906 fcntl(fd_, F_SETFL, fcntl(fd_, F_GETFL, 0) | O_NONBLOCK); | 1006 fcntl(fd_, F_SETFL, fcntl(fd_, F_GETFL, 0) | O_NONBLOCK); |
907 } | 1007 } |
908 | 1008 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1002 virtual SOCKET GetSocket() { | 1102 virtual SOCKET GetSocket() { |
1003 return INVALID_SOCKET; | 1103 return INVALID_SOCKET; |
1004 } | 1104 } |
1005 | 1105 |
1006 virtual bool CheckSignalClose() { return false; } | 1106 virtual bool CheckSignalClose() { return false; } |
1007 | 1107 |
1008 private: | 1108 private: |
1009 PhysicalSocketServer* ss_; | 1109 PhysicalSocketServer* ss_; |
1010 WSAEVENT hev_; | 1110 WSAEVENT hev_; |
1011 }; | 1111 }; |
1012 | |
1013 SocketDispatcher::SocketDispatcher(PhysicalSocketServer* ss) | |
1014 : PhysicalSocket(ss), | |
1015 id_(0), | |
1016 signal_close_(false) { | |
1017 } | |
1018 | |
1019 SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer* ss) | |
1020 : PhysicalSocket(ss, s), | |
1021 id_(0), | |
1022 signal_close_(false) { | |
1023 } | |
1024 | |
1025 SocketDispatcher::~SocketDispatcher() { | |
1026 Close(); | |
1027 } | |
1028 | |
1029 bool SocketDispatcher::Initialize() { | |
1030 ASSERT(s_ != INVALID_SOCKET); | |
1031 // Must be a non-blocking | |
1032 u_long argp = 1; | |
1033 ioctlsocket(s_, FIONBIO, &argp); | |
1034 ss_->Add(this); | |
1035 return true; | |
1036 } | |
1037 | |
1038 bool SocketDispatcher::Create(int type) { | |
1039 return Create(AF_INET, type); | |
1040 } | |
1041 | |
1042 bool SocketDispatcher::Create(int family, int type) { | |
1043 // Create socket | |
1044 if (!PhysicalSocket::Create(family, type)) | |
1045 return false; | |
1046 | |
1047 if (!Initialize()) | |
1048 return false; | |
1049 | |
1050 do { id_ = ++next_id_; } while (id_ == 0); | |
1051 return true; | |
1052 } | |
1053 | |
1054 int SocketDispatcher::Close() { | |
1055 if (s_ == INVALID_SOCKET) | |
1056 return 0; | |
1057 | |
1058 id_ = 0; | |
1059 signal_close_ = false; | |
1060 ss_->Remove(this); | |
1061 return PhysicalSocket::Close(); | |
1062 } | |
1063 | |
1064 uint32_t SocketDispatcher::GetRequestedEvents() { | |
1065 return enabled_events_; | |
1066 } | |
1067 | |
1068 void SocketDispatcher::OnPreEvent(uint32_t ff) { | |
1069 if ((ff & DE_CONNECT) != 0) | |
1070 state_ = CS_CONNECTED; | |
1071 // We set CS_CLOSED from CheckSignalClose. | |
1072 } | |
1073 | |
1074 void SocketDispatcher::OnEvent(uint32_t ff, int err) { | |
1075 int cache_id = id_; | |
1076 // Make sure we deliver connect/accept first. Otherwise, consumers may see | |
1077 // something like a READ followed by a CONNECT, which would be odd. | |
1078 if (((ff & DE_CONNECT) != 0) && (id_ == cache_id)) { | |
1079 if (ff != DE_CONNECT) | |
1080 LOG(LS_VERBOSE) << "Signalled with DE_CONNECT: " << ff; | |
1081 enabled_events_ &= ~DE_CONNECT; | |
1082 #if !defined(NDEBUG) | |
1083 dbg_addr_ = "Connected @ "; | |
1084 dbg_addr_.append(GetRemoteAddress().ToString()); | |
1085 #endif | |
1086 SignalConnectEvent(this); | |
1087 } | |
1088 if (((ff & DE_ACCEPT) != 0) && (id_ == cache_id)) { | |
1089 enabled_events_ &= ~DE_ACCEPT; | |
1090 SignalReadEvent(this); | |
1091 } | |
1092 if ((ff & DE_READ) != 0) { | |
1093 enabled_events_ &= ~DE_READ; | |
1094 SignalReadEvent(this); | |
1095 } | |
1096 if (((ff & DE_WRITE) != 0) && (id_ == cache_id)) { | |
1097 enabled_events_ &= ~DE_WRITE; | |
1098 SignalWriteEvent(this); | |
1099 } | |
1100 if (((ff & DE_CLOSE) != 0) && (id_ == cache_id)) { | |
1101 signal_close_ = true; | |
1102 signal_err_ = err; | |
1103 } | |
1104 } | |
1105 | |
1106 WSAEVENT SocketDispatcher::GetWSAEvent() { | |
1107 return WSA_INVALID_EVENT; | |
1108 } | |
1109 | |
1110 SOCKET SocketDispatcher::GetSocket() { | |
1111 return s_; | |
1112 } | |
1113 | |
1114 bool SocketDispatcher::CheckSignalClose() { | |
1115 if (!signal_close_) | |
1116 return false; | |
1117 | |
1118 char ch; | |
1119 if (recv(s_, &ch, 1, MSG_PEEK) > 0) | |
1120 return false; | |
1121 | |
1122 state_ = CS_CLOSED; | |
1123 signal_close_ = false; | |
1124 SignalCloseEvent(this, signal_err_); | |
1125 return true; | |
1126 } | |
1127 | |
1128 int SocketDispatcher::next_id_ = 0; | |
1129 | |
1130 #endif // WEBRTC_WIN | 1112 #endif // WEBRTC_WIN |
1131 | 1113 |
1132 // Sets the value of a boolean value to false when signaled. | 1114 // Sets the value of a boolean value to false when signaled. |
1133 class Signaler : public EventDispatcher { | 1115 class Signaler : public EventDispatcher { |
1134 public: | 1116 public: |
1135 Signaler(PhysicalSocketServer* ss, bool* pf) | 1117 Signaler(PhysicalSocketServer* ss, bool* pf) |
1136 : EventDispatcher(ss), pf_(pf) { | 1118 : EventDispatcher(ss), pf_(pf) { |
1137 } | 1119 } |
1138 ~Signaler() override { } | 1120 ~Signaler() override { } |
1139 | 1121 |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1617 break; | 1599 break; |
1618 } | 1600 } |
1619 } | 1601 } |
1620 | 1602 |
1621 // Done | 1603 // Done |
1622 return true; | 1604 return true; |
1623 } | 1605 } |
1624 #endif // WEBRTC_WIN | 1606 #endif // WEBRTC_WIN |
1625 | 1607 |
1626 } // namespace rtc | 1608 } // namespace rtc |
OLD | NEW |