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