ALooper.cpp revision 0b0f6075377260e006e860e3ba296f5504a6c891
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) { 710b0f6075377260e006e860e3ba296f5504a6c891Marco Nelissen // clean up stale AHandlers. Doing it here instead of in the destructor avoids 720b0f6075377260e006e860e3ba296f5504a6c891Marco Nelissen // the side effect of objects being deleted from the unregister function recursively. 730b0f6075377260e006e860e3ba296f5504a6c891Marco Nelissen gLooperRoster.unregisterStaleHandlers(); 7472961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 7572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 7672961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::~ALooper() { 7772961230a5890071bcca436eb5630172ce84ec41Andreas Huber stop(); 780b0f6075377260e006e860e3ba296f5504a6c891Marco Nelissen // stale AHandlers are now cleaned up in the constructor of the next ALooper to come along 7972961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 8072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 81a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Hubervoid ALooper::setName(const char *name) { 82a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mName = name; 83a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber} 84a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber 8572961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) { 8672961230a5890071bcca436eb5630172ce84ec41Andreas Huber return gLooperRoster.registerHandler(this, handler); 8772961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 8872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 8972961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::unregisterHandler(handler_id handlerID) { 9072961230a5890071bcca436eb5630172ce84ec41Andreas Huber gLooperRoster.unregisterHandler(handlerID); 9172961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 9272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 93348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huberstatus_t ALooper::start( 94348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber bool runOnCallingThread, bool canCallJava, int32_t priority) { 9572961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (runOnCallingThread) { 9672961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 9772961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 9872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 9972961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread != NULL || mRunningLocally) { 10072961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 10172961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 10272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10372961230a5890071bcca436eb5630172ce84ec41Andreas Huber mRunningLocally = true; 10472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 10572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10672961230a5890071bcca436eb5630172ce84ec41Andreas Huber do { 10772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } while (loop()); 10872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10972961230a5890071bcca436eb5630172ce84ec41Andreas Huber return OK; 11072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 11172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11272961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 11372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11472961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread != NULL || mRunningLocally) { 11572961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 11672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 11772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11842d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huber mThread = new LooperThread(this, canCallJava); 11972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 120a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber status_t err = mThread->run( 121a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mName.empty() ? "ALooper" : mName.c_str(), priority); 12272961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (err != OK) { 12372961230a5890071bcca436eb5630172ce84ec41Andreas Huber mThread.clear(); 12472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 12572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 12672961230a5890071bcca436eb5630172ce84ec41Andreas Huber return err; 12772961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 12872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 12972961230a5890071bcca436eb5630172ce84ec41Andreas Huberstatus_t ALooper::stop() { 13072961230a5890071bcca436eb5630172ce84ec41Andreas Huber sp<LooperThread> thread; 13172961230a5890071bcca436eb5630172ce84ec41Andreas Huber bool runningLocally; 13272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 13372961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 13472961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 13572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 13672961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread = mThread; 13772961230a5890071bcca436eb5630172ce84ec41Andreas Huber runningLocally = mRunningLocally; 13872961230a5890071bcca436eb5630172ce84ec41Andreas Huber mThread.clear(); 13972961230a5890071bcca436eb5630172ce84ec41Andreas Huber mRunningLocally = false; 14072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 14172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 14272961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (thread == NULL && !runningLocally) { 14372961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 14472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 14572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 14672961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (thread != NULL) { 14772961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread->requestExit(); 14872961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 14972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 15072961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.signal(); 15172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 152f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber if (!runningLocally && !thread->isCurrentThread()) { 153f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // If not running locally and this thread _is_ the looper thread, 154f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // the loop() function will return and never be called again. 15572961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread->requestExitAndWait(); 15672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 15772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 15872961230a5890071bcca436eb5630172ce84ec41Andreas Huber return OK; 15972961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 16072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 16172961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::post(const sp<AMessage> &msg, int64_t delayUs) { 16272961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 16372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 16472961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t whenUs; 16572961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (delayUs > 0) { 16672961230a5890071bcca436eb5630172ce84ec41Andreas Huber whenUs = GetNowUs() + delayUs; 16772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } else { 16872961230a5890071bcca436eb5630172ce84ec41Andreas Huber whenUs = GetNowUs(); 16972961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 17072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 17172961230a5890071bcca436eb5630172ce84ec41Andreas Huber List<Event>::iterator it = mEventQueue.begin(); 17272961230a5890071bcca436eb5630172ce84ec41Andreas Huber while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) { 17372961230a5890071bcca436eb5630172ce84ec41Andreas Huber ++it; 17472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 17572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 17672961230a5890071bcca436eb5630172ce84ec41Andreas Huber Event event; 17772961230a5890071bcca436eb5630172ce84ec41Andreas Huber event.mWhenUs = whenUs; 17872961230a5890071bcca436eb5630172ce84ec41Andreas Huber event.mMessage = msg; 17972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18072961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (it == mEventQueue.begin()) { 18172961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.signal(); 18272961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 18372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18472961230a5890071bcca436eb5630172ce84ec41Andreas Huber mEventQueue.insert(it, event); 18572961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 18672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18772961230a5890071bcca436eb5630172ce84ec41Andreas Huberbool ALooper::loop() { 18872961230a5890071bcca436eb5630172ce84ec41Andreas Huber Event event; 18972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 19072961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 19172961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 19272961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread == NULL && !mRunningLocally) { 19372961230a5890071bcca436eb5630172ce84ec41Andreas Huber return false; 19472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 19572961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mEventQueue.empty()) { 19672961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.wait(mLock); 19772961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 19872961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 19972961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t whenUs = (*mEventQueue.begin()).mWhenUs; 20072961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t nowUs = GetNowUs(); 20172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 20272961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (whenUs > nowUs) { 20372961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t delayUs = whenUs - nowUs; 20472961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll); 20572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 20672961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 20772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 20872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 20972961230a5890071bcca436eb5630172ce84ec41Andreas Huber event = *mEventQueue.begin(); 21072961230a5890071bcca436eb5630172ce84ec41Andreas Huber mEventQueue.erase(mEventQueue.begin()); 21172961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 21272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 21372961230a5890071bcca436eb5630172ce84ec41Andreas Huber gLooperRoster.deliverMessage(event.mMessage); 21472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 215f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // NOTE: It's important to note that at this point our "ALooper" object 216f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // may no longer exist (its final reference may have gone away while 217f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // delivering the message). We have made sure, however, that loop() 218f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber // won't be called again. 219f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber 22072961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 22172961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 22272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 22372961230a5890071bcca436eb5630172ce84ec41Andreas Huber} // namespace android 224