ALooper.cpp revision f8be8c0c8055ead961d23b969bf46315eb93e887
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() { 6672961230a5890071bcca436eb5630172ce84ec41Andreas Huber struct timeval tv; 6772961230a5890071bcca436eb5630172ce84ec41Andreas Huber gettimeofday(&tv, NULL); 6872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 6972961230a5890071bcca436eb5630172ce84ec41Andreas Huber return (int64_t)tv.tv_sec * 1000000ll + tv.tv_usec; 7072961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 7172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 7272961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::ALooper() 7372961230a5890071bcca436eb5630172ce84ec41Andreas Huber : mRunningLocally(false) { 7472961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 7572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 7672961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::~ALooper() { 7772961230a5890071bcca436eb5630172ce84ec41Andreas Huber stop(); 7872961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 7972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 80a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Hubervoid ALooper::setName(const char *name) { 81a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mName = name; 82a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber} 83a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber 8472961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) { 8572961230a5890071bcca436eb5630172ce84ec41Andreas Huber return gLooperRoster.registerHandler(this, handler); 8672961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 8772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 8872961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::unregisterHandler(handler_id handlerID) { 8972961230a5890071bcca436eb5630172ce84ec41Andreas Huber gLooperRoster.unregisterHandler(handlerID); 9072961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 9172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 92348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huberstatus_t ALooper::start( 93348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber bool runOnCallingThread, bool canCallJava, int32_t priority) { 9472961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (runOnCallingThread) { 9572961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 9672961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 9772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 9872961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread != NULL || mRunningLocally) { 9972961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 10072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 10172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10272961230a5890071bcca436eb5630172ce84ec41Andreas Huber mRunningLocally = true; 10372961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 10472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10572961230a5890071bcca436eb5630172ce84ec41Andreas Huber do { 10672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } while (loop()); 10772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10872961230a5890071bcca436eb5630172ce84ec41Andreas Huber return OK; 10972961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 11072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11172961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 11272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11372961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread != NULL || mRunningLocally) { 11472961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 11572961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 11672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11742d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huber mThread = new LooperThread(this, canCallJava); 11872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 119a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber status_t err = mThread->run( 120a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mName.empty() ? "ALooper" : mName.c_str(), priority); 12172961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (err != OK) { 12272961230a5890071bcca436eb5630172ce84ec41Andreas Huber mThread.clear(); 12372961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 12472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 12572961230a5890071bcca436eb5630172ce84ec41Andreas Huber return err; 12672961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 12772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 12872961230a5890071bcca436eb5630172ce84ec41Andreas Huberstatus_t ALooper::stop() { 12972961230a5890071bcca436eb5630172ce84ec41Andreas Huber sp<LooperThread> thread; 13072961230a5890071bcca436eb5630172ce84ec41Andreas Huber bool runningLocally; 13172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 13272961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 13372961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 13472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 13572961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread = mThread; 13672961230a5890071bcca436eb5630172ce84ec41Andreas Huber runningLocally = mRunningLocally; 13772961230a5890071bcca436eb5630172ce84ec41Andreas Huber mThread.clear(); 13872961230a5890071bcca436eb5630172ce84ec41Andreas Huber mRunningLocally = false; 13972961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 14072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 14172961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (thread == NULL && !runningLocally) { 14272961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 14372961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 14472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 14572961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (thread != NULL) { 14672961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread->requestExit(); 14772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 14872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 14972961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.signal(); 15072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 151f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber if (!runningLocally && !thread->isCurrentThread()) { 152f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // If not running locally and this thread _is_ the looper thread, 153f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // the loop() function will return and never be called again. 15472961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread->requestExitAndWait(); 15572961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 15672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 15772961230a5890071bcca436eb5630172ce84ec41Andreas Huber return OK; 15872961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 15972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 16072961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::post(const sp<AMessage> &msg, int64_t delayUs) { 16172961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 16272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 16372961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t whenUs; 16472961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (delayUs > 0) { 16572961230a5890071bcca436eb5630172ce84ec41Andreas Huber whenUs = GetNowUs() + delayUs; 16672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } else { 16772961230a5890071bcca436eb5630172ce84ec41Andreas Huber whenUs = GetNowUs(); 16872961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 16972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 17072961230a5890071bcca436eb5630172ce84ec41Andreas Huber List<Event>::iterator it = mEventQueue.begin(); 17172961230a5890071bcca436eb5630172ce84ec41Andreas Huber while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) { 17272961230a5890071bcca436eb5630172ce84ec41Andreas Huber ++it; 17372961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 17472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 17572961230a5890071bcca436eb5630172ce84ec41Andreas Huber Event event; 17672961230a5890071bcca436eb5630172ce84ec41Andreas Huber event.mWhenUs = whenUs; 17772961230a5890071bcca436eb5630172ce84ec41Andreas Huber event.mMessage = msg; 17872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 17972961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (it == mEventQueue.begin()) { 18072961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.signal(); 18172961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 18272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18372961230a5890071bcca436eb5630172ce84ec41Andreas Huber mEventQueue.insert(it, event); 18472961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 18572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18672961230a5890071bcca436eb5630172ce84ec41Andreas Huberbool ALooper::loop() { 18772961230a5890071bcca436eb5630172ce84ec41Andreas Huber Event event; 18872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18972961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 19072961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 19172961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread == NULL && !mRunningLocally) { 19272961230a5890071bcca436eb5630172ce84ec41Andreas Huber return false; 19372961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 19472961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mEventQueue.empty()) { 19572961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.wait(mLock); 19672961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 19772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 19872961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t whenUs = (*mEventQueue.begin()).mWhenUs; 19972961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t nowUs = GetNowUs(); 20072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 20172961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (whenUs > nowUs) { 20272961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t delayUs = whenUs - nowUs; 20372961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll); 20472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 20572961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 20672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 20772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 20872961230a5890071bcca436eb5630172ce84ec41Andreas Huber event = *mEventQueue.begin(); 20972961230a5890071bcca436eb5630172ce84ec41Andreas Huber mEventQueue.erase(mEventQueue.begin()); 21072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 21172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 21272961230a5890071bcca436eb5630172ce84ec41Andreas Huber gLooperRoster.deliverMessage(event.mMessage); 21372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 214f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // NOTE: It's important to note that at this point our "ALooper" object 215f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // may no longer exist (its final reference may have gone away while 216f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // delivering the message). We have made sure, however, that loop() 217f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // won't be called again. 218f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber 21972961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 22072961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 22172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 22272961230a5890071bcca436eb5630172ce84ec41Andreas Huber} // namespace android 223