diff options
author | Jeff Brown | 2010-09-21 17:11:18 -0500 |
---|---|---|
committer | Alex Ray | 2013-07-30 15:56:54 -0500 |
commit | d18051870e8e2a5f55237a2c11fde75f46082639 (patch) | |
tree | a3d25c52dd42dc7ae773fc0c8ed2c5ce2795bdac /libs/utils/Looper.cpp | |
parent | 9da1810050d8825e51dabdd0262173432d49c16c (diff) | |
download | platform-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.cpp | 29 |
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 | ||
25 | namespace android { | 25 | namespace android { |
26 | 26 | ||
27 | static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; | ||
28 | static bool gHaveTLS = false; | ||
29 | static 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. |
32 | static const int EPOLL_SIZE_HINT = 8; | 28 | static 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. |
35 | static const int EPOLL_MAX_EVENTS = 16; | 31 | static const int EPOLL_MAX_EVENTS = 16; |
36 | 32 | ||
33 | static pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT; | ||
34 | static pthread_key_t gTLSKey = 0; | ||
35 | |||
37 | Looper::Looper(bool allowNonCallbacks) : | 36 | Looper::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 | ||
72 | void Looper::initTLSKey() { | ||
73 | int result = pthread_key_create(& gTLSKey, threadDestructor); | ||
74 | LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key."); | ||
75 | } | ||
76 | |||
72 | void Looper::threadDestructor(void *st) { | 77 | void 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 | ||
93 | sp<Looper> Looper::getForThread() { | 98 | sp<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 | ||
107 | sp<Looper> Looper::prepare(int opts) { | 105 | sp<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 | ||