aboutsummaryrefslogtreecommitdiff
path: root/webrtc
diff options
context:
space:
mode:
authorjbauch <jbauch@webrtc.org>2016-01-06 22:20:28 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-07 06:20:31 +0000
commit4331fcd51736b030f30c31a35c732f119b31b6fc (patch)
treeb91da15ee6a72267a8add45cb436c7618bdaf161 /webrtc
parent44cc7950160aee01889a6b5a21a384b20cfb5532 (diff)
downloadwebrtc-4331fcd51736b030f30c31a35c732f119b31b6fc.tar.gz
Remove duplicate code in SocketDispatcher
This CL is a follow-up on https://codereview.webrtc.org/1452903006/ which moved the definition of SocketDispatcher to physicalsocketserver.h. Here the duplicate implementations are merged with only some #ifdef parts. BUG= Review URL: https://codereview.webrtc.org/1537273002 Cr-Commit-Position: refs/heads/master@{#11160}
Diffstat (limited to 'webrtc')
-rw-r--r--webrtc/base/physicalsocketserver.cc446
1 files changed, 214 insertions, 232 deletions
diff --git a/webrtc/base/physicalsocketserver.cc b/webrtc/base/physicalsocketserver.cc
index 524617221c..3e454527ca 100644
--- a/webrtc/base/physicalsocketserver.cc
+++ b/webrtc/base/physicalsocketserver.cc
@@ -546,6 +546,220 @@ int PhysicalSocket::TranslateOption(Option opt, int* slevel, int* sopt) {
return 0;
}
+SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss)
+#if defined(WEBRTC_WIN)
+ : PhysicalSocket(ss), id_(0), signal_close_(false)
+#else
+ : PhysicalSocket(ss)
+#endif
+{
+}
+
+SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss)
+#if defined(WEBRTC_WIN)
+ : PhysicalSocket(ss, s), id_(0), signal_close_(false)
+#else
+ : PhysicalSocket(ss, s)
+#endif
+{
+}
+
+SocketDispatcher::~SocketDispatcher() {
+ Close();
+}
+
+bool SocketDispatcher::Initialize() {
+ ASSERT(s_ != INVALID_SOCKET);
+ // Must be a non-blocking
+#if defined(WEBRTC_WIN)
+ u_long argp = 1;
+ ioctlsocket(s_, FIONBIO, &argp);
+#elif defined(WEBRTC_POSIX)
+ fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK);
+#endif
+ ss_->Add(this);
+ return true;
+}
+
+bool SocketDispatcher::Create(int type) {
+ return Create(AF_INET, type);
+}
+
+bool SocketDispatcher::Create(int family, int type) {
+ // Change the socket to be non-blocking.
+ if (!PhysicalSocket::Create(family, type))
+ return false;
+
+ if (!Initialize())
+ return false;
+
+#if defined(WEBRTC_WIN)
+ do { id_ = ++next_id_; } while (id_ == 0);
+#endif
+ return true;
+}
+
+#if defined(WEBRTC_WIN)
+
+WSAEVENT SocketDispatcher::GetWSAEvent() {
+ return WSA_INVALID_EVENT;
+}
+
+SOCKET SocketDispatcher::GetSocket() {
+ return s_;
+}
+
+bool SocketDispatcher::CheckSignalClose() {
+ if (!signal_close_)
+ return false;
+
+ char ch;
+ if (recv(s_, &ch, 1, MSG_PEEK) > 0)
+ return false;
+
+ state_ = CS_CLOSED;
+ signal_close_ = false;
+ SignalCloseEvent(this, signal_err_);
+ return true;
+}
+
+int SocketDispatcher::next_id_ = 0;
+
+#elif defined(WEBRTC_POSIX)
+
+int SocketDispatcher::GetDescriptor() {
+ return s_;
+}
+
+bool SocketDispatcher::IsDescriptorClosed() {
+ // We don't have a reliable way of distinguishing end-of-stream
+ // from readability. So test on each readable call. Is this
+ // inefficient? Probably.
+ char ch;
+ ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK);
+ if (res > 0) {
+ // Data available, so not closed.
+ return false;
+ } else if (res == 0) {
+ // EOF, so closed.
+ return true;
+ } else { // error
+ switch (errno) {
+ // Returned if we've already closed s_.
+ case EBADF:
+ // Returned during ungraceful peer shutdown.
+ case ECONNRESET:
+ return true;
+ default:
+ // Assume that all other errors are just blocking errors, meaning the
+ // connection is still good but we just can't read from it right now.
+ // This should only happen when connecting (and at most once), because
+ // in all other cases this function is only called if the file
+ // descriptor is already known to be in the readable state. However,
+ // it's not necessary a problem if we spuriously interpret a
+ // "connection lost"-type error as a blocking error, because typically
+ // the next recv() will get EOF, so we'll still eventually notice that
+ // the socket is closed.
+ LOG_ERR(LS_WARNING) << "Assuming benign blocking error";
+ return false;
+ }
+ }
+}
+
+#endif // WEBRTC_POSIX
+
+uint32_t SocketDispatcher::GetRequestedEvents() {
+ return enabled_events_;
+}
+
+void SocketDispatcher::OnPreEvent(uint32_t ff) {
+ if ((ff & DE_CONNECT) != 0)
+ state_ = CS_CONNECTED;
+
+#if defined(WEBRTC_WIN)
+ // We set CS_CLOSED from CheckSignalClose.
+#elif defined(WEBRTC_POSIX)
+ if ((ff & DE_CLOSE) != 0)
+ state_ = CS_CLOSED;
+#endif
+}
+
+#if defined(WEBRTC_WIN)
+
+void SocketDispatcher::OnEvent(uint32_t ff, int err) {
+ int cache_id = id_;
+ // Make sure we deliver connect/accept first. Otherwise, consumers may see
+ // something like a READ followed by a CONNECT, which would be odd.
+ if (((ff & DE_CONNECT) != 0) && (id_ == cache_id)) {
+ if (ff != DE_CONNECT)
+ LOG(LS_VERBOSE) << "Signalled with DE_CONNECT: " << ff;
+ enabled_events_ &= ~DE_CONNECT;
+#if !defined(NDEBUG)
+ dbg_addr_ = "Connected @ ";
+ dbg_addr_.append(GetRemoteAddress().ToString());
+#endif
+ SignalConnectEvent(this);
+ }
+ if (((ff & DE_ACCEPT) != 0) && (id_ == cache_id)) {
+ enabled_events_ &= ~DE_ACCEPT;
+ SignalReadEvent(this);
+ }
+ if ((ff & DE_READ) != 0) {
+ enabled_events_ &= ~DE_READ;
+ SignalReadEvent(this);
+ }
+ if (((ff & DE_WRITE) != 0) && (id_ == cache_id)) {
+ enabled_events_ &= ~DE_WRITE;
+ SignalWriteEvent(this);
+ }
+ if (((ff & DE_CLOSE) != 0) && (id_ == cache_id)) {
+ signal_close_ = true;
+ signal_err_ = err;
+ }
+}
+
+#elif defined(WEBRTC_POSIX)
+
+void SocketDispatcher::OnEvent(uint32_t ff, int err) {
+ // Make sure we deliver connect/accept first. Otherwise, consumers may see
+ // something like a READ followed by a CONNECT, which would be odd.
+ if ((ff & DE_CONNECT) != 0) {
+ enabled_events_ &= ~DE_CONNECT;
+ SignalConnectEvent(this);
+ }
+ if ((ff & DE_ACCEPT) != 0) {
+ enabled_events_ &= ~DE_ACCEPT;
+ SignalReadEvent(this);
+ }
+ if ((ff & DE_READ) != 0) {
+ enabled_events_ &= ~DE_READ;
+ SignalReadEvent(this);
+ }
+ if ((ff & DE_WRITE) != 0) {
+ enabled_events_ &= ~DE_WRITE;
+ SignalWriteEvent(this);
+ }
+ if ((ff & DE_CLOSE) != 0) {
+ // The socket is now dead to us, so stop checking it.
+ enabled_events_ = 0;
+ SignalCloseEvent(this, err);
+ }
+}
+
+#endif // WEBRTC_POSIX
+
+int SocketDispatcher::Close() {
+ if (s_ == INVALID_SOCKET)
+ return 0;
+
+#if defined(WEBRTC_WIN)
+ id_ = 0;
+ signal_close_ = false;
+#endif
+ ss_->Remove(this);
+ return PhysicalSocket::Close();
+}
+
#if defined(WEBRTC_POSIX)
class EventDispatcher : public Dispatcher {
public:
@@ -782,120 +996,6 @@ class PosixSignalDispatcher : public Dispatcher {
PhysicalSocketServer *owner_;
};
-SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss)
- : PhysicalSocket(ss) {
-}
-
-SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss)
- : PhysicalSocket(ss, s) {
-}
-
-SocketDispatcher::~SocketDispatcher() {
- Close();
-}
-
-bool SocketDispatcher::Initialize() {
- ss_->Add(this);
- fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK);
- return true;
-}
-
-bool SocketDispatcher::Create(int type) {
- return Create(AF_INET, type);
-}
-
-bool SocketDispatcher::Create(int family, int type) {
- // Change the socket to be non-blocking.
- if (!PhysicalSocket::Create(family, type))
- return false;
-
- return Initialize();
-}
-
-int SocketDispatcher::GetDescriptor() {
- return s_;
-}
-
-bool SocketDispatcher::IsDescriptorClosed() {
- // We don't have a reliable way of distinguishing end-of-stream
- // from readability. So test on each readable call. Is this
- // inefficient? Probably.
- char ch;
- ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK);
- if (res > 0) {
- // Data available, so not closed.
- return false;
- } else if (res == 0) {
- // EOF, so closed.
- return true;
- } else { // error
- switch (errno) {
- // Returned if we've already closed s_.
- case EBADF:
- // Returned during ungraceful peer shutdown.
- case ECONNRESET:
- return true;
- default:
- // Assume that all other errors are just blocking errors, meaning the
- // connection is still good but we just can't read from it right now.
- // This should only happen when connecting (and at most once), because
- // in all other cases this function is only called if the file
- // descriptor is already known to be in the readable state. However,
- // it's not necessary a problem if we spuriously interpret a
- // "connection lost"-type error as a blocking error, because typically
- // the next recv() will get EOF, so we'll still eventually notice that
- // the socket is closed.
- LOG_ERR(LS_WARNING) << "Assuming benign blocking error";
- return false;
- }
- }
-}
-
-uint32_t SocketDispatcher::GetRequestedEvents() {
- return enabled_events_;
-}
-
-void SocketDispatcher::OnPreEvent(uint32_t ff) {
- if ((ff & DE_CONNECT) != 0)
- state_ = CS_CONNECTED;
- if ((ff & DE_CLOSE) != 0)
- state_ = CS_CLOSED;
-}
-
-void SocketDispatcher::OnEvent(uint32_t ff, int err) {
- // Make sure we deliver connect/accept first. Otherwise, consumers may see
- // something like a READ followed by a CONNECT, which would be odd.
- if ((ff & DE_CONNECT) != 0) {
- enabled_events_ &= ~DE_CONNECT;
- SignalConnectEvent(this);
- }
- if ((ff & DE_ACCEPT) != 0) {
- enabled_events_ &= ~DE_ACCEPT;
- SignalReadEvent(this);
- }
- if ((ff & DE_READ) != 0) {
- enabled_events_ &= ~DE_READ;
- SignalReadEvent(this);
- }
- if ((ff & DE_WRITE) != 0) {
- enabled_events_ &= ~DE_WRITE;
- SignalWriteEvent(this);
- }
- if ((ff & DE_CLOSE) != 0) {
- // The socket is now dead to us, so stop checking it.
- enabled_events_ = 0;
- SignalCloseEvent(this, err);
- }
-}
-
-int SocketDispatcher::Close() {
- if (s_ == INVALID_SOCKET)
- return 0;
-
- ss_->Remove(this);
- return PhysicalSocket::Close();
-}
-
class FileDispatcher: public Dispatcher, public AsyncFile {
public:
FileDispatcher(int fd, PhysicalSocketServer *ss) : ss_(ss), fd_(fd) {
@@ -1009,124 +1109,6 @@ private:
PhysicalSocketServer* ss_;
WSAEVENT hev_;
};
-
-SocketDispatcher::SocketDispatcher(PhysicalSocketServer* ss)
- : PhysicalSocket(ss),
- id_(0),
- signal_close_(false) {
-}
-
-SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer* ss)
- : PhysicalSocket(ss, s),
- id_(0),
- signal_close_(false) {
-}
-
-SocketDispatcher::~SocketDispatcher() {
- Close();
-}
-
-bool SocketDispatcher::Initialize() {
- ASSERT(s_ != INVALID_SOCKET);
- // Must be a non-blocking
- u_long argp = 1;
- ioctlsocket(s_, FIONBIO, &argp);
- ss_->Add(this);
- return true;
-}
-
-bool SocketDispatcher::Create(int type) {
- return Create(AF_INET, type);
-}
-
-bool SocketDispatcher::Create(int family, int type) {
- // Create socket
- if (!PhysicalSocket::Create(family, type))
- return false;
-
- if (!Initialize())
- return false;
-
- do { id_ = ++next_id_; } while (id_ == 0);
- return true;
-}
-
-int SocketDispatcher::Close() {
- if (s_ == INVALID_SOCKET)
- return 0;
-
- id_ = 0;
- signal_close_ = false;
- ss_->Remove(this);
- return PhysicalSocket::Close();
-}
-
-uint32_t SocketDispatcher::GetRequestedEvents() {
- return enabled_events_;
-}
-
-void SocketDispatcher::OnPreEvent(uint32_t ff) {
- if ((ff & DE_CONNECT) != 0)
- state_ = CS_CONNECTED;
- // We set CS_CLOSED from CheckSignalClose.
-}
-
-void SocketDispatcher::OnEvent(uint32_t ff, int err) {
- int cache_id = id_;
- // Make sure we deliver connect/accept first. Otherwise, consumers may see
- // something like a READ followed by a CONNECT, which would be odd.
- if (((ff & DE_CONNECT) != 0) && (id_ == cache_id)) {
- if (ff != DE_CONNECT)
- LOG(LS_VERBOSE) << "Signalled with DE_CONNECT: " << ff;
- enabled_events_ &= ~DE_CONNECT;
-#if !defined(NDEBUG)
- dbg_addr_ = "Connected @ ";
- dbg_addr_.append(GetRemoteAddress().ToString());
-#endif
- SignalConnectEvent(this);
- }
- if (((ff & DE_ACCEPT) != 0) && (id_ == cache_id)) {
- enabled_events_ &= ~DE_ACCEPT;
- SignalReadEvent(this);
- }
- if ((ff & DE_READ) != 0) {
- enabled_events_ &= ~DE_READ;
- SignalReadEvent(this);
- }
- if (((ff & DE_WRITE) != 0) && (id_ == cache_id)) {
- enabled_events_ &= ~DE_WRITE;
- SignalWriteEvent(this);
- }
- if (((ff & DE_CLOSE) != 0) && (id_ == cache_id)) {
- signal_close_ = true;
- signal_err_ = err;
- }
-}
-
-WSAEVENT SocketDispatcher::GetWSAEvent() {
- return WSA_INVALID_EVENT;
-}
-
-SOCKET SocketDispatcher::GetSocket() {
- return s_;
-}
-
-bool SocketDispatcher::CheckSignalClose() {
- if (!signal_close_)
- return false;
-
- char ch;
- if (recv(s_, &ch, 1, MSG_PEEK) > 0)
- return false;
-
- state_ = CS_CLOSED;
- signal_close_ = false;
- SignalCloseEvent(this, signal_err_);
- return true;
-}
-
-int SocketDispatcher::next_id_ = 0;
-
#endif // WEBRTC_WIN
// Sets the value of a boolean value to false when signaled.