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

Side by Side Diff: webrtc/base/physicalsocketserver.cc

Issue 1537273002: Remove duplicate code in SocketDispatcher (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698