ALooper.cpp revision 42d7f83904b8a91ce33e87a44de109572679ac1f
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
7642d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huberstatus_t ALooper::start(bool runOnCallingThread, bool canCallJava) {
7772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (runOnCallingThread) {
7872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        {
7972961230a5890071bcca436eb5630172ce84ec41Andreas Huber            Mutex::Autolock autoLock(mLock);
8072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
8172961230a5890071bcca436eb5630172ce84ec41Andreas Huber            if (mThread != NULL || mRunningLocally) {
8272961230a5890071bcca436eb5630172ce84ec41Andreas Huber                return INVALID_OPERATION;
8372961230a5890071bcca436eb5630172ce84ec41Andreas Huber            }
8472961230a5890071bcca436eb5630172ce84ec41Andreas Huber
8572961230a5890071bcca436eb5630172ce84ec41Andreas Huber            mRunningLocally = true;
8672961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
8772961230a5890071bcca436eb5630172ce84ec41Andreas Huber
8872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        do {
8972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        } while (loop());
9072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
9172961230a5890071bcca436eb5630172ce84ec41Andreas Huber        return OK;
9272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
9372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
9472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
9572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
9672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (mThread != NULL || mRunningLocally) {
9772961230a5890071bcca436eb5630172ce84ec41Andreas Huber        return INVALID_OPERATION;
9872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
9972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
10042d7f83904b8a91ce33e87a44de109572679ac1fAndreas Huber    mThread = new LooperThread(this, canCallJava);
10172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
10272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    status_t err = mThread->run("ALooper");
10372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (err != OK) {
10472961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mThread.clear();
10572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
10672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
10772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return err;
10872961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
10972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
11072961230a5890071bcca436eb5630172ce84ec41Andreas Huberstatus_t ALooper::stop() {
11172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    sp<LooperThread> thread;
11272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    bool runningLocally;
11372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
11472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    {
11572961230a5890071bcca436eb5630172ce84ec41Andreas Huber        Mutex::Autolock autoLock(mLock);
11672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
11772961230a5890071bcca436eb5630172ce84ec41Andreas Huber        thread = mThread;
11872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        runningLocally = mRunningLocally;
11972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mThread.clear();
12072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mRunningLocally = false;
12172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
12272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
12372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (thread == NULL && !runningLocally) {
12472961230a5890071bcca436eb5630172ce84ec41Andreas Huber        return INVALID_OPERATION;
12572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
12672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
12772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (thread != NULL) {
12872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        thread->requestExit();
12972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
13072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
13172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    mQueueChangedCondition.signal();
13272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
13372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (!runningLocally) {
13472961230a5890071bcca436eb5630172ce84ec41Andreas Huber        thread->requestExitAndWait();
13572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
13672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
13772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return OK;
13872961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
13972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
14072961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooper::post(const sp<AMessage> &msg, int64_t delayUs) {
14172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
14272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
14372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    int64_t whenUs;
14472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (delayUs > 0) {
14572961230a5890071bcca436eb5630172ce84ec41Andreas Huber        whenUs = GetNowUs() + delayUs;
14672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    } else {
14772961230a5890071bcca436eb5630172ce84ec41Andreas Huber        whenUs = GetNowUs();
14872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
14972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
15072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    List<Event>::iterator it = mEventQueue.begin();
15172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) {
15272961230a5890071bcca436eb5630172ce84ec41Andreas Huber        ++it;
15372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
15472961230a5890071bcca436eb5630172ce84ec41Andreas Huber
15572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Event event;
15672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    event.mWhenUs = whenUs;
15772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    event.mMessage = msg;
15872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
15972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (it == mEventQueue.begin()) {
16072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mQueueChangedCondition.signal();
16172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
16272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
16372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    mEventQueue.insert(it, event);
16472961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
16572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
16672961230a5890071bcca436eb5630172ce84ec41Andreas Huberbool ALooper::loop() {
16772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Event event;
16872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
16972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    {
17072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        Mutex::Autolock autoLock(mLock);
17172961230a5890071bcca436eb5630172ce84ec41Andreas Huber        if (mThread == NULL && !mRunningLocally) {
17272961230a5890071bcca436eb5630172ce84ec41Andreas Huber            return false;
17372961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
17472961230a5890071bcca436eb5630172ce84ec41Andreas Huber        if (mEventQueue.empty()) {
17572961230a5890071bcca436eb5630172ce84ec41Andreas Huber            mQueueChangedCondition.wait(mLock);
17672961230a5890071bcca436eb5630172ce84ec41Andreas Huber            return true;
17772961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
17872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        int64_t whenUs = (*mEventQueue.begin()).mWhenUs;
17972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        int64_t nowUs = GetNowUs();
18072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
18172961230a5890071bcca436eb5630172ce84ec41Andreas Huber        if (whenUs > nowUs) {
18272961230a5890071bcca436eb5630172ce84ec41Andreas Huber            int64_t delayUs = whenUs - nowUs;
18372961230a5890071bcca436eb5630172ce84ec41Andreas Huber            mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);
18472961230a5890071bcca436eb5630172ce84ec41Andreas Huber
18572961230a5890071bcca436eb5630172ce84ec41Andreas Huber            return true;
18672961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
18772961230a5890071bcca436eb5630172ce84ec41Andreas Huber
18872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        event = *mEventQueue.begin();
18972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mEventQueue.erase(mEventQueue.begin());
19072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
19172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
19272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    gLooperRoster.deliverMessage(event.mMessage);
19372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
19472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return true;
19572961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
19672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
19772961230a5890071bcca436eb5630172ce84ec41Andreas Huber}  // namespace android
198