MessageQueue.cpp revision f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdint.h>
18#include <errno.h>
19#include <sys/types.h>
20
21#include <utils/threads.h>
22#include <utils/Timers.h>
23#include <utils/Log.h>
24#include <binder/IPCThreadState.h>
25
26#include "MessageQueue.h"
27
28namespace android {
29
30// ---------------------------------------------------------------------------
31
32MessageBase::MessageBase()
33    : MessageHandler() {
34}
35
36MessageBase::~MessageBase() {
37}
38
39void MessageBase::handleMessage(const Message&) {
40    this->handler();
41    barrier.open();
42};
43
44// ---------------------------------------------------------------------------
45
46MessageQueue::MessageQueue()
47    : mLooper(new Looper(true)),
48      mInvalidatePending(0)
49{
50}
51
52MessageQueue::~MessageQueue() {
53}
54
55void MessageQueue::waitMessage() {
56    do {
57        // handle invalidate events first
58        if (android_atomic_and(0, &mInvalidatePending) != 0)
59            break;
60
61        IPCThreadState::self()->flushCommands();
62
63        int32_t ret = mLooper->pollOnce(-1);
64        switch (ret) {
65            case ALOOPER_POLL_WAKE:
66                // we got woken-up there is work to do in the main loop
67                continue;
68
69            case ALOOPER_POLL_CALLBACK:
70                // callback was handled, loop again
71                continue;
72
73            case ALOOPER_POLL_TIMEOUT:
74                // timeout (should not happen)
75                continue;
76
77            case ALOOPER_POLL_ERROR:
78                LOGE("ALOOPER_POLL_ERROR");
79                continue;
80
81            default:
82                // should not happen
83                LOGE("Looper::pollOnce() returned unknown status %d", ret);
84                continue;
85        }
86    } while (true);
87}
88
89status_t MessageQueue::postMessage(
90        const sp<MessageBase>& messageHandler, nsecs_t relTime)
91{
92    const Message dummyMessage;
93    if (relTime > 0) {
94        mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
95    } else {
96        mLooper->sendMessage(messageHandler, dummyMessage);
97    }
98    return NO_ERROR;
99}
100
101status_t MessageQueue::invalidate() {
102    android_atomic_or(1, &mInvalidatePending);
103    mLooper->wake();
104    return NO_ERROR;
105}
106
107// ---------------------------------------------------------------------------
108
109}; // namespace android
110