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