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) {
7172961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
7272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
7372961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::~ALooper() {
7472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    stop();
7572961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
7672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
77a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Hubervoid ALooper::setName(const char *name) {
78a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber    mName = name;
79a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber}
80a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber
8172961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) {
8272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return gLooperRoster.registerHandler(this, handler);
8372961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
8472961230a5890071bcca436eb5630172ce84ec41Andreas Huber
8572961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::unregisterHandler(handler_id handlerID) {
8672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    gLooperRoster.unregisterHandler(handlerID);
8772961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
8872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
89348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huberstatus_t ALooper::start(
90348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber        bool runOnCallingThread, bool canCallJava, int32_t priority) {
9172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (runOnCallingThread) {
9272961230a5890071bcca436eb5630172ce84ec41Andreas Huber        {
9372961230a5890071bcca436eb5630172ce84ec41Andreas Huber            Mutex::Autolock autoLock(mLock);
9472961230a5890071bcca436eb5630172ce84ec41Andreas Huber
9572961230a5890071bcca436eb5630172ce84ec41Andreas Huber            if (mThread != NULL || mRunningLocally) {
9672961230a5890071bcca436eb5630172ce84ec41Andreas Huber                return INVALID_OPERATION;
9772961230a5890071bcca436eb5630172ce84ec41Andreas Huber            }
9872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
9972961230a5890071bcca436eb5630172ce84ec41Andreas Huber            mRunningLocally = true;
10072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
10172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
10272961230a5890071bcca436eb5630172ce84ec41Andreas Huber        do {
10372961230a5890071bcca436eb5630172ce84ec41Andreas Huber        } while (loop());
10472961230a5890071bcca436eb5630172ce84ec41Andreas Huber
10572961230a5890071bcca436eb5630172ce84ec41Andreas Huber        return OK;
10672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
10772961230a5890071bcca436eb5630172ce84ec41Andreas Huber
10872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
10972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
11072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (mThread != NULL || mRunningLocally) {
11172961230a5890071bcca436eb5630172ce84ec41Andreas Huber        return INVALID_OPERATION;
11272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
11372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
11442d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huber    mThread = new LooperThread(this, canCallJava);
11572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
116a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber    status_t err = mThread->run(
117a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber            mName.empty() ? "ALooper" : mName.c_str(), priority);
11872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (err != OK) {
11972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mThread.clear();
12072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
12172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
12272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return err;
12372961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
12472961230a5890071bcca436eb5630172ce84ec41Andreas Huber
12572961230a5890071bcca436eb5630172ce84ec41Andreas Huberstatus_t ALooper::stop() {
12672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    sp<LooperThread> thread;
12772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    bool runningLocally;
12872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
12972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    {
13072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        Mutex::Autolock autoLock(mLock);
13172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
13272961230a5890071bcca436eb5630172ce84ec41Andreas Huber        thread = mThread;
13372961230a5890071bcca436eb5630172ce84ec41Andreas Huber        runningLocally = mRunningLocally;
13472961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mThread.clear();
13572961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mRunningLocally = false;
13672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
13772961230a5890071bcca436eb5630172ce84ec41Andreas Huber
13872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (thread == NULL && !runningLocally) {
13972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        return INVALID_OPERATION;
14072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
14172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
14272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (thread != NULL) {
14372961230a5890071bcca436eb5630172ce84ec41Andreas Huber        thread->requestExit();
14472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
14572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
14672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    mQueueChangedCondition.signal();
14772961230a5890071bcca436eb5630172ce84ec41Andreas Huber
148f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber    if (!runningLocally && !thread->isCurrentThread()) {
149f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber        // If not running locally and this thread _is_ the looper thread,
150f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber        // the loop() function will return and never be called again.
15172961230a5890071bcca436eb5630172ce84ec41Andreas Huber        thread->requestExitAndWait();
15272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
15372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
15472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return OK;
15572961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
15672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
15772961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::post(const sp<AMessage> &msg, int64_t delayUs) {
15872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
15972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
16072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    int64_t whenUs;
16172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (delayUs > 0) {
16272961230a5890071bcca436eb5630172ce84ec41Andreas Huber        whenUs = GetNowUs() + delayUs;
16372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    } else {
16472961230a5890071bcca436eb5630172ce84ec41Andreas Huber        whenUs = GetNowUs();
16572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
16672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
16772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    List<Event>::iterator it = mEventQueue.begin();
16872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) {
16972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        ++it;
17072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
17172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
17272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Event event;
17372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    event.mWhenUs = whenUs;
17472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    event.mMessage = msg;
17572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
17672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (it == mEventQueue.begin()) {
17772961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mQueueChangedCondition.signal();
17872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
17972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
18072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    mEventQueue.insert(it, event);
18172961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
18272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
18372961230a5890071bcca436eb5630172ce84ec41Andreas Huberbool ALooper::loop() {
18472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Event event;
18572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
18672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    {
18772961230a5890071bcca436eb5630172ce84ec41Andreas Huber        Mutex::Autolock autoLock(mLock);
18872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        if (mThread == NULL && !mRunningLocally) {
18972961230a5890071bcca436eb5630172ce84ec41Andreas Huber            return false;
19072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
19172961230a5890071bcca436eb5630172ce84ec41Andreas Huber        if (mEventQueue.empty()) {
19272961230a5890071bcca436eb5630172ce84ec41Andreas Huber            mQueueChangedCondition.wait(mLock);
19372961230a5890071bcca436eb5630172ce84ec41Andreas Huber            return true;
19472961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
19572961230a5890071bcca436eb5630172ce84ec41Andreas Huber        int64_t whenUs = (*mEventQueue.begin()).mWhenUs;
19672961230a5890071bcca436eb5630172ce84ec41Andreas Huber        int64_t nowUs = GetNowUs();
19772961230a5890071bcca436eb5630172ce84ec41Andreas Huber
19872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        if (whenUs > nowUs) {
19972961230a5890071bcca436eb5630172ce84ec41Andreas Huber            int64_t delayUs = whenUs - nowUs;
20072961230a5890071bcca436eb5630172ce84ec41Andreas Huber            mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);
20172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
20272961230a5890071bcca436eb5630172ce84ec41Andreas Huber            return true;
20372961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
20472961230a5890071bcca436eb5630172ce84ec41Andreas Huber
20572961230a5890071bcca436eb5630172ce84ec41Andreas Huber        event = *mEventQueue.begin();
20672961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mEventQueue.erase(mEventQueue.begin());
20772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
20872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
20972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    gLooperRoster.deliverMessage(event.mMessage);
21072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
211f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber    // NOTE: It's important to note that at this point our "ALooper" object
212f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber    // may no longer exist (its final reference may have gone away while
213f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber    // delivering the message). We have made sure, however, that loop()
214f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber    // won't be called again.
215f8be8c0c8055ead961d23b969bf46315eb93e887Andreas Huber
21672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return true;
21772961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
21872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
21972961230a5890071bcca436eb5630172ce84ec41Andreas Huber}  // namespace android
220