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