system/core
Révision | c00328f99aad5f1e8e879557f142981f08146fe3 (tree) |
---|---|
l'heure | 2016-08-30 12:59:49 |
Auteur | Scott Mertz <scott@cyng...> |
Commiter | Scott Mertz |
libutils: fix deadlock in elapsedRealtimeNano
If n > 2 threads all lock the mutex awaiting the clock method to
be set, the 1st thread will first set the method and unlock. The
2nd thread will then take the mutex, but never unlock because the
clock_method has already been updated by the 1st thread. This causes
a deadlock for threads 3-n.
Solution is to ensure the calling thread always unlocks the mutex if
it has previously locked it.
Log:
"main" prio=5 tid=1 Native
"Thread-6372" prio=5 tid=9 Native
HAM-1470
Change-Id: I41874d2b0ea034a35a74da030398231089c15cde
@@ -121,9 +121,11 @@ int64_t elapsedRealtimeNano() | ||
121 | 121 | #endif |
122 | 122 | |
123 | 123 | static int s_fd = -1; |
124 | + bool need_unlock = false; | |
124 | 125 | |
125 | 126 | if (clock_method < 0) { |
126 | 127 | pthread_mutex_lock(&clock_lock); |
128 | + need_unlock = true; | |
127 | 129 | } |
128 | 130 | |
129 | 131 | if (clock_method < 0 || clock_method == METHOD_IOCTL) { |
@@ -143,6 +145,8 @@ int64_t elapsedRealtimeNano() | ||
143 | 145 | checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL); |
144 | 146 | if (clock_method < 0) { |
145 | 147 | clock_method = METHOD_IOCTL; |
148 | + } | |
149 | + if (need_unlock) { | |
146 | 150 | pthread_mutex_unlock(&clock_lock); |
147 | 151 | } |
148 | 152 | return timestamp; |
@@ -159,6 +163,8 @@ int64_t elapsedRealtimeNano() | ||
159 | 163 | METHOD_CLOCK_GETTIME); |
160 | 164 | if (clock_method < 0) { |
161 | 165 | clock_method = METHOD_CLOCK_GETTIME; |
166 | + } | |
167 | + if (need_unlock) { | |
162 | 168 | pthread_mutex_unlock(&clock_lock); |
163 | 169 | } |
164 | 170 | return timestamp; |
@@ -173,6 +179,8 @@ int64_t elapsedRealtimeNano() | ||
173 | 179 | METHOD_SYSTEMTIME); |
174 | 180 | if (clock_method < 0) { |
175 | 181 | clock_method = METHOD_SYSTEMTIME; |
182 | + } | |
183 | + if (need_unlock) { | |
176 | 184 | pthread_mutex_unlock(&clock_lock); |
177 | 185 | } |
178 | 186 | return timestamp; |