17d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber/* 27d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * Copyright (C) 2010 The Android Open Source Project 37d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * 47d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 57d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * you may not use this file except in compliance with the License. 67d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * You may obtain a copy of the License at 77d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * 87d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 97d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * 107d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * Unless required by applicable law or agreed to in writing, software 117d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 127d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * See the License for the specific language governing permissions and 147d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * limitations under the License. 157d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber */ 167d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 177d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber//#define LOG_NDEBUG 0 187d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#define LOG_TAG "ALooper" 197d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include <utils/Log.h> 207d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 217d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include <sys/time.h> 227d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 237d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include "ALooper.h" 247d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 257d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include "AHandler.h" 267d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include "ALooperRoster.h" 277d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include "AMessage.h" 287d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 297d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubernamespace android { 307d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 317d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas HuberALooperRoster gLooperRoster; 327d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 337d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huberstruct ALooper::LooperThread : public Thread { 344f104d99d8657fd3fef675eb2a3e84ba9f5870e4Andreas Huber LooperThread(ALooper *looper, bool canCallJava) 354f104d99d8657fd3fef675eb2a3e84ba9f5870e4Andreas Huber : Thread(canCallJava), 364f104d99d8657fd3fef675eb2a3e84ba9f5870e4Andreas Huber mLooper(looper) { 377d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 387d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 397d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber virtual bool threadLoop() { 407d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return mLooper->loop(); 417d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 427d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 437d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huberprotected: 447d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber virtual ~LooperThread() {} 457d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 467d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huberprivate: 477d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ALooper *mLooper; 487d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 497d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(LooperThread); 507d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber}; 517d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 527d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber// static 537d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huberint64_t ALooper::GetNowUs() { 547d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber struct timeval tv; 557d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber gettimeofday(&tv, NULL); 567d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 577d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return (int64_t)tv.tv_sec * 1000000ll + tv.tv_usec; 587d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 597d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 607d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas HuberALooper::ALooper() 617d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber : mRunningLocally(false) { 627d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 637d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 647d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas HuberALooper::~ALooper() { 657d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber stop(); 667d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 677d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 68c4e0b70a21fadb47d70955c71fc31ce1473da925Andreas Hubervoid ALooper::setName(const char *name) { 69c4e0b70a21fadb47d70955c71fc31ce1473da925Andreas Huber mName = name; 70c4e0b70a21fadb47d70955c71fc31ce1473da925Andreas Huber} 71c4e0b70a21fadb47d70955c71fc31ce1473da925Andreas Huber 727d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas HuberALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) { 737d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return gLooperRoster.registerHandler(this, handler); 747d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 757d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 767d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubervoid ALooper::unregisterHandler(handler_id handlerID) { 777d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber gLooperRoster.unregisterHandler(handlerID); 787d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 797d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 804e4173b0af52bdf2b5730a5837476e400c5b2040Andreas Huberstatus_t ALooper::start( 814e4173b0af52bdf2b5730a5837476e400c5b2040Andreas Huber bool runOnCallingThread, bool canCallJava, int32_t priority) { 827d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (runOnCallingThread) { 837d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber { 847d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 857d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 867d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (mThread != NULL || mRunningLocally) { 877d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return INVALID_OPERATION; 887d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 897d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 907d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mRunningLocally = true; 917d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 927d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 937d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber do { 947d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } while (loop()); 957d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 967d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return OK; 977d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 987d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 997d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 1007d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1017d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (mThread != NULL || mRunningLocally) { 1027d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return INVALID_OPERATION; 1037d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1047d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1054f104d99d8657fd3fef675eb2a3e84ba9f5870e4Andreas Huber mThread = new LooperThread(this, canCallJava); 1067d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 107c4e0b70a21fadb47d70955c71fc31ce1473da925Andreas Huber status_t err = mThread->run( 108c4e0b70a21fadb47d70955c71fc31ce1473da925Andreas Huber mName.empty() ? "ALooper" : mName.c_str(), priority); 1097d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (err != OK) { 1107d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mThread.clear(); 1117d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1127d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1137d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return err; 1147d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 1157d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1167d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huberstatus_t ALooper::stop() { 1177d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber sp<LooperThread> thread; 1187d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber bool runningLocally; 1197d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1207d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber { 1217d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 1227d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1237d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber thread = mThread; 1247d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber runningLocally = mRunningLocally; 1257d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mThread.clear(); 1267d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mRunningLocally = false; 1277d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1287d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1297d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (thread == NULL && !runningLocally) { 1307d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return INVALID_OPERATION; 1317d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1327d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1337d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (thread != NULL) { 1347d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber thread->requestExit(); 1357d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1367d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1377d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mQueueChangedCondition.signal(); 1387d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1397d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (!runningLocally) { 1407d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber thread->requestExitAndWait(); 1417d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1427d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1437d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return OK; 1447d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 1457d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1467d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubervoid ALooper::post(const sp<AMessage> &msg, int64_t delayUs) { 1477d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 1487d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1497d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber int64_t whenUs; 1507d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (delayUs > 0) { 1517d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber whenUs = GetNowUs() + delayUs; 1527d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } else { 1537d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber whenUs = GetNowUs(); 1547d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1557d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1567d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber List<Event>::iterator it = mEventQueue.begin(); 1577d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) { 1587d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ++it; 1597d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1607d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1617d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Event event; 1627d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber event.mWhenUs = whenUs; 1637d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber event.mMessage = msg; 1647d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1657d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (it == mEventQueue.begin()) { 1667d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mQueueChangedCondition.signal(); 1677d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1687d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1697d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mEventQueue.insert(it, event); 1707d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 1717d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1727d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huberbool ALooper::loop() { 1737d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Event event; 1747d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1757d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber { 1767d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 1777d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (mThread == NULL && !mRunningLocally) { 1787d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return false; 1797d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1807d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (mEventQueue.empty()) { 1817d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mQueueChangedCondition.wait(mLock); 1827d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return true; 1837d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1847d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber int64_t whenUs = (*mEventQueue.begin()).mWhenUs; 1857d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber int64_t nowUs = GetNowUs(); 1867d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1877d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (whenUs > nowUs) { 1887d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber int64_t delayUs = whenUs - nowUs; 1897d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll); 1907d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1917d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return true; 1927d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1937d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1947d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber event = *mEventQueue.begin(); 1957d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mEventQueue.erase(mEventQueue.begin()); 1967d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1977d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1987d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber gLooperRoster.deliverMessage(event.mMessage); 1997d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 2007d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return true; 2017d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 2027d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 2037d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} // namespace android 204