summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown2010-09-21 17:11:18 -0500
committerAlex Ray2013-07-30 15:56:54 -0500
commitd18051870e8e2a5f55237a2c11fde75f46082639 (patch)
treea3d25c52dd42dc7ae773fc0c8ed2c5ce2795bdac /libs/utils/Looper.cpp
parent9da1810050d8825e51dabdd0262173432d49c16c (diff)
downloadplatform-system-core-d18051870e8e2a5f55237a2c11fde75f46082639.tar.gz
platform-system-core-d18051870e8e2a5f55237a2c11fde75f46082639.tar.xz
platform-system-core-d18051870e8e2a5f55237a2c11fde75f46082639.zip
Looper: use pthread_once for TLS key initialization.
Also fix a Valgrind complaint by zeroing out the entire epoll event struct since otherwise the data field union would be partly uninitialized (but not in a harmful way). Change-Id: I2091ce517e87fcad7c9caf90e2c5e4854a7ca465
Diffstat (limited to 'libs/utils/Looper.cpp')
-rw-r--r--libs/utils/Looper.cpp29
1 files changed, 14 insertions, 15 deletions
diff --git a/libs/utils/Looper.cpp b/libs/utils/Looper.cpp
index b46279efc..d2dd6eb48 100644
--- a/libs/utils/Looper.cpp
+++ b/libs/utils/Looper.cpp
@@ -24,16 +24,15 @@
24 24
25namespace android { 25namespace android {
26 26
27static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
28static bool gHaveTLS = false;
29static pthread_key_t gTLS = 0;
30
31// Hint for number of file descriptors to be associated with the epoll instance. 27// Hint for number of file descriptors to be associated with the epoll instance.
32static const int EPOLL_SIZE_HINT = 8; 28static const int EPOLL_SIZE_HINT = 8;
33 29
34// Maximum number of file descriptors for which to retrieve poll events each iteration. 30// Maximum number of file descriptors for which to retrieve poll events each iteration.
35static const int EPOLL_MAX_EVENTS = 16; 31static const int EPOLL_MAX_EVENTS = 16;
36 32
33static pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;
34static pthread_key_t gTLSKey = 0;
35
37Looper::Looper(bool allowNonCallbacks) : 36Looper::Looper(bool allowNonCallbacks) :
38 mAllowNonCallbacks(allowNonCallbacks), 37 mAllowNonCallbacks(allowNonCallbacks),
39 mResponseIndex(0) { 38 mResponseIndex(0) {
@@ -56,6 +55,7 @@ Looper::Looper(bool allowNonCallbacks) :
56 errno); 55 errno);
57 56
58 struct epoll_event eventItem; 57 struct epoll_event eventItem;
58 memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
59 eventItem.events = EPOLLIN; 59 eventItem.events = EPOLLIN;
60 eventItem.data.fd = mWakeReadPipeFd; 60 eventItem.data.fd = mWakeReadPipeFd;
61 result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); 61 result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
@@ -69,6 +69,11 @@ Looper::~Looper() {
69 close(mEpollFd); 69 close(mEpollFd);
70} 70}
71 71
72void Looper::initTLSKey() {
73 int result = pthread_key_create(& gTLSKey, threadDestructor);
74 LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key.");
75}
76
72void Looper::threadDestructor(void *st) { 77void Looper::threadDestructor(void *st) {
73 Looper* const self = static_cast<Looper*>(st); 78 Looper* const self = static_cast<Looper*>(st);
74 if (self != NULL) { 79 if (self != NULL) {
@@ -83,7 +88,7 @@ void Looper::setForThread(const sp<Looper>& looper) {
83 looper->incStrong((void*)threadDestructor); 88 looper->incStrong((void*)threadDestructor);
84 } 89 }
85 90
86 pthread_setspecific(gTLS, looper.get()); 91 pthread_setspecific(gTLSKey, looper.get());
87 92
88 if (old != NULL) { 93 if (old != NULL) {
89 old->decStrong((void*)threadDestructor); 94 old->decStrong((void*)threadDestructor);
@@ -91,17 +96,10 @@ void Looper::setForThread(const sp<Looper>& looper) {
91} 96}
92 97
93sp<Looper> Looper::getForThread() { 98sp<Looper> Looper::getForThread() {
94 if (!gHaveTLS) { 99 int result = pthread_once(& gTLSOnce, initTLSKey);
95 pthread_mutex_lock(&gTLSMutex); 100 LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");
96 if (pthread_key_create(&gTLS, threadDestructor) != 0) {
97 pthread_mutex_unlock(&gTLSMutex);
98 return NULL;
99 }
100 gHaveTLS = true;
101 pthread_mutex_unlock(&gTLSMutex);
102 }
103 101
104 return (Looper*)pthread_getspecific(gTLS); 102 return (Looper*)pthread_getspecific(gTLSKey);
105} 103}
106 104
107sp<Looper> Looper::prepare(int opts) { 105sp<Looper> Looper::prepare(int opts) {
@@ -331,6 +329,7 @@ int Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback,
331 request.data = data; 329 request.data = data;
332 330
333 struct epoll_event eventItem; 331 struct epoll_event eventItem;
332 memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
334 eventItem.events = epollEvents; 333 eventItem.events = epollEvents;
335 eventItem.data.fd = fd; 334 eventItem.data.fd = fd;
336 335