diff --git a/ipc/unixsocket/UnixSocket.cpp b/ipc/unixsocket/UnixSocket.cpp index 2593b3f86bcb..9ecd7f79fe69 100644 --- a/ipc/unixsocket/UnixSocket.cpp +++ b/ipc/unixsocket/UnixSocket.cpp @@ -174,6 +174,9 @@ public: RefPtr mConsumer; private: + + void FireSocketError(); + /** * libevent triggered functions that reads data from socket when available and * guarenteed non-blocking. Only to be called on IO thread. @@ -487,29 +490,47 @@ void ShutdownSocketTask::Run() } void -UnixSocketImpl::Accept() +UnixSocketImpl::FireSocketError() { MOZ_ASSERT(!NS_IsMainThread()); - if (!mConnector) { - NS_WARNING("No connector object available!"); - return; - } + // Clean up watchers, statuses, fds + mReadWatcher.StopWatchingFileDescriptor(); + mWriteWatcher.StopWatchingFileDescriptor(); + mConnectionStatus = SOCKET_DISCONNECTED; + mFd.reset(-1); + + // Tell the main thread we've errored + nsRefPtr t = + new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); + NS_DispatchToMainThread(t); +} + +void +UnixSocketImpl::Accept() +{ + MOZ_ASSERT(!NS_IsMainThread()); + MOZ_ASSERT(mConnector); // This will set things we don't particularly care about, but it will hand // back the correct structure size which is what we do care about. if (!mConnector->CreateAddr(true, mAddrSize, mAddr, nullptr)) { NS_WARNING("Cannot create socket address!"); + FireSocketError(); return; } if (mFd.get() < 0) { mFd = mConnector->Create(); if (mFd.get() < 0) { + NS_WARNING("Cannot create socket fd!"); + FireSocketError(); return; } if (!SetSocketFlags()) { + NS_WARNING("Cannot set socket flags!"); + FireSocketError(); return; } @@ -517,6 +538,7 @@ UnixSocketImpl::Accept() #ifdef DEBUG CHROMIUM_LOG("...bind(%d) gave errno %d", mFd.get(), errno); #endif + FireSocketError(); return; } @@ -524,15 +546,13 @@ UnixSocketImpl::Accept() #ifdef DEBUG CHROMIUM_LOG("...listen(%d) gave errno %d", mFd.get(), errno); #endif + FireSocketError(); return; } if (!mConnector->SetUpListenSocket(mFd)) { NS_WARNING("Could not set up listen socket!"); - nsRefPtr t = - new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); - NS_DispatchToMainThread(t); - mConnectionStatus = SOCKET_DISCONNECTED; + FireSocketError(); return; } @@ -545,15 +565,13 @@ void UnixSocketImpl::Connect() { MOZ_ASSERT(!NS_IsMainThread()); - - if (!mConnector) { - NS_WARNING("No connector object available!"); - return; - } + MOZ_ASSERT(mConnector); if (mFd.get() < 0) { mFd = mConnector->Create(); if (mFd.get() < 0) { + NS_WARNING("Cannot create socket fd!"); + FireSocketError(); return; } } @@ -562,15 +580,14 @@ UnixSocketImpl::Connect() if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) { NS_WARNING("Cannot create socket address!"); + FireSocketError(); return; } // Select non-blocking IO. if (-1 == fcntl(mFd.get(), F_SETFL, O_NONBLOCK)) { - nsRefPtr t = - new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); - NS_DispatchToMainThread(t); - mConnectionStatus = SOCKET_DISCONNECTED; + NS_WARNING("Cannot set nonblock!"); + FireSocketError(); return; } @@ -583,20 +600,12 @@ UnixSocketImpl::Connect() int current_opts = fcntl(mFd.get(), F_GETFL, 0); if (-1 == current_opts) { NS_WARNING("Cannot get socket opts!"); - mFd.reset(-1); - nsRefPtr t = - new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); - NS_DispatchToMainThread(t); - mConnectionStatus = SOCKET_DISCONNECTED; + FireSocketError(); return; } if (-1 == fcntl(mFd.get(), F_SETFL, current_opts & ~O_NONBLOCK)) { NS_WARNING("Cannot set socket opts to blocking!"); - mFd.reset(-1); - nsRefPtr t = - new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); - NS_DispatchToMainThread(t); - mConnectionStatus = SOCKET_DISCONNECTED; + FireSocketError(); return; } @@ -616,20 +625,19 @@ UnixSocketImpl::Connect() #if DEBUG CHROMIUM_LOG("Socket connect errno=%d\n", errno); #endif - mFd.reset(-1); - nsRefPtr t = - new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); - NS_DispatchToMainThread(t); - mConnectionStatus = SOCKET_DISCONNECTED; + FireSocketError(); return; } if (!SetSocketFlags()) { + NS_WARNING("Cannot set socket flags!"); + FireSocketError(); return; } if (!mConnector->SetUp(mFd)) { NS_WARNING("Could not set up socket!"); + FireSocketError(); return; } @@ -862,30 +870,19 @@ UnixSocketImpl::OnFileCanWriteWithoutBlocking(int aFd) if (ret || error) { NS_WARNING("getsockopt failure on async socket connect!"); - mFd.reset(-1); - nsRefPtr t = - new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); - NS_DispatchToMainThread(t); - mConnectionStatus = SOCKET_DISCONNECTED; + FireSocketError(); return; } if (!SetSocketFlags()) { - mFd.reset(-1); - nsRefPtr t = - new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); - NS_DispatchToMainThread(t); - mConnectionStatus = SOCKET_DISCONNECTED; + NS_WARNING("Cannot set socket flags!"); + FireSocketError(); return; } if (!mConnector->SetUp(mFd)) { NS_WARNING("Could not set up socket!"); - mFd.reset(-1); - nsRefPtr t = - new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); - NS_DispatchToMainThread(t); - mConnectionStatus = SOCKET_DISCONNECTED; + FireSocketError(); return; }