ALooper.cpp revision af5dd7753e62353411cf0daf3b513c38818e9662
172961230a5890071bcca436eb5630172ce84ec41Andreas Huber/* 272961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Copyright (C) 2010 The Android Open Source Project 372961230a5890071bcca436eb5630172ce84ec41Andreas Huber * 472961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 572961230a5890071bcca436eb5630172ce84ec41Andreas Huber * you may not use this file except in compliance with the License. 672961230a5890071bcca436eb5630172ce84ec41Andreas Huber * You may obtain a copy of the License at 772961230a5890071bcca436eb5630172ce84ec41Andreas Huber * 872961230a5890071bcca436eb5630172ce84ec41Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 972961230a5890071bcca436eb5630172ce84ec41Andreas Huber * 1072961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Unless required by applicable law or agreed to in writing, software 1172961230a5890071bcca436eb5630172ce84ec41Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1272961230a5890071bcca436eb5630172ce84ec41Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1372961230a5890071bcca436eb5630172ce84ec41Andreas Huber * See the License for the specific language governing permissions and 1472961230a5890071bcca436eb5630172ce84ec41Andreas Huber * limitations under the License. 1572961230a5890071bcca436eb5630172ce84ec41Andreas Huber */ 1672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 1772961230a5890071bcca436eb5630172ce84ec41Andreas Huber//#define LOG_NDEBUG 0 1872961230a5890071bcca436eb5630172ce84ec41Andreas Huber#define LOG_TAG "ALooper" 1972961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include <utils/Log.h> 2072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 2172961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include <sys/time.h> 2272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 2372961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "ALooper.h" 2472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 2572961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "AHandler.h" 2672961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "ALooperRoster.h" 2772961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "AMessage.h" 2872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 2972961230a5890071bcca436eb5630172ce84ec41Andreas Hubernamespace android { 3072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 3172961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooperRoster gLooperRoster; 3272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 3372961230a5890071bcca436eb5630172ce84ec41Andreas Huberstruct ALooper::LooperThread : public Thread { 3442d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huber LooperThread(ALooper *looper, bool canCallJava) 3542d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huber : Thread(canCallJava), 36f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber mLooper(looper), 37f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber mThreadId(NULL) { 38f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber } 39f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber 40f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber virtual status_t readyToRun() { 41f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber mThreadId = androidGetThreadId(); 42f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber 43f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber return Thread::readyToRun(); 4472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 4572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 4672961230a5890071bcca436eb5630172ce84ec41Andreas Huber virtual bool threadLoop() { 4772961230a5890071bcca436eb5630172ce84ec41Andreas Huber return mLooper->loop(); 4872961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 4972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 50f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber bool isCurrentThread() const { 51f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber return mThreadId == androidGetThreadId(); 52f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber } 53f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber 5472961230a5890071bcca436eb5630172ce84ec41Andreas Huberprotected: 5572961230a5890071bcca436eb5630172ce84ec41Andreas Huber virtual ~LooperThread() {} 5672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 5772961230a5890071bcca436eb5630172ce84ec41Andreas Huberprivate: 5872961230a5890071bcca436eb5630172ce84ec41Andreas Huber ALooper *mLooper; 59f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber android_thread_id_t mThreadId; 6072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 6172961230a5890071bcca436eb5630172ce84ec41Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(LooperThread); 6272961230a5890071bcca436eb5630172ce84ec41Andreas Huber}; 6372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 6472961230a5890071bcca436eb5630172ce84ec41Andreas Huber// static 6572961230a5890071bcca436eb5630172ce84ec41Andreas Huberint64_t ALooper::GetNowUs() { 66af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber return systemTime(SYSTEM_TIME_MONOTONIC) / 1000ll; 6772961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 6872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 6972961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::ALooper() 7072961230a5890071bcca436eb5630172ce84ec41Andreas Huber : mRunningLocally(false) { 7172961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 7272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 7372961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::~ALooper() { 7472961230a5890071bcca436eb5630172ce84ec41Andreas Huber stop(); 7572961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 7672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 77a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Hubervoid ALooper::setName(const char *name) { 78a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mName = name; 79a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber} 80a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber 8172961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) { 8272961230a5890071bcca436eb5630172ce84ec41Andreas Huber return gLooperRoster.registerHandler(this, handler); 8372961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 8472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 8572961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::unregisterHandler(handler_id handlerID) { 8672961230a5890071bcca436eb5630172ce84ec41Andreas Huber gLooperRoster.unregisterHandler(handlerID); 8772961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 8872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 89348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huberstatus_t ALooper::start( 90348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber bool runOnCallingThread, bool canCallJava, int32_t priority) { 9172961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (runOnCallingThread) { 9272961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 9372961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 9472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 9572961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread != NULL || mRunningLocally) { 9672961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 9772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 9872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 9972961230a5890071bcca436eb5630172ce84ec41Andreas Huber mRunningLocally = true; 10072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 10172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10272961230a5890071bcca436eb5630172ce84ec41Andreas Huber do { 10372961230a5890071bcca436eb5630172ce84ec41Andreas Huber } while (loop()); 10472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10572961230a5890071bcca436eb5630172ce84ec41Andreas Huber return OK; 10672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 10772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10872961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 10972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11072961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread != NULL || mRunningLocally) { 11172961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 11272961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 11372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11442d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huber mThread = new LooperThread(this, canCallJava); 11572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 116a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber status_t err = mThread->run( 117a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mName.empty() ? "ALooper" : mName.c_str(), priority); 11872961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (err != OK) { 11972961230a5890071bcca436eb5630172ce84ec41Andreas Huber mThread.clear(); 12072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 12172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 12272961230a5890071bcca436eb5630172ce84ec41Andreas Huber return err; 12372961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 12472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 12572961230a5890071bcca436eb5630172ce84ec41Andreas Huberstatus_t ALooper::stop() { 12672961230a5890071bcca436eb5630172ce84ec41Andreas Huber sp<LooperThread> thread; 12772961230a5890071bcca436eb5630172ce84ec41Andreas Huber bool runningLocally; 12872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 12972961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 13072961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 13172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 13272961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread = mThread; 13372961230a5890071bcca436eb5630172ce84ec41Andreas Huber runningLocally = mRunningLocally; 13472961230a5890071bcca436eb5630172ce84ec41Andreas Huber mThread.clear(); 13572961230a5890071bcca436eb5630172ce84ec41Andreas Huber mRunningLocally = false; 13672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 13772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 13872961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (thread == NULL && !runningLocally) { 13972961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 14072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 14172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 14272961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (thread != NULL) { 14372961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread->requestExit(); 14472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 14572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 14672961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.signal(); 14772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 148f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber if (!runningLocally && !thread->isCurrentThread()) { 149f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // If not running locally and this thread _is_ the looper thread, 150f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // the loop() function will return and never be called again. 15172961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread->requestExitAndWait(); 15272961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 15372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 15472961230a5890071bcca436eb5630172ce84ec41Andreas Huber return OK; 15572961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 15672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 15772961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::post(const sp<AMessage> &msg, int64_t delayUs) { 15872961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 15972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 16072961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t whenUs; 16172961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (delayUs > 0) { 16272961230a5890071bcca436eb5630172ce84ec41Andreas Huber whenUs = GetNowUs() + delayUs; 16372961230a5890071bcca436eb5630172ce84ec41Andreas Huber } else { 16472961230a5890071bcca436eb5630172ce84ec41Andreas Huber whenUs = GetNowUs(); 16572961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 16672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 16772961230a5890071bcca436eb5630172ce84ec41Andreas Huber List<Event>::iterator it = mEventQueue.begin(); 16872961230a5890071bcca436eb5630172ce84ec41Andreas Huber while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) { 16972961230a5890071bcca436eb5630172ce84ec41Andreas Huber ++it; 17072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 17172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 17272961230a5890071bcca436eb5630172ce84ec41Andreas Huber Event event; 17372961230a5890071bcca436eb5630172ce84ec41Andreas Huber event.mWhenUs = whenUs; 17472961230a5890071bcca436eb5630172ce84ec41Andreas Huber event.mMessage = msg; 17572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 17672961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (it == mEventQueue.begin()) { 17772961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.signal(); 17872961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 17972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18072961230a5890071bcca436eb5630172ce84ec41Andreas Huber mEventQueue.insert(it, event); 18172961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 18272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18372961230a5890071bcca436eb5630172ce84ec41Andreas Huberbool ALooper::loop() { 18472961230a5890071bcca436eb5630172ce84ec41Andreas Huber Event event; 18572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18672961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 18772961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 18872961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread == NULL && !mRunningLocally) { 18972961230a5890071bcca436eb5630172ce84ec41Andreas Huber return false; 19072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 19172961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mEventQueue.empty()) { 19272961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.wait(mLock); 19372961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 19472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 19572961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t whenUs = (*mEventQueue.begin()).mWhenUs; 19672961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t nowUs = GetNowUs(); 19772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 19872961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (whenUs > nowUs) { 19972961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t delayUs = whenUs - nowUs; 20072961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll); 20172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 20272961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 20372961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 20472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 20572961230a5890071bcca436eb5630172ce84ec41Andreas Huber event = *mEventQueue.begin(); 20672961230a5890071bcca436eb5630172ce84ec41Andreas Huber mEventQueue.erase(mEventQueue.begin()); 20772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 20872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 20972961230a5890071bcca436eb5630172ce84ec41Andreas Huber gLooperRoster.deliverMessage(event.mMessage); 21072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 211f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // NOTE: It's important to note that at this point our "ALooper" object 212f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // may no longer exist (its final reference may have gone away while 213f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // delivering the message). We have made sure, however, that loop() 214f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // won't be called again. 215f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber 21672961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 21772961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 21872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 21972961230a5890071bcca436eb5630172ce84ec41Andreas Huber} // namespace android 220