ALooper.cpp revision 348a8eab84f4bba76c04ca83b2f5418467aa1a48
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), 3642d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huber mLooper(looper) { 3772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 3872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 3972961230a5890071bcca436eb5630172ce84ec41Andreas Huber virtual bool threadLoop() { 4072961230a5890071bcca436eb5630172ce84ec41Andreas Huber return mLooper->loop(); 4172961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 4272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 4372961230a5890071bcca436eb5630172ce84ec41Andreas Huberprotected: 4472961230a5890071bcca436eb5630172ce84ec41Andreas Huber virtual ~LooperThread() {} 4572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 4672961230a5890071bcca436eb5630172ce84ec41Andreas Huberprivate: 4772961230a5890071bcca436eb5630172ce84ec41Andreas Huber ALooper *mLooper; 4872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 4972961230a5890071bcca436eb5630172ce84ec41Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(LooperThread); 5072961230a5890071bcca436eb5630172ce84ec41Andreas Huber}; 5172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 5272961230a5890071bcca436eb5630172ce84ec41Andreas Huber// static 5372961230a5890071bcca436eb5630172ce84ec41Andreas Huberint64_t ALooper::GetNowUs() { 5472961230a5890071bcca436eb5630172ce84ec41Andreas Huber struct timeval tv; 5572961230a5890071bcca436eb5630172ce84ec41Andreas Huber gettimeofday(&tv, NULL); 5672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 5772961230a5890071bcca436eb5630172ce84ec41Andreas Huber return (int64_t)tv.tv_sec * 1000000ll + tv.tv_usec; 5872961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 5972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 6072961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::ALooper() 6172961230a5890071bcca436eb5630172ce84ec41Andreas Huber : mRunningLocally(false) { 6272961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 6372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 6472961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::~ALooper() { 6572961230a5890071bcca436eb5630172ce84ec41Andreas Huber stop(); 6672961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 6772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 6872961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) { 6972961230a5890071bcca436eb5630172ce84ec41Andreas Huber return gLooperRoster.registerHandler(this, handler); 7072961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 7172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 7272961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::unregisterHandler(handler_id handlerID) { 7372961230a5890071bcca436eb5630172ce84ec41Andreas Huber gLooperRoster.unregisterHandler(handlerID); 7472961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 7572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 76348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huberstatus_t ALooper::start( 77348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber bool runOnCallingThread, bool canCallJava, int32_t priority) { 7872961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (runOnCallingThread) { 7972961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 8072961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 8172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 8272961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread != NULL || mRunningLocally) { 8372961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 8472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 8572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 8672961230a5890071bcca436eb5630172ce84ec41Andreas Huber mRunningLocally = true; 8772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 8872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 8972961230a5890071bcca436eb5630172ce84ec41Andreas Huber do { 9072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } while (loop()); 9172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 9272961230a5890071bcca436eb5630172ce84ec41Andreas Huber return OK; 9372961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 9472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 9572961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 9672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 9772961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread != NULL || mRunningLocally) { 9872961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 9972961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 10072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10142d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huber mThread = new LooperThread(this, canCallJava); 10272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 103348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber status_t err = mThread->run("ALooper", priority); 10472961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (err != OK) { 10572961230a5890071bcca436eb5630172ce84ec41Andreas Huber mThread.clear(); 10672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 10772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 10872961230a5890071bcca436eb5630172ce84ec41Andreas Huber return err; 10972961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 11072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11172961230a5890071bcca436eb5630172ce84ec41Andreas Huberstatus_t ALooper::stop() { 11272961230a5890071bcca436eb5630172ce84ec41Andreas Huber sp<LooperThread> thread; 11372961230a5890071bcca436eb5630172ce84ec41Andreas Huber bool runningLocally; 11472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11572961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 11672961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 11772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 11872961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread = mThread; 11972961230a5890071bcca436eb5630172ce84ec41Andreas Huber runningLocally = mRunningLocally; 12072961230a5890071bcca436eb5630172ce84ec41Andreas Huber mThread.clear(); 12172961230a5890071bcca436eb5630172ce84ec41Andreas Huber mRunningLocally = false; 12272961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 12372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 12472961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (thread == NULL && !runningLocally) { 12572961230a5890071bcca436eb5630172ce84ec41Andreas Huber return INVALID_OPERATION; 12672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 12772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 12872961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (thread != NULL) { 12972961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread->requestExit(); 13072961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 13172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 13272961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.signal(); 13372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 13472961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (!runningLocally) { 13572961230a5890071bcca436eb5630172ce84ec41Andreas Huber thread->requestExitAndWait(); 13672961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 13772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 13872961230a5890071bcca436eb5630172ce84ec41Andreas Huber return OK; 13972961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 14072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 14172961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::post(const sp<AMessage> &msg, int64_t delayUs) { 14272961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 14372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 14472961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t whenUs; 14572961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (delayUs > 0) { 14672961230a5890071bcca436eb5630172ce84ec41Andreas Huber whenUs = GetNowUs() + delayUs; 14772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } else { 14872961230a5890071bcca436eb5630172ce84ec41Andreas Huber whenUs = GetNowUs(); 14972961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 15072961230a5890071bcca436eb5630172ce84ec41Andreas Huber 15172961230a5890071bcca436eb5630172ce84ec41Andreas Huber List<Event>::iterator it = mEventQueue.begin(); 15272961230a5890071bcca436eb5630172ce84ec41Andreas Huber while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) { 15372961230a5890071bcca436eb5630172ce84ec41Andreas Huber ++it; 15472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 15572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 15672961230a5890071bcca436eb5630172ce84ec41Andreas Huber Event event; 15772961230a5890071bcca436eb5630172ce84ec41Andreas Huber event.mWhenUs = whenUs; 15872961230a5890071bcca436eb5630172ce84ec41Andreas Huber event.mMessage = msg; 15972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 16072961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (it == mEventQueue.begin()) { 16172961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.signal(); 16272961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 16372961230a5890071bcca436eb5630172ce84ec41Andreas Huber 16472961230a5890071bcca436eb5630172ce84ec41Andreas Huber mEventQueue.insert(it, event); 16572961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 16672961230a5890071bcca436eb5630172ce84ec41Andreas Huber 16772961230a5890071bcca436eb5630172ce84ec41Andreas Huberbool ALooper::loop() { 16872961230a5890071bcca436eb5630172ce84ec41Andreas Huber Event event; 16972961230a5890071bcca436eb5630172ce84ec41Andreas Huber 17072961230a5890071bcca436eb5630172ce84ec41Andreas Huber { 17172961230a5890071bcca436eb5630172ce84ec41Andreas Huber Mutex::Autolock autoLock(mLock); 17272961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mThread == NULL && !mRunningLocally) { 17372961230a5890071bcca436eb5630172ce84ec41Andreas Huber return false; 17472961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 17572961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (mEventQueue.empty()) { 17672961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.wait(mLock); 17772961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 17872961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 17972961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t whenUs = (*mEventQueue.begin()).mWhenUs; 18072961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t nowUs = GetNowUs(); 18172961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18272961230a5890071bcca436eb5630172ce84ec41Andreas Huber if (whenUs > nowUs) { 18372961230a5890071bcca436eb5630172ce84ec41Andreas Huber int64_t delayUs = whenUs - nowUs; 18472961230a5890071bcca436eb5630172ce84ec41Andreas Huber mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll); 18572961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18672961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 18772961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 18872961230a5890071bcca436eb5630172ce84ec41Andreas Huber 18972961230a5890071bcca436eb5630172ce84ec41Andreas Huber event = *mEventQueue.begin(); 19072961230a5890071bcca436eb5630172ce84ec41Andreas Huber mEventQueue.erase(mEventQueue.begin()); 19172961230a5890071bcca436eb5630172ce84ec41Andreas Huber } 19272961230a5890071bcca436eb5630172ce84ec41Andreas Huber 19372961230a5890071bcca436eb5630172ce84ec41Andreas Huber gLooperRoster.deliverMessage(event.mMessage); 19472961230a5890071bcca436eb5630172ce84ec41Andreas Huber 19572961230a5890071bcca436eb5630172ce84ec41Andreas Huber return true; 19672961230a5890071bcca436eb5630172ce84ec41Andreas Huber} 19772961230a5890071bcca436eb5630172ce84ec41Andreas Huber 19872961230a5890071bcca436eb5630172ce84ec41Andreas Huber} // namespace android 199