Fix potential race introduced in Icd7f5f03
Digit wrote: "You probably don't want to close the socket here without updating c->socket as well. Otherwise, another thread holding a handle to the client after the c->decRef() could end up sending a message to a different socket, if the file descriptor index is reused by another client in the meantime." Change-Id: Icdefb5ffc0c7607325d7db761e1f04e5d868bfb7
This commit is contained in:
parent
13aa8ad445
commit
3549b0dc28
|
@ -44,7 +44,7 @@ public:
|
|||
// SocketListener creates a SocketClient (at refcount 1) and calls
|
||||
// decRef() when it's done with the client.
|
||||
void incRef();
|
||||
void decRef();
|
||||
bool decRef(); // returns true at 0 (but note: SocketClient already deleted)
|
||||
};
|
||||
|
||||
typedef android::List<SocketClient *> SocketClientCollection;
|
||||
|
|
|
@ -104,20 +104,23 @@ int SocketClient::sendData(const void* data, int len) {
|
|||
}
|
||||
|
||||
void SocketClient::incRef() {
|
||||
pthread_mutex_lock(&mRefCountMutex);
|
||||
mRefCount++;
|
||||
pthread_mutex_unlock(&mRefCountMutex);
|
||||
pthread_mutex_lock(&mRefCountMutex);
|
||||
mRefCount++;
|
||||
pthread_mutex_unlock(&mRefCountMutex);
|
||||
}
|
||||
|
||||
void SocketClient::decRef() {
|
||||
bool deleteSelf = false;
|
||||
pthread_mutex_lock(&mRefCountMutex);
|
||||
mRefCount--;
|
||||
if (mRefCount == 0) {
|
||||
deleteSelf = true;
|
||||
}
|
||||
pthread_mutex_unlock(&mRefCountMutex);
|
||||
if (deleteSelf) {
|
||||
delete this;
|
||||
}
|
||||
bool SocketClient::decRef() {
|
||||
bool deleteSelf = false;
|
||||
pthread_mutex_lock(&mRefCountMutex);
|
||||
mRefCount--;
|
||||
if (mRefCount == 0) {
|
||||
deleteSelf = true;
|
||||
} else if (mRefCount < 0) {
|
||||
SLOGE("SocketClient refcount went negative!");
|
||||
}
|
||||
pthread_mutex_unlock(&mRefCountMutex);
|
||||
if (deleteSelf) {
|
||||
delete this;
|
||||
}
|
||||
return deleteSelf;
|
||||
}
|
||||
|
|
|
@ -225,8 +225,11 @@ void SocketListener::runListener() {
|
|||
}
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
/* Destroy the client */
|
||||
close(c->getSocket());
|
||||
c->decRef();
|
||||
int socket = c->getSocket();
|
||||
if (c->decRef()) {
|
||||
// Note: 'c' is deleted memory at this point.
|
||||
close(socket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue