Fix issue #18356768: some app process may hang at Runtime#exit...

...in Parcel destructor

Don't use a Mutux object, just use simple posix mutex primitives,
to avoid static init/destroy order problems.

Change-Id: Ic012d94297564c0a55d58869f8276d7d10545fbc
This commit is contained in:
Dianne Hackborn 2014-11-13 17:07:40 -08:00
parent ca69e8f2d0
commit a4cff88d80
3 changed files with 22 additions and 25 deletions

View File

@ -34,11 +34,6 @@ extern Vector<int32_t> gTextBuffers;
extern Mutex gProcessMutex; extern Mutex gProcessMutex;
extern sp<ProcessState> gProcess; extern sp<ProcessState> gProcess;
// For Parcel.cpp
extern Mutex gParcelGlobalAllocSizeLock;
extern size_t gParcelGlobalAllocSize;
extern size_t gParcelGlobalAllocCount;
// For IServiceManager.cpp // For IServiceManager.cpp
extern Mutex gDefaultServiceManagerLock; extern Mutex gDefaultServiceManagerLock;
extern sp<IServiceManager> gDefaultServiceManager; extern sp<IServiceManager> gDefaultServiceManager;

View File

@ -75,6 +75,10 @@ struct small_flat_data
namespace android { namespace android {
static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
static size_t gParcelGlobalAllocSize = 0;
static size_t gParcelGlobalAllocCount = 0;
void acquire_object(const sp<ProcessState>& proc, void acquire_object(const sp<ProcessState>& proc,
const flat_binder_object& obj, const void* who) const flat_binder_object& obj, const void* who)
{ {
@ -305,13 +309,17 @@ Parcel::~Parcel()
} }
size_t Parcel::getGlobalAllocSize() { size_t Parcel::getGlobalAllocSize() {
AutoMutex _l(gParcelGlobalAllocSizeLock); pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
return gParcelGlobalAllocSize; size_t size = gParcelGlobalAllocSize;
pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
return size;
} }
size_t Parcel::getGlobalAllocCount() { size_t Parcel::getGlobalAllocCount() {
AutoMutex _l(gParcelGlobalAllocSizeLock); pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
return gParcelGlobalAllocCount; size_t count = gParcelGlobalAllocCount;
pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
return count;
} }
const uint8_t* Parcel::data() const const uint8_t* Parcel::data() const
@ -1511,10 +1519,10 @@ void Parcel::freeDataNoInit()
releaseObjects(); releaseObjects();
if (mData) { if (mData) {
LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity); LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
gParcelGlobalAllocSizeLock.lock(); pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
gParcelGlobalAllocSize -= mDataCapacity; gParcelGlobalAllocSize -= mDataCapacity;
gParcelGlobalAllocCount--; gParcelGlobalAllocCount--;
gParcelGlobalAllocSizeLock.unlock(); pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
free(mData); free(mData);
} }
if (mObjects) free(mObjects); if (mObjects) free(mObjects);
@ -1546,10 +1554,10 @@ status_t Parcel::restartWrite(size_t desired)
if (data) { if (data) {
LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired); LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
gParcelGlobalAllocSizeLock.lock(); pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
gParcelGlobalAllocSize += desired; gParcelGlobalAllocSize += desired;
gParcelGlobalAllocSize -= mDataCapacity; gParcelGlobalAllocSize -= mDataCapacity;
gParcelGlobalAllocSizeLock.unlock(); pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
mData = data; mData = data;
mDataCapacity = desired; mDataCapacity = desired;
} }
@ -1630,10 +1638,10 @@ status_t Parcel::continueWrite(size_t desired)
mOwner = NULL; mOwner = NULL;
LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired); LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
gParcelGlobalAllocSizeLock.lock(); pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
gParcelGlobalAllocSize += desired; gParcelGlobalAllocSize += desired;
gParcelGlobalAllocCount++; gParcelGlobalAllocCount++;
gParcelGlobalAllocSizeLock.unlock(); pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
mData = data; mData = data;
mObjects = objects; mObjects = objects;
@ -1671,10 +1679,10 @@ status_t Parcel::continueWrite(size_t desired)
if (data) { if (data) {
LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity, LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
desired); desired);
gParcelGlobalAllocSizeLock.lock(); pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
gParcelGlobalAllocSize += desired; gParcelGlobalAllocSize += desired;
gParcelGlobalAllocSize -= mDataCapacity; gParcelGlobalAllocSize -= mDataCapacity;
gParcelGlobalAllocSizeLock.unlock(); pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
mData = data; mData = data;
mDataCapacity = desired; mDataCapacity = desired;
} else if (desired > mDataCapacity) { } else if (desired > mDataCapacity) {
@ -1706,10 +1714,10 @@ status_t Parcel::continueWrite(size_t desired)
} }
LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired); LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
gParcelGlobalAllocSizeLock.lock(); pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
gParcelGlobalAllocSize += desired; gParcelGlobalAllocSize += desired;
gParcelGlobalAllocCount++; gParcelGlobalAllocCount++;
gParcelGlobalAllocSizeLock.unlock(); pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
mData = data; mData = data;
mDataSize = mDataPos = 0; mDataSize = mDataPos = 0;

View File

@ -90,12 +90,6 @@ public:
static LibBinderIPCtStatics gIPCStatics; static LibBinderIPCtStatics gIPCStatics;
// ------------ Parcel.cpp
Mutex gParcelGlobalAllocSizeLock;
size_t gParcelGlobalAllocSize = 0;
size_t gParcelGlobalAllocCount = 0;
// ------------ IServiceManager.cpp // ------------ IServiceManager.cpp
Mutex gDefaultServiceManagerLock; Mutex gDefaultServiceManagerLock;