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