From 4520246d3534c087f3e9253c34f99dd1e45b7bd7 Mon Sep 17 00:00:00 2001 From: Xianzhu Wang Date: Thu, 29 Sep 2011 12:59:55 +0800 Subject: 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 --- libsysutils/src/SocketClient.cpp | 10 +++++++++- libsysutils/src/SocketListener.cpp | 12 ++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'libsysutils/src') diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp index 90ca52e7..722dcb29 100644 --- a/libsysutils/src/SocketClient.cpp +++ b/libsysutils/src/SocketClient.cpp @@ -10,8 +10,9 @@ #include -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 fcad624b..3f871ea8 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(); } } } -- cgit v1.2.3