Loading libs/binder/IPCThreadState.cpp +15 −13 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <private/binder/binder_module.h> #include <private/binder/binder_module.h> #include <private/binder/Static.h> #include <private/binder/Static.h> #include <atomic> #include <errno.h> #include <errno.h> #include <inttypes.h> #include <inttypes.h> #include <pthread.h> #include <pthread.h> Loading Loading @@ -278,14 +279,14 @@ static const void* printCommand(TextOutput& out, const void* _cmd) } } static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; static bool gHaveTLS = false; static std::atomic<bool> gHaveTLS(false); static pthread_key_t gTLS = 0; static pthread_key_t gTLS = 0; static bool gShutdown = false; static std::atomic<bool> gShutdown = false; static bool gDisableBackgroundScheduling = false; static std::atomic<bool> gDisableBackgroundScheduling = false; IPCThreadState* IPCThreadState::self() IPCThreadState* IPCThreadState::self() { { if (gHaveTLS) { if (gHaveTLS.load(std::memory_order_acquire)) { restart: restart: const pthread_key_t k = gTLS; const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); Loading @@ -293,13 +294,14 @@ restart: return new IPCThreadState; return new IPCThreadState; } } if (gShutdown) { // Racey, heuristic test for simultaneous shutdown. if (gShutdown.load(std::memory_order_relaxed)) { ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n"); ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n"); return nullptr; return nullptr; } } pthread_mutex_lock(&gTLSMutex); pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { if (!gHaveTLS.load(std::memory_order_relaxed)) { int key_create_value = pthread_key_create(&gTLS, threadDestructor); int key_create_value = pthread_key_create(&gTLS, threadDestructor); if (key_create_value != 0) { if (key_create_value != 0) { pthread_mutex_unlock(&gTLSMutex); pthread_mutex_unlock(&gTLSMutex); Loading @@ -307,7 +309,7 @@ restart: strerror(key_create_value)); strerror(key_create_value)); return nullptr; return nullptr; } } gHaveTLS = true; gHaveTLS.store(true, std::memory_order_release); } } pthread_mutex_unlock(&gTLSMutex); pthread_mutex_unlock(&gTLSMutex); goto restart; goto restart; Loading @@ -315,7 +317,7 @@ restart: IPCThreadState* IPCThreadState::selfOrNull() IPCThreadState* IPCThreadState::selfOrNull() { { if (gHaveTLS) { if (gHaveTLS.load(std::memory_order_acquire)) { const pthread_key_t k = gTLS; const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); return st; return st; Loading @@ -325,9 +327,9 @@ IPCThreadState* IPCThreadState::selfOrNull() void IPCThreadState::shutdown() void IPCThreadState::shutdown() { { gShutdown = true; gShutdown.store(true, std::memory_order_relaxed); if (gHaveTLS) { if (gHaveTLS.load(std::memory_order_acquire)) { // XXX Need to wait for all thread pool threads to exit! // XXX Need to wait for all thread pool threads to exit! IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS); IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS); if (st) { if (st) { Loading @@ -335,18 +337,18 @@ void IPCThreadState::shutdown() pthread_setspecific(gTLS, nullptr); pthread_setspecific(gTLS, nullptr); } } pthread_key_delete(gTLS); pthread_key_delete(gTLS); gHaveTLS = false; gHaveTLS.store(false, std::memory_order_release); } } } } void IPCThreadState::disableBackgroundScheduling(bool disable) void IPCThreadState::disableBackgroundScheduling(bool disable) { { gDisableBackgroundScheduling = disable; gDisableBackgroundScheduling.store(disable, std::memory_order_relaxed); } } bool IPCThreadState::backgroundSchedulingDisabled() bool IPCThreadState::backgroundSchedulingDisabled() { { return gDisableBackgroundScheduling; return gDisableBackgroundScheduling.load(std::memory_order_relaxed); } } sp<ProcessState> IPCThreadState::process() sp<ProcessState> IPCThreadState::process() Loading libs/binder/include/binder/ProcessState.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -124,6 +124,8 @@ private: int64_t mStarvationStartTimeMs; int64_t mStarvationStartTimeMs; mutable Mutex mLock; // protects everything below. mutable Mutex mLock; // protects everything below. // TODO: mManagesContexts is often accessed without the lock. // Explain why that's safe. Vector<handle_entry>mHandleToObject; Vector<handle_entry>mHandleToObject; Loading Loading
libs/binder/IPCThreadState.cpp +15 −13 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <private/binder/binder_module.h> #include <private/binder/binder_module.h> #include <private/binder/Static.h> #include <private/binder/Static.h> #include <atomic> #include <errno.h> #include <errno.h> #include <inttypes.h> #include <inttypes.h> #include <pthread.h> #include <pthread.h> Loading Loading @@ -278,14 +279,14 @@ static const void* printCommand(TextOutput& out, const void* _cmd) } } static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; static bool gHaveTLS = false; static std::atomic<bool> gHaveTLS(false); static pthread_key_t gTLS = 0; static pthread_key_t gTLS = 0; static bool gShutdown = false; static std::atomic<bool> gShutdown = false; static bool gDisableBackgroundScheduling = false; static std::atomic<bool> gDisableBackgroundScheduling = false; IPCThreadState* IPCThreadState::self() IPCThreadState* IPCThreadState::self() { { if (gHaveTLS) { if (gHaveTLS.load(std::memory_order_acquire)) { restart: restart: const pthread_key_t k = gTLS; const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); Loading @@ -293,13 +294,14 @@ restart: return new IPCThreadState; return new IPCThreadState; } } if (gShutdown) { // Racey, heuristic test for simultaneous shutdown. if (gShutdown.load(std::memory_order_relaxed)) { ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n"); ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n"); return nullptr; return nullptr; } } pthread_mutex_lock(&gTLSMutex); pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { if (!gHaveTLS.load(std::memory_order_relaxed)) { int key_create_value = pthread_key_create(&gTLS, threadDestructor); int key_create_value = pthread_key_create(&gTLS, threadDestructor); if (key_create_value != 0) { if (key_create_value != 0) { pthread_mutex_unlock(&gTLSMutex); pthread_mutex_unlock(&gTLSMutex); Loading @@ -307,7 +309,7 @@ restart: strerror(key_create_value)); strerror(key_create_value)); return nullptr; return nullptr; } } gHaveTLS = true; gHaveTLS.store(true, std::memory_order_release); } } pthread_mutex_unlock(&gTLSMutex); pthread_mutex_unlock(&gTLSMutex); goto restart; goto restart; Loading @@ -315,7 +317,7 @@ restart: IPCThreadState* IPCThreadState::selfOrNull() IPCThreadState* IPCThreadState::selfOrNull() { { if (gHaveTLS) { if (gHaveTLS.load(std::memory_order_acquire)) { const pthread_key_t k = gTLS; const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); return st; return st; Loading @@ -325,9 +327,9 @@ IPCThreadState* IPCThreadState::selfOrNull() void IPCThreadState::shutdown() void IPCThreadState::shutdown() { { gShutdown = true; gShutdown.store(true, std::memory_order_relaxed); if (gHaveTLS) { if (gHaveTLS.load(std::memory_order_acquire)) { // XXX Need to wait for all thread pool threads to exit! // XXX Need to wait for all thread pool threads to exit! IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS); IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS); if (st) { if (st) { Loading @@ -335,18 +337,18 @@ void IPCThreadState::shutdown() pthread_setspecific(gTLS, nullptr); pthread_setspecific(gTLS, nullptr); } } pthread_key_delete(gTLS); pthread_key_delete(gTLS); gHaveTLS = false; gHaveTLS.store(false, std::memory_order_release); } } } } void IPCThreadState::disableBackgroundScheduling(bool disable) void IPCThreadState::disableBackgroundScheduling(bool disable) { { gDisableBackgroundScheduling = disable; gDisableBackgroundScheduling.store(disable, std::memory_order_relaxed); } } bool IPCThreadState::backgroundSchedulingDisabled() bool IPCThreadState::backgroundSchedulingDisabled() { { return gDisableBackgroundScheduling; return gDisableBackgroundScheduling.load(std::memory_order_relaxed); } } sp<ProcessState> IPCThreadState::process() sp<ProcessState> IPCThreadState::process() Loading
libs/binder/include/binder/ProcessState.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -124,6 +124,8 @@ private: int64_t mStarvationStartTimeMs; int64_t mStarvationStartTimeMs; mutable Mutex mLock; // protects everything below. mutable Mutex mLock; // protects everything below. // TODO: mManagesContexts is often accessed without the lock. // Explain why that's safe. Vector<handle_entry>mHandleToObject; Vector<handle_entry>mHandleToObject; Loading