1f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian/* 2f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * Copyright (C) 2007 The Android Open Source Project 3f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * 4f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * you may not use this file except in compliance with the License. 6f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * You may obtain a copy of the License at 7f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * 8f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * 10f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * Unless required by applicable law or agreed to in writing, software 11f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * See the License for the specific language governing permissions and 14f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * limitations under the License. 15f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian */ 16f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 17f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#ifndef _LIBS_UTILS_THREAD_H 18f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#define _LIBS_UTILS_THREAD_H 19f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 20f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <stdint.h> 21f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <sys/types.h> 22f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <time.h> 23f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 24f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#if defined(HAVE_PTHREADS) 25f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian# include <pthread.h> 26f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif 27f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 28f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <utils/Condition.h> 29f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <utils/Errors.h> 30f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <utils/Mutex.h> 31f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <utils/RefBase.h> 32f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <utils/Timers.h> 33f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <utils/ThreadDefs.h> 34f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 35f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian// --------------------------------------------------------------------------- 36f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopiannamespace android { 37f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian// --------------------------------------------------------------------------- 38f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 39f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianclass Thread : virtual public RefBase 40f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian{ 41f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianpublic: 42f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Create a Thread object, but doesn't create or start the associated 43f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // thread. See the run() method. 44f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian Thread(bool canCallJava = true); 45f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian virtual ~Thread(); 46f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 47f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Start the thread in threadLoop() which needs to be implemented. 48f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian virtual status_t run( const char* name = 0, 49f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian int32_t priority = PRIORITY_DEFAULT, 50f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian size_t stack = 0); 51f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 52f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Ask this object's thread to exit. This function is asynchronous, when the 53f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // function returns the thread might still be running. Of course, this 54f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // function can be called from a different thread. 55f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian virtual void requestExit(); 56f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 57f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Good place to do one-time initializations 58f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian virtual status_t readyToRun(); 59f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 60f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Call requestExit() and wait until this object's thread exits. 61f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call 62f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // this function from this object's thread. Will return WOULD_BLOCK in 63f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // that case. 64f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian status_t requestExitAndWait(); 65f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 66f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Wait until this object's thread exits. Returns immediately if not yet running. 67f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Do not call from this object's thread; will return WOULD_BLOCK in that case. 68f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian status_t join(); 69f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 70f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#ifdef HAVE_ANDROID_OS 71f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Return the thread's kernel ID, same as the thread itself calling gettid() or 72f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // androidGetTid(), or -1 if the thread is not running. 73f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pid_t getTid() const; 74f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif 75f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 76f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianprotected: 77f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // exitPending() returns true if requestExit() has been called. 78f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian bool exitPending() const; 79f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 80f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianprivate: 81f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Derived class must implement threadLoop(). The thread starts its life 82f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // here. There are two ways of using the Thread object: 83f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // 1) loop: if threadLoop() returns true, it will be called again if 84f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // requestExit() wasn't called. 85f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // 2) once: if threadLoop() returns false, the thread will exit upon return. 86f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian virtual bool threadLoop() = 0; 87f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 88f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianprivate: 89f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian Thread& operator=(const Thread&); 90f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian static int _threadLoop(void* user); 91f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian const bool mCanCallJava; 92f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // always hold mLock when reading or writing 93f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian thread_id_t mThread; 94f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian mutable Mutex mLock; 95f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian Condition mThreadExitedCondition; 96f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian status_t mStatus; 97f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // note that all accesses of mExitPending and mRunning need to hold mLock 98f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian volatile bool mExitPending; 99f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian volatile bool mRunning; 100f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian sp<Thread> mHoldSelf; 101f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#ifdef HAVE_ANDROID_OS 102f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // legacy for debugging, not used by getTid() as it is set by the child thread 103f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // and so is not initialized until the child reaches that point 104f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pid_t mTid; 105f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif 106f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian}; 107f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 108f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 109f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian}; // namespace android 110f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 111f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian// --------------------------------------------------------------------------- 112f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif // _LIBS_UTILS_THREAD_H 113f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian// --------------------------------------------------------------------------- 114