12bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian/* 22bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Copyright (C) 2007 The Android Open Source Project 32bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 42bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 52bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * you may not use this file except in compliance with the License. 62bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * You may obtain a copy of the License at 72bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 82bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 92bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 102bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Unless required by applicable law or agreed to in writing, software 112bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 122bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * See the License for the specific language governing permissions and 142bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * limitations under the License. 152bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian */ 162bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 172bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#ifndef _LIBS_UTILS_THREAD_H 182bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#define _LIBS_UTILS_THREAD_H 192bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 202bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <stdint.h> 212bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <sys/types.h> 222bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <time.h> 232bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 242bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS) 252bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian# include <pthread.h> 262bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif 272bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 282bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/Condition.h> 292bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/Errors.h> 302bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/Mutex.h> 312bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/RefBase.h> 322bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/Timers.h> 332bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/ThreadDefs.h> 342bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 352bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 362bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopiannamespace android { 372bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 382bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 392bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianclass Thread : virtual public RefBase 402bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian{ 412bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianpublic: 422bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Create a Thread object, but doesn't create or start the associated 432bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // thread. See the run() method. 442bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Thread(bool canCallJava = true); 452bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian virtual ~Thread(); 462bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 472bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Start the thread in threadLoop() which needs to be implemented. 482bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian virtual status_t run( const char* name = 0, 492bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian int32_t priority = PRIORITY_DEFAULT, 502bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian size_t stack = 0); 512bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 522bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Ask this object's thread to exit. This function is asynchronous, when the 532bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // function returns the thread might still be running. Of course, this 542bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // function can be called from a different thread. 552bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian virtual void requestExit(); 562bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 572bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Good place to do one-time initializations 582bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian virtual status_t readyToRun(); 592bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 602bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Call requestExit() and wait until this object's thread exits. 612bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call 622bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // this function from this object's thread. Will return WOULD_BLOCK in 632bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // that case. 642bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian status_t requestExitAndWait(); 652bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 662bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Wait until this object's thread exits. Returns immediately if not yet running. 672bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Do not call from this object's thread; will return WOULD_BLOCK in that case. 682bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian status_t join(); 692bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 7031ba37f1c80801ee128749d4772c47f23323a3beRomain Guy // Indicates whether this thread is running or not. 7131ba37f1c80801ee128749d4772c47f23323a3beRomain Guy bool isRunning() const; 7231ba37f1c80801ee128749d4772c47f23323a3beRomain Guy 732bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#ifdef HAVE_ANDROID_OS 742bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Return the thread's kernel ID, same as the thread itself calling gettid() or 752bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // androidGetTid(), or -1 if the thread is not running. 762bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pid_t getTid() const; 772bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif 782bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 792bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianprotected: 802bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // exitPending() returns true if requestExit() has been called. 812bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian bool exitPending() const; 822bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 832bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianprivate: 842bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Derived class must implement threadLoop(). The thread starts its life 852bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // here. There are two ways of using the Thread object: 862bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // 1) loop: if threadLoop() returns true, it will be called again if 872bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // requestExit() wasn't called. 882bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // 2) once: if threadLoop() returns false, the thread will exit upon return. 892bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian virtual bool threadLoop() = 0; 902bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 912bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianprivate: 922bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Thread& operator=(const Thread&); 932bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian static int _threadLoop(void* user); 942bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian const bool mCanCallJava; 952bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // always hold mLock when reading or writing 962bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian thread_id_t mThread; 972bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian mutable Mutex mLock; 982bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Condition mThreadExitedCondition; 992bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian status_t mStatus; 1002bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // note that all accesses of mExitPending and mRunning need to hold mLock 1012bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian volatile bool mExitPending; 1022bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian volatile bool mRunning; 1032bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian sp<Thread> mHoldSelf; 1042bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#ifdef HAVE_ANDROID_OS 1052bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // legacy for debugging, not used by getTid() as it is set by the child thread 1062bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // and so is not initialized until the child reaches that point 1072bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pid_t mTid; 1082bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif 1092bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}; 1102bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1112bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1122bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}; // namespace android 1132bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1142bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 1152bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // _LIBS_UTILS_THREAD_H 1162bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 117