ALooperRoster.cpp revision 75c672fc376ef9b3ceff61a96513242b0e5ebd60
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 "ALooperRoster"
1972961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include <utils/Log.h>
2072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2172961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "ALooperRoster.h"
2272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2372961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "ADebug.h"
2472961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "AHandler.h"
2572961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "AMessage.h"
2672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2772961230a5890071bcca436eb5630172ce84ec41Andreas Hubernamespace android {
2872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2972961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooperRoster::ALooperRoster()
305df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    : mNextHandlerID(1),
315df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber      mNextReplyID(1) {
3272961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
3372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
3472961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::handler_id ALooperRoster::registerHandler(
3572961230a5890071bcca436eb5630172ce84ec41Andreas Huber        const sp<ALooper> looper, const sp<AHandler> &handler) {
3672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
3772961230a5890071bcca436eb5630172ce84ec41Andreas Huber
3872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (handler->id() != 0) {
3972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        CHECK(!"A handler must only be registered once.");
4072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        return INVALID_OPERATION;
4172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
4272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
4372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    HandlerInfo info;
4472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    info.mLooper = looper;
4572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    info.mHandler = handler;
4672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    ALooper::handler_id handlerID = mNextHandlerID++;
4772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    mHandlers.add(handlerID, info);
4872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
4972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    handler->setID(handlerID);
5072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return handlerID;
5272961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
5372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5472961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
5572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
5672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    ssize_t index = mHandlers.indexOfKey(handlerID);
58f200777290d2e3e8b580c512cc0808eae9790705Andreas Huber
59f200777290d2e3e8b580c512cc0808eae9790705Andreas Huber    if (index < 0) {
60f200777290d2e3e8b580c512cc0808eae9790705Andreas Huber        return;
61f200777290d2e3e8b580c512cc0808eae9790705Andreas Huber    }
6272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
6372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    const HandlerInfo &info = mHandlers.valueAt(index);
6411cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
6511cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    sp<AHandler> handler = info.mHandler.promote();
6611cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
6711cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    if (handler != NULL) {
6811cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        handler->setID(0);
6911cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    }
7072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
7172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    mHandlers.removeItemsAt(index);
7272961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
7372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
7430873bfd08255e2c4e98ff5732ffff2838772617Andreas Hubervoid ALooperRoster::unregisterStaleHandlers() {
7530873bfd08255e2c4e98ff5732ffff2838772617Andreas Huber
7675c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen    Vector<sp<ALooper> > activeLoopers;
7775c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen    {
7875c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen        Mutex::Autolock autoLock(mLock);
7975c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen
8075c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen        for (size_t i = mHandlers.size(); i-- > 0;) {
8175c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen            const HandlerInfo &info = mHandlers.valueAt(i);
8275c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen
8375c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen            sp<ALooper> looper = info.mLooper.promote();
8475c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen            if (looper == NULL) {
8575c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen                ALOGV("Unregistering stale handler %d", mHandlers.keyAt(i));
8675c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen                mHandlers.removeItemsAt(i);
8775c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen            } else {
8875c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen                // At this point 'looper' might be the only sp<> keeping
8975c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen                // the object alive. To prevent it from going out of scope
9075c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen                // and having ~ALooper call this method again recursively
9175c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen                // and then deadlocking because of the Autolock above, add
9275c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen                // it to a Vector which will go out of scope after the lock
9375c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen                // has been released.
9475c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen                activeLoopers.add(looper);
9575c672fc376ef9b3ceff61a96513242b0e5ebd60Marco Nelissen            }
9630873bfd08255e2c4e98ff5732ffff2838772617Andreas Huber        }
9730873bfd08255e2c4e98ff5732ffff2838772617Andreas Huber    }
9830873bfd08255e2c4e98ff5732ffff2838772617Andreas Huber}
9930873bfd08255e2c4e98ff5732ffff2838772617Andreas Huber
1005df775d2f509c76e76a46615fca83dba95299f6eAndreas Huberstatus_t ALooperRoster::postMessage(
10172961230a5890071bcca436eb5630172ce84ec41Andreas Huber        const sp<AMessage> &msg, int64_t delayUs) {
10272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
1035df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    return postMessage_l(msg, delayUs);
1045df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber}
10572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
1065df775d2f509c76e76a46615fca83dba95299f6eAndreas Huberstatus_t ALooperRoster::postMessage_l(
1075df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber        const sp<AMessage> &msg, int64_t delayUs) {
10872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    ssize_t index = mHandlers.indexOfKey(msg->target());
10972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
11072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (index < 0) {
1110df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber        ALOGW("failed to post message '%s'. Target handler not registered.",
1120df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber              msg->debugString().c_str());
1135df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber        return -ENOENT;
11472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
11572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
11672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    const HandlerInfo &info = mHandlers.valueAt(index);
11711cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
11811cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    sp<ALooper> looper = info.mLooper.promote();
11911cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
12011cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    if (looper == NULL) {
1215ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("failed to post message. "
122f200777290d2e3e8b580c512cc0808eae9790705Andreas Huber             "Target handler %d still registered, but object gone.",
123f200777290d2e3e8b580c512cc0808eae9790705Andreas Huber             msg->target());
12411cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
12511cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        mHandlers.removeItemsAt(index);
1265df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber        return -ENOENT;
12711cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    }
12811cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
12911cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    looper->post(msg, delayUs);
1305df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
1315df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    return OK;
13272961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
13372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
13472961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooperRoster::deliverMessage(const sp<AMessage> &msg) {
13572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    sp<AHandler> handler;
13672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
13772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    {
13872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        Mutex::Autolock autoLock(mLock);
13972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
14072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        ssize_t index = mHandlers.indexOfKey(msg->target());
14172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
14272961230a5890071bcca436eb5630172ce84ec41Andreas Huber        if (index < 0) {
1435ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("failed to deliver message. Target handler not registered.");
14472961230a5890071bcca436eb5630172ce84ec41Andreas Huber            return;
14572961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
14672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
14772961230a5890071bcca436eb5630172ce84ec41Andreas Huber        const HandlerInfo &info = mHandlers.valueAt(index);
14811cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        handler = info.mHandler.promote();
14911cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
15011cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        if (handler == NULL) {
1515ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("failed to deliver message. "
152f200777290d2e3e8b580c512cc0808eae9790705Andreas Huber                 "Target handler %d registered, but object gone.",
153f200777290d2e3e8b580c512cc0808eae9790705Andreas Huber                 msg->target());
15411cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
15511cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber            mHandlers.removeItemsAt(index);
15611cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber            return;
15711cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        }
15872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
15972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
16072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    handler->onMessageReceived(msg);
16172961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
16272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
163e2b20987c2652a984d10520ef3542d50d91119c5Andreas Hubersp<ALooper> ALooperRoster::findLooper(ALooper::handler_id handlerID) {
164e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber    Mutex::Autolock autoLock(mLock);
165e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber
166e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber    ssize_t index = mHandlers.indexOfKey(handlerID);
167e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber
168e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber    if (index < 0) {
169e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber        return NULL;
170e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber    }
171e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber
17211cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    sp<ALooper> looper = mHandlers.valueAt(index).mLooper.promote();
17311cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
17411cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    if (looper == NULL) {
17511cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        mHandlers.removeItemsAt(index);
17611cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        return NULL;
17711cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    }
17811cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
17911cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    return looper;
180e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber}
181e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber
1825df775d2f509c76e76a46615fca83dba95299f6eAndreas Huberstatus_t ALooperRoster::postAndAwaitResponse(
1835df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
1845df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    Mutex::Autolock autoLock(mLock);
1855df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
1865df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    uint32_t replyID = mNextReplyID++;
1875df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
1885df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    msg->setInt32("replyID", replyID);
1895df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
1905df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    status_t err = postMessage_l(msg, 0 /* delayUs */);
1915df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
1925df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    if (err != OK) {
1935df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber        response->clear();
1945df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber        return err;
1955df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    }
1965df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
1975df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    ssize_t index;
1985df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    while ((index = mReplies.indexOfKey(replyID)) < 0) {
1995df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber        mRepliesCondition.wait(mLock);
2005df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    }
2015df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
2025df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    *response = mReplies.valueAt(index);
2035df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    mReplies.removeItemsAt(index);
2045df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
2055df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    return OK;
2065df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber}
2075df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
2085df775d2f509c76e76a46615fca83dba95299f6eAndreas Hubervoid ALooperRoster::postReply(uint32_t replyID, const sp<AMessage> &reply) {
2095df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    Mutex::Autolock autoLock(mLock);
2105df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
2115df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    CHECK(mReplies.indexOfKey(replyID) < 0);
2125df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    mReplies.add(replyID, reply);
2135df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber    mRepliesCondition.broadcast();
2145df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber}
2155df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber
21672961230a5890071bcca436eb5630172ce84ec41Andreas Huber}  // namespace android
217