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