diff options
author | Xianzhu Wang <wangxianzhu@google.com> | 2011-09-29 12:59:55 +0800 |
---|---|---|
committer | Xianzhu Wang <wangxianzhu@google.com> | 2011-09-29 13:42:32 +0800 |
commit | 4520246d3534c087f3e9253c34f99dd1e45b7bd7 (patch) | |
tree | 68fb2d909e6258f785347d60a026b42efeaa93b4 /libsysutils | |
parent | 2a32df25b8bb307693173911041458aaca84c84c (diff) | |
download | core-4520246d3534c087f3e9253c34f99dd1e45b7bd7.tar.gz core-4520246d3534c087f3e9253c34f99dd1e45b7bd7.tar.bz2 core-4520246d3534c087f3e9253c34f99dd1e45b7bd7.zip |
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
Diffstat (limited to 'libsysutils')
-rw-r--r-- | libsysutils/src/SocketClient.cpp | 10 | ||||
-rw-r--r-- | libsysutils/src/SocketListener.cpp | 12 |
2 files changed, 13 insertions, 9 deletions
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp index 90ca52e74..722dcb291 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 fcad624b1..3f871ea88 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(); } } } |