• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // #define LOG_NDEBUG 0
18 #define LOG_TAG "libutils.threads"
19 
20 #include <utils/threads.h>
21 #include <utils/Log.h>
22 
23 #include <cutils/sched_policy.h>
24 #include <cutils/properties.h>
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <memory.h>
29 #include <errno.h>
30 #include <assert.h>
31 #include <unistd.h>
32 
33 #if defined(HAVE_PTHREADS)
34 # include <pthread.h>
35 # include <sched.h>
36 # include <sys/resource.h>
37 #elif defined(HAVE_WIN32_THREADS)
38 # include <windows.h>
39 # include <stdint.h>
40 # include <process.h>
41 # define HAVE_CREATETHREAD  // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW
42 #endif
43 
44 #if defined(HAVE_PRCTL)
45 #include <sys/prctl.h>
46 #endif
47 
48 /*
49  * ===========================================================================
50  *      Thread wrappers
51  * ===========================================================================
52  */
53 
54 using namespace android;
55 
56 // ----------------------------------------------------------------------------
57 #if defined(HAVE_PTHREADS)
58 // ----------------------------------------------------------------------------
59 
60 /*
61  * Create and run a new thread.
62  *
63  * We create it "detached", so it cleans up after itself.
64  */
65 
66 typedef void* (*android_pthread_entry)(void*);
67 
68 static pthread_once_t gDoSchedulingGroupOnce = PTHREAD_ONCE_INIT;
69 static bool gDoSchedulingGroup = true;
70 
checkDoSchedulingGroup(void)71 static void checkDoSchedulingGroup(void) {
72     char buf[PROPERTY_VALUE_MAX];
73     int len = property_get("debug.sys.noschedgroups", buf, "");
74     if (len > 0) {
75         int temp;
76         if (sscanf(buf, "%d", &temp) == 1) {
77             gDoSchedulingGroup = temp == 0;
78         }
79     }
80 }
81 
82 struct thread_data_t {
83     thread_func_t   entryFunction;
84     void*           userData;
85     int             priority;
86     char *          threadName;
87 
88     // we use this trampoline when we need to set the priority with
89     // nice/setpriority.
trampolinethread_data_t90     static int trampoline(const thread_data_t* t) {
91         thread_func_t f = t->entryFunction;
92         void* u = t->userData;
93         int prio = t->priority;
94         char * name = t->threadName;
95         delete t;
96         setpriority(PRIO_PROCESS, 0, prio);
97         pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
98         if (gDoSchedulingGroup) {
99             if (prio >= ANDROID_PRIORITY_BACKGROUND) {
100                 set_sched_policy(androidGetTid(), SP_BACKGROUND);
101             } else {
102                 set_sched_policy(androidGetTid(), SP_FOREGROUND);
103             }
104         }
105 
106         if (name) {
107 #if defined(HAVE_PRCTL)
108             // Mac OS doesn't have this, and we build libutil for the host too
109             int hasAt = 0;
110             int hasDot = 0;
111             char *s = name;
112             while (*s) {
113                 if (*s == '.') hasDot = 1;
114                 else if (*s == '@') hasAt = 1;
115                 s++;
116             }
117             int len = s - name;
118             if (len < 15 || hasAt || !hasDot) {
119                 s = name;
120             } else {
121                 s = name + len - 15;
122             }
123             prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
124 #endif
125             free(name);
126         }
127         return f(u);
128     }
129 };
130 
androidCreateRawThreadEtc(android_thread_func_t entryFunction,void * userData,const char * threadName,int32_t threadPriority,size_t threadStackSize,android_thread_id_t * threadId)131 int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
132                                void *userData,
133                                const char* threadName,
134                                int32_t threadPriority,
135                                size_t threadStackSize,
136                                android_thread_id_t *threadId)
137 {
138     pthread_attr_t attr;
139     pthread_attr_init(&attr);
140     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
141 
142 #ifdef HAVE_ANDROID_OS  /* valgrind is rejecting RT-priority create reqs */
143     if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
144         // We could avoid the trampoline if there was a way to get to the
145         // android_thread_id_t (pid) from pthread_t
146         thread_data_t* t = new thread_data_t;
147         t->priority = threadPriority;
148         t->threadName = threadName ? strdup(threadName) : NULL;
149         t->entryFunction = entryFunction;
150         t->userData = userData;
151         entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
152         userData = t;
153     }
154 #endif
155 
156     if (threadStackSize) {
157         pthread_attr_setstacksize(&attr, threadStackSize);
158     }
159 
160     errno = 0;
161     pthread_t thread;
162     int result = pthread_create(&thread, &attr,
163                     (android_pthread_entry)entryFunction, userData);
164     if (result != 0) {
165         LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
166              "(android threadPriority=%d)",
167             entryFunction, result, errno, threadPriority);
168         return 0;
169     }
170 
171     if (threadId != NULL) {
172         *threadId = (android_thread_id_t)thread; // XXX: this is not portable
173     }
174     return 1;
175 }
176 
androidGetThreadId()177 android_thread_id_t androidGetThreadId()
178 {
179     return (android_thread_id_t)pthread_self();
180 }
181 
182 // ----------------------------------------------------------------------------
183 #elif defined(HAVE_WIN32_THREADS)
184 // ----------------------------------------------------------------------------
185 
186 /*
187  * Trampoline to make us __stdcall-compliant.
188  *
189  * We're expected to delete "vDetails" when we're done.
190  */
191 struct threadDetails {
192     int (*func)(void*);
193     void* arg;
194 };
threadIntermediary(void * vDetails)195 static __stdcall unsigned int threadIntermediary(void* vDetails)
196 {
197     struct threadDetails* pDetails = (struct threadDetails*) vDetails;
198     int result;
199 
200     result = (*(pDetails->func))(pDetails->arg);
201 
202     delete pDetails;
203 
204     LOG(LOG_VERBOSE, "thread", "thread exiting\n");
205     return (unsigned int) result;
206 }
207 
208 /*
209  * Create and run a new thread.
210  */
doCreateThread(android_thread_func_t fn,void * arg,android_thread_id_t * id)211 static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)
212 {
213     HANDLE hThread;
214     struct threadDetails* pDetails = new threadDetails; // must be on heap
215     unsigned int thrdaddr;
216 
217     pDetails->func = fn;
218     pDetails->arg = arg;
219 
220 #if defined(HAVE__BEGINTHREADEX)
221     hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,
222                     &thrdaddr);
223     if (hThread == 0)
224 #elif defined(HAVE_CREATETHREAD)
225     hThread = CreateThread(NULL, 0,
226                     (LPTHREAD_START_ROUTINE) threadIntermediary,
227                     (void*) pDetails, 0, (DWORD*) &thrdaddr);
228     if (hThread == NULL)
229 #endif
230     {
231         LOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
232         return false;
233     }
234 
235 #if defined(HAVE_CREATETHREAD)
236     /* close the management handle */
237     CloseHandle(hThread);
238 #endif
239 
240     if (id != NULL) {
241       	*id = (android_thread_id_t)thrdaddr;
242     }
243 
244     return true;
245 }
246 
androidCreateRawThreadEtc(android_thread_func_t fn,void * userData,const char * threadName,int32_t threadPriority,size_t threadStackSize,android_thread_id_t * threadId)247 int androidCreateRawThreadEtc(android_thread_func_t fn,
248                                void *userData,
249                                const char* threadName,
250                                int32_t threadPriority,
251                                size_t threadStackSize,
252                                android_thread_id_t *threadId)
253 {
254     return doCreateThread(  fn, userData, threadId);
255 }
256 
androidGetThreadId()257 android_thread_id_t androidGetThreadId()
258 {
259     return (android_thread_id_t)GetCurrentThreadId();
260 }
261 
262 // ----------------------------------------------------------------------------
263 #else
264 #error "Threads not supported"
265 #endif
266 
267 // ----------------------------------------------------------------------------
268 
androidCreateThread(android_thread_func_t fn,void * arg)269 int androidCreateThread(android_thread_func_t fn, void* arg)
270 {
271     return createThreadEtc(fn, arg);
272 }
273 
androidCreateThreadGetID(android_thread_func_t fn,void * arg,android_thread_id_t * id)274 int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)
275 {
276     return createThreadEtc(fn, arg, "android:unnamed_thread",
277                            PRIORITY_DEFAULT, 0, id);
278 }
279 
280 static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
281 
androidCreateThreadEtc(android_thread_func_t entryFunction,void * userData,const char * threadName,int32_t threadPriority,size_t threadStackSize,android_thread_id_t * threadId)282 int androidCreateThreadEtc(android_thread_func_t entryFunction,
283                             void *userData,
284                             const char* threadName,
285                             int32_t threadPriority,
286                             size_t threadStackSize,
287                             android_thread_id_t *threadId)
288 {
289     return gCreateThreadFn(entryFunction, userData, threadName,
290         threadPriority, threadStackSize, threadId);
291 }
292 
androidSetCreateThreadFunc(android_create_thread_fn func)293 void androidSetCreateThreadFunc(android_create_thread_fn func)
294 {
295     gCreateThreadFn = func;
296 }
297 
androidGetTid()298 pid_t androidGetTid()
299 {
300 #ifdef HAVE_GETTID
301     return gettid();
302 #else
303     return getpid();
304 #endif
305 }
306 
androidSetThreadSchedulingGroup(pid_t tid,int grp)307 int androidSetThreadSchedulingGroup(pid_t tid, int grp)
308 {
309     if (grp > ANDROID_TGROUP_MAX || grp < 0) {
310         return BAD_VALUE;
311     }
312 
313 #if defined(HAVE_PTHREADS)
314     pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
315     if (gDoSchedulingGroup) {
316         if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
317                                           SP_BACKGROUND : SP_FOREGROUND)) {
318             return PERMISSION_DENIED;
319         }
320     }
321 #endif
322 
323     return NO_ERROR;
324 }
325 
androidSetThreadPriority(pid_t tid,int pri)326 int androidSetThreadPriority(pid_t tid, int pri)
327 {
328     int rc = 0;
329 
330 #if defined(HAVE_PTHREADS)
331     int lasterr = 0;
332 
333     pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
334     if (gDoSchedulingGroup) {
335         if (pri >= ANDROID_PRIORITY_BACKGROUND) {
336             rc = set_sched_policy(tid, SP_BACKGROUND);
337         } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
338             rc = set_sched_policy(tid, SP_FOREGROUND);
339         }
340     }
341 
342     if (rc) {
343         lasterr = errno;
344     }
345 
346     if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
347         rc = INVALID_OPERATION;
348     } else {
349         errno = lasterr;
350     }
351 #endif
352 
353     return rc;
354 }
355 
356 namespace android {
357 
358 /*
359  * ===========================================================================
360  *      Mutex class
361  * ===========================================================================
362  */
363 
364 #if defined(HAVE_PTHREADS)
365 // implemented as inlines in threads.h
366 #elif defined(HAVE_WIN32_THREADS)
367 
368 Mutex::Mutex()
369 {
370     HANDLE hMutex;
371 
372     assert(sizeof(hMutex) == sizeof(mState));
373 
374     hMutex = CreateMutex(NULL, FALSE, NULL);
375     mState = (void*) hMutex;
376 }
377 
378 Mutex::Mutex(const char* name)
379 {
380     // XXX: name not used for now
381     HANDLE hMutex;
382 
383     assert(sizeof(hMutex) == sizeof(mState));
384 
385     hMutex = CreateMutex(NULL, FALSE, NULL);
386     mState = (void*) hMutex;
387 }
388 
389 Mutex::Mutex(int type, const char* name)
390 {
391     // XXX: type and name not used for now
392     HANDLE hMutex;
393 
394     assert(sizeof(hMutex) == sizeof(mState));
395 
396     hMutex = CreateMutex(NULL, FALSE, NULL);
397     mState = (void*) hMutex;
398 }
399 
400 Mutex::~Mutex()
401 {
402     CloseHandle((HANDLE) mState);
403 }
404 
405 status_t Mutex::lock()
406 {
407     DWORD dwWaitResult;
408     dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);
409     return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;
410 }
411 
412 void Mutex::unlock()
413 {
414     if (!ReleaseMutex((HANDLE) mState))
415         LOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
416 }
417 
418 status_t Mutex::tryLock()
419 {
420     DWORD dwWaitResult;
421 
422     dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
423     if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
424         LOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
425     return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
426 }
427 
428 #else
429 #error "Somebody forgot to implement threads for this platform."
430 #endif
431 
432 
433 /*
434  * ===========================================================================
435  *      Condition class
436  * ===========================================================================
437  */
438 
439 #if defined(HAVE_PTHREADS)
440 // implemented as inlines in threads.h
441 #elif defined(HAVE_WIN32_THREADS)
442 
443 /*
444  * Windows doesn't have a condition variable solution.  It's possible
445  * to create one, but it's easy to get it wrong.  For a discussion, and
446  * the origin of this implementation, see:
447  *
448  *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
449  *
450  * The implementation shown on the page does NOT follow POSIX semantics.
451  * As an optimization they require acquiring the external mutex before
452  * calling signal() and broadcast(), whereas POSIX only requires grabbing
453  * it before calling wait().  The implementation here has been un-optimized
454  * to have the correct behavior.
455  */
456 typedef struct WinCondition {
457     // Number of waiting threads.
458     int                 waitersCount;
459 
460     // Serialize access to waitersCount.
461     CRITICAL_SECTION    waitersCountLock;
462 
463     // Semaphore used to queue up threads waiting for the condition to
464     // become signaled.
465     HANDLE              sema;
466 
467     // An auto-reset event used by the broadcast/signal thread to wait
468     // for all the waiting thread(s) to wake up and be released from
469     // the semaphore.
470     HANDLE              waitersDone;
471 
472     // This mutex wouldn't be necessary if we required that the caller
473     // lock the external mutex before calling signal() and broadcast().
474     // I'm trying to mimic pthread semantics though.
475     HANDLE              internalMutex;
476 
477     // Keeps track of whether we were broadcasting or signaling.  This
478     // allows us to optimize the code if we're just signaling.
479     bool                wasBroadcast;
480 
481     status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)
482     {
483         // Increment the wait count, avoiding race conditions.
484         EnterCriticalSection(&condState->waitersCountLock);
485         condState->waitersCount++;
486         //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n",
487         //    condState->waitersCount, getThreadId());
488         LeaveCriticalSection(&condState->waitersCountLock);
489 
490         DWORD timeout = INFINITE;
491         if (abstime) {
492             nsecs_t reltime = *abstime - systemTime();
493             if (reltime < 0)
494                 reltime = 0;
495             timeout = reltime/1000000;
496         }
497 
498         // Atomically release the external mutex and wait on the semaphore.
499         DWORD res =
500             SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);
501 
502         //printf("+++ wait: awake (tid=%ld)\n", getThreadId());
503 
504         // Reacquire lock to avoid race conditions.
505         EnterCriticalSection(&condState->waitersCountLock);
506 
507         // No longer waiting.
508         condState->waitersCount--;
509 
510         // Check to see if we're the last waiter after a broadcast.
511         bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);
512 
513         //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n",
514         //    lastWaiter, condState->wasBroadcast, condState->waitersCount);
515 
516         LeaveCriticalSection(&condState->waitersCountLock);
517 
518         // If we're the last waiter thread during this particular broadcast
519         // then signal broadcast() that we're all awake.  It'll drop the
520         // internal mutex.
521         if (lastWaiter) {
522             // Atomically signal the "waitersDone" event and wait until we
523             // can acquire the internal mutex.  We want to do this in one step
524             // because it ensures that everybody is in the mutex FIFO before
525             // any thread has a chance to run.  Without it, another thread
526             // could wake up, do work, and hop back in ahead of us.
527             SignalObjectAndWait(condState->waitersDone, condState->internalMutex,
528                 INFINITE, FALSE);
529         } else {
530             // Grab the internal mutex.
531             WaitForSingleObject(condState->internalMutex, INFINITE);
532         }
533 
534         // Release the internal and grab the external.
535         ReleaseMutex(condState->internalMutex);
536         WaitForSingleObject(hMutex, INFINITE);
537 
538         return res == WAIT_OBJECT_0 ? NO_ERROR : -1;
539     }
540 } WinCondition;
541 
542 /*
543  * Constructor.  Set up the WinCondition stuff.
544  */
545 Condition::Condition()
546 {
547     WinCondition* condState = new WinCondition;
548 
549     condState->waitersCount = 0;
550     condState->wasBroadcast = false;
551     // semaphore: no security, initial value of 0
552     condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
553     InitializeCriticalSection(&condState->waitersCountLock);
554     // auto-reset event, not signaled initially
555     condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
556     // used so we don't have to lock external mutex on signal/broadcast
557     condState->internalMutex = CreateMutex(NULL, FALSE, NULL);
558 
559     mState = condState;
560 }
561 
562 /*
563  * Destructor.  Free Windows resources as well as our allocated storage.
564  */
565 Condition::~Condition()
566 {
567     WinCondition* condState = (WinCondition*) mState;
568     if (condState != NULL) {
569         CloseHandle(condState->sema);
570         CloseHandle(condState->waitersDone);
571         delete condState;
572     }
573 }
574 
575 
576 status_t Condition::wait(Mutex& mutex)
577 {
578     WinCondition* condState = (WinCondition*) mState;
579     HANDLE hMutex = (HANDLE) mutex.mState;
580 
581     return ((WinCondition*)mState)->wait(condState, hMutex, NULL);
582 }
583 
584 status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
585 {
586     WinCondition* condState = (WinCondition*) mState;
587     HANDLE hMutex = (HANDLE) mutex.mState;
588     nsecs_t absTime = systemTime()+reltime;
589 
590     return ((WinCondition*)mState)->wait(condState, hMutex, &absTime);
591 }
592 
593 /*
594  * Signal the condition variable, allowing one thread to continue.
595  */
596 void Condition::signal()
597 {
598     WinCondition* condState = (WinCondition*) mState;
599 
600     // Lock the internal mutex.  This ensures that we don't clash with
601     // broadcast().
602     WaitForSingleObject(condState->internalMutex, INFINITE);
603 
604     EnterCriticalSection(&condState->waitersCountLock);
605     bool haveWaiters = (condState->waitersCount > 0);
606     LeaveCriticalSection(&condState->waitersCountLock);
607 
608     // If no waiters, then this is a no-op.  Otherwise, knock the semaphore
609     // down a notch.
610     if (haveWaiters)
611         ReleaseSemaphore(condState->sema, 1, 0);
612 
613     // Release internal mutex.
614     ReleaseMutex(condState->internalMutex);
615 }
616 
617 /*
618  * Signal the condition variable, allowing all threads to continue.
619  *
620  * First we have to wake up all threads waiting on the semaphore, then
621  * we wait until all of the threads have actually been woken before
622  * releasing the internal mutex.  This ensures that all threads are woken.
623  */
624 void Condition::broadcast()
625 {
626     WinCondition* condState = (WinCondition*) mState;
627 
628     // Lock the internal mutex.  This keeps the guys we're waking up
629     // from getting too far.
630     WaitForSingleObject(condState->internalMutex, INFINITE);
631 
632     EnterCriticalSection(&condState->waitersCountLock);
633     bool haveWaiters = false;
634 
635     if (condState->waitersCount > 0) {
636         haveWaiters = true;
637         condState->wasBroadcast = true;
638     }
639 
640     if (haveWaiters) {
641         // Wake up all the waiters.
642         ReleaseSemaphore(condState->sema, condState->waitersCount, 0);
643 
644         LeaveCriticalSection(&condState->waitersCountLock);
645 
646         // Wait for all awakened threads to acquire the counting semaphore.
647         // The last guy who was waiting sets this.
648         WaitForSingleObject(condState->waitersDone, INFINITE);
649 
650         // Reset wasBroadcast.  (No crit section needed because nobody
651         // else can wake up to poke at it.)
652         condState->wasBroadcast = 0;
653     } else {
654         // nothing to do
655         LeaveCriticalSection(&condState->waitersCountLock);
656     }
657 
658     // Release internal mutex.
659     ReleaseMutex(condState->internalMutex);
660 }
661 
662 #else
663 #error "condition variables not supported on this platform"
664 #endif
665 
666 // ----------------------------------------------------------------------------
667 
668 /*
669  * This is our thread object!
670  */
671 
Thread(bool canCallJava)672 Thread::Thread(bool canCallJava)
673     :   mCanCallJava(canCallJava),
674         mThread(thread_id_t(-1)),
675         mLock("Thread::mLock"),
676         mStatus(NO_ERROR),
677         mExitPending(false), mRunning(false)
678 {
679 }
680 
~Thread()681 Thread::~Thread()
682 {
683 }
684 
readyToRun()685 status_t Thread::readyToRun()
686 {
687     return NO_ERROR;
688 }
689 
run(const char * name,int32_t priority,size_t stack)690 status_t Thread::run(const char* name, int32_t priority, size_t stack)
691 {
692     Mutex::Autolock _l(mLock);
693 
694     if (mRunning) {
695         // thread already started
696         return INVALID_OPERATION;
697     }
698 
699     // reset status and exitPending to their default value, so we can
700     // try again after an error happened (either below, or in readyToRun())
701     mStatus = NO_ERROR;
702     mExitPending = false;
703     mThread = thread_id_t(-1);
704 
705     // hold a strong reference on ourself
706     mHoldSelf = this;
707 
708     mRunning = true;
709 
710     bool res;
711     if (mCanCallJava) {
712         res = createThreadEtc(_threadLoop,
713                 this, name, priority, stack, &mThread);
714     } else {
715         res = androidCreateRawThreadEtc(_threadLoop,
716                 this, name, priority, stack, &mThread);
717     }
718 
719     if (res == false) {
720         mStatus = UNKNOWN_ERROR;   // something happened!
721         mRunning = false;
722         mThread = thread_id_t(-1);
723         mHoldSelf.clear();  // "this" may have gone away after this.
724 
725         return UNKNOWN_ERROR;
726     }
727 
728     // Do not refer to mStatus here: The thread is already running (may, in fact
729     // already have exited with a valid mStatus result). The NO_ERROR indication
730     // here merely indicates successfully starting the thread and does not
731     // imply successful termination/execution.
732     return NO_ERROR;
733 }
734 
_threadLoop(void * user)735 int Thread::_threadLoop(void* user)
736 {
737     Thread* const self = static_cast<Thread*>(user);
738     sp<Thread> strong(self->mHoldSelf);
739     wp<Thread> weak(strong);
740     self->mHoldSelf.clear();
741 
742 #if HAVE_ANDROID_OS
743     // this is very useful for debugging with gdb
744     self->mTid = gettid();
745 #endif
746 
747     bool first = true;
748 
749     do {
750         bool result;
751         if (first) {
752             first = false;
753             self->mStatus = self->readyToRun();
754             result = (self->mStatus == NO_ERROR);
755 
756             if (result && !self->mExitPending) {
757                 // Binder threads (and maybe others) rely on threadLoop
758                 // running at least once after a successful ::readyToRun()
759                 // (unless, of course, the thread has already been asked to exit
760                 // at that point).
761                 // This is because threads are essentially used like this:
762                 //   (new ThreadSubclass())->run();
763                 // The caller therefore does not retain a strong reference to
764                 // the thread and the thread would simply disappear after the
765                 // successful ::readyToRun() call instead of entering the
766                 // threadLoop at least once.
767                 result = self->threadLoop();
768             }
769         } else {
770             result = self->threadLoop();
771         }
772 
773         if (result == false || self->mExitPending) {
774             self->mExitPending = true;
775             self->mLock.lock();
776             self->mRunning = false;
777             // clear thread ID so that requestExitAndWait() does not exit if
778             // called by a new thread using the same thread ID as this one.
779             self->mThread = thread_id_t(-1);
780             self->mThreadExitedCondition.broadcast();
781             self->mThread = thread_id_t(-1); // thread id could be reused
782             self->mLock.unlock();
783             break;
784         }
785 
786         // Release our strong reference, to let a chance to the thread
787         // to die a peaceful death.
788         strong.clear();
789         // And immediately, re-acquire a strong reference for the next loop
790         strong = weak.promote();
791     } while(strong != 0);
792 
793     return 0;
794 }
795 
requestExit()796 void Thread::requestExit()
797 {
798     mExitPending = true;
799 }
800 
requestExitAndWait()801 status_t Thread::requestExitAndWait()
802 {
803     if (mThread == getThreadId()) {
804         LOGW(
805         "Thread (this=%p): don't call waitForExit() from this "
806         "Thread object's thread. It's a guaranteed deadlock!",
807         this);
808 
809         return WOULD_BLOCK;
810     }
811 
812     requestExit();
813 
814     Mutex::Autolock _l(mLock);
815     while (mRunning == true) {
816         mThreadExitedCondition.wait(mLock);
817     }
818     mExitPending = false;
819 
820     return mStatus;
821 }
822 
exitPending() const823 bool Thread::exitPending() const
824 {
825     return mExitPending;
826 }
827 
828 
829 
830 };  // namespace android
831