diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-14 20:21:02 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-14 20:21:02 +0000 |
commit | c69bbf973d97ab15cbe810c2ee7148db459d39c5 (patch) | |
tree | defd9443f451446ef006a7a9371b8a3cedcd134b /third_party/libjingle | |
parent | 0d8446f1516e7cbcfcb3654c185a13602f9d82c4 (diff) | |
download | chromium_src-c69bbf973d97ab15cbe810c2ee7148db459d39c5.zip chromium_src-c69bbf973d97ab15cbe810c2ee7148db459d39c5.tar.gz chromium_src-c69bbf973d97ab15cbe810c2ee7148db459d39c5.tar.bz2 |
Check for closed read sockets and handle them properly.
BUG=40724
TEST=manual
Review URL: http://codereview.chromium.org/1549042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44529 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/libjingle')
-rw-r--r-- | third_party/libjingle/files/talk/base/physicalsocketserver.cc | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/third_party/libjingle/files/talk/base/physicalsocketserver.cc b/third_party/libjingle/files/talk/base/physicalsocketserver.cc index b05b44c..fe7da7a 100644 --- a/third_party/libjingle/files/talk/base/physicalsocketserver.cc +++ b/third_party/libjingle/files/talk/base/physicalsocketserver.cc @@ -253,6 +253,10 @@ public: // Note: on graceful shutdown, recv can return 0. In this case, we // pretend it is blocking, and then signal close, so that simplifying // assumptions can be made about Recv. + LOG(LS_WARNING) << "EOF from socket; deferring close event"; + // Must turn this back on so that the select() loop will notice the close + // event. + enabled_events_ |= kfRead; error_ = EWOULDBLOCK; return SOCKET_ERROR; } @@ -390,6 +394,7 @@ public: virtual void OnPreEvent(uint32 ff) = 0; virtual void OnEvent(uint32 ff, int err) = 0; virtual int GetDescriptor() = 0; + virtual bool IsDescriptorClosed() = 0; }; class EventDispatcher : public Dispatcher { @@ -440,6 +445,10 @@ public: return afd_[0]; } + virtual bool IsDescriptorClosed() { + return false; + } + private: PhysicalSocketServer *ss_; int afd_[2]; @@ -478,6 +487,14 @@ public: return s_; } + virtual bool 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; + return (0 == ::recv(s_, &ch, 1, MSG_PEEK)); + } + virtual uint32 GetRequestedEvents() { return enabled_events_; } @@ -534,6 +551,10 @@ public: return fd_; } + virtual bool IsDescriptorClosed() { + return false; + } + virtual uint32 GetRequestedEvents() { return flags_; } @@ -903,7 +924,11 @@ bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { uint32 ff = 0; if (FD_ISSET(fd, &fdsRead)) { FD_CLR(fd, &fdsRead); - ff |= kfRead; + if (pdispatcher->IsDescriptorClosed()) { + ff |= kfClose; + } else { + ff |= kfRead; + } } if (FD_ISSET(fd, &fdsWrite)) { FD_CLR(fd, &fdsWrite); |