summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXianzhu Wang <wangxianzhu@google.com>2011-09-29 12:59:55 +0800
committerXianzhu Wang <wangxianzhu@google.com>2011-09-29 13:42:32 +0800
commit4520246d3534c087f3e9253c34f99dd1e45b7bd7 (patch)
tree68fb2d909e6258f785347d60a026b42efeaa93b4
parent2a32df25b8bb307693173911041458aaca84c84c (diff)
downloadsystem_core-4520246d3534c087f3e9253c34f99dd1e45b7bd7.zip
system_core-4520246d3534c087f3e9253c34f99dd1e45b7bd7.tar.gz
system_core-4520246d3534c087f3e9253c34f99dd1e45b7bd7.tar.bz2
Fix SocketListener socket leak issue.
The problem was: if a socket is shared between SocketListener and another thread, only if the last reference is removed by SocketListener can the socket be closed, otherwise the socket will leak. This sometimes happens in netd's dnsproxyd. This change let the SocketClient own the socket and close the socket when the SocketClient is destructed. Change-Id: I2865fbfe9ee4d8b3e43d7e02919dbb2d261f70de
-rw-r--r--include/sysutils/SocketClient.h5
-rw-r--r--libsysutils/src/SocketClient.cpp10
-rw-r--r--libsysutils/src/SocketListener.cpp12
3 files changed, 16 insertions, 11 deletions
diff --git a/include/sysutils/SocketClient.h b/include/sysutils/SocketClient.h
index d6bb7d5..7d2b1d6 100644
--- a/include/sysutils/SocketClient.h
+++ b/include/sysutils/SocketClient.h
@@ -8,6 +8,7 @@
class SocketClient {
int mSocket;
+ bool mSocketOwned;
pthread_mutex_t mWriteMutex;
/* Peer process ID */
@@ -24,8 +25,8 @@ class SocketClient {
int mRefCount;
public:
- SocketClient(int sock);
- virtual ~SocketClient() {}
+ SocketClient(int sock, bool owned);
+ virtual ~SocketClient();
int getSocket() { return mSocket; }
pid_t getPid() const { return mPid; }
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
index 90ca52e..722dcb2 100644
--- a/libsysutils/src/SocketClient.cpp
+++ b/libsysutils/src/SocketClient.cpp
@@ -10,8 +10,9 @@
#include <sysutils/SocketClient.h>
-SocketClient::SocketClient(int socket)
+SocketClient::SocketClient(int socket, bool owned)
: mSocket(socket)
+ , mSocketOwned(owned)
, mPid(-1)
, mUid(-1)
, mGid(-1)
@@ -32,6 +33,13 @@ SocketClient::SocketClient(int socket)
}
}
+SocketClient::~SocketClient()
+{
+ if (mSocketOwned) {
+ close(mSocket);
+ }
+}
+
int SocketClient::sendMsg(int code, const char *msg, bool addErrno) {
char *buf;
const char* arg;
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index fcad624..3f871ea 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -79,7 +79,7 @@ int SocketListener::startListener() {
SLOGE("Unable to listen on socket (%s)", strerror(errno));
return -1;
} else if (!mListen)
- mClients->push_back(new SocketClient(mSock));
+ mClients->push_back(new SocketClient(mSock, false));
if (pipe(mCtrlPipe)) {
SLOGE("pipe failed (%s)", strerror(errno));
@@ -191,7 +191,7 @@ void SocketListener::runListener() {
continue;
}
pthread_mutex_lock(&mClientsLock);
- mClients->push_back(new SocketClient(c));
+ mClients->push_back(new SocketClient(c, true));
pthread_mutex_unlock(&mClientsLock);
}
@@ -225,12 +225,8 @@ void SocketListener::runListener() {
}
}
pthread_mutex_unlock(&mClientsLock);
- /* Destroy the client */
- int socket = c->getSocket();
- if (c->decRef()) {
- // Note: 'c' is deleted memory at this point.
- close(socket);
- }
+ /* Remove our reference to the client */
+ c->decRef();
}
}
}