120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#undef __STRICT_ANSI__
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define __STDINT_LIMITS
19361f482fd229c4d0b683d04c93b9da4ab01660b7Marco Nelissen#define __STDC_LIMIT_MACROS
2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h>
2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber//#define LOG_NDEBUG 0
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "TimedEventQueue"
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
2517e8ad9c4b8fbdebec4559702b82114fb6543b67Marco Nelissen#include <utils/threads.h>
2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2789e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/TimedEventQueue.h"
2889e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
2903f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber#include <sys/prctl.h>
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <sys/time.h>
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
33af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber#include <media/stagefright/foundation/ALooper.h>
3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberTimedEventQueue::TimedEventQueue()
38be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    : mNextEventID(1),
39be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber      mRunning(false),
4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mStopped(false) {
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberTimedEventQueue::~TimedEventQueue() {
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    stop();
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid TimedEventQueue::start() {
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mRunning) {
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return;
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStopped = false;
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    pthread_attr_t attr;
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    pthread_attr_init(&attr);
5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    pthread_create(&mThread, &attr, ThreadWrapper, this);
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    pthread_attr_destroy(&attr);
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mRunning = true;
6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid TimedEventQueue::stop(bool flush) {
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!mRunning) {
6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return;
6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (flush) {
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        postEventToBack(new StopEvent);
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        postTimedEvent(new StopEvent, INT64_MIN);
7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    void *dummy;
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    pthread_join(mThread, &dummy);
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mQueue.clear();
8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mRunning = false;
8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
84be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas HuberTimedEventQueue::event_id TimedEventQueue::postEvent(const sp<Event> &event) {
8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    // Reserve an earlier timeslot an INT64_MIN to be able to post
8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    // the StopEvent to the absolute head of the queue.
87be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    return postTimedEvent(event, INT64_MIN + 1);
8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
90be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas HuberTimedEventQueue::event_id TimedEventQueue::postEventToBack(
91be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        const sp<Event> &event) {
92be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    return postTimedEvent(event, INT64_MAX);
9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
95be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas HuberTimedEventQueue::event_id TimedEventQueue::postEventWithDelay(
9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const sp<Event> &event, int64_t delay_us) {
970c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(delay_us >= 0);
98af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber    return postTimedEvent(event, ALooper::GetNowUs() + delay_us);
9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
101be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas HuberTimedEventQueue::event_id TimedEventQueue::postTimedEvent(
10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const sp<Event> &event, int64_t realtime_us) {
10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
105be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    event->setEventID(mNextEventID++);
106be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    List<QueueItem>::iterator it = mQueue.begin();
10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (it != mQueue.end() && realtime_us >= (*it).realtime_us) {
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        ++it;
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    QueueItem item;
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    item.event = event;
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    item.realtime_us = realtime_us;
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (it == mQueue.begin()) {
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mQueueHeadChangedCondition.signal();
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mQueue.insert(it, item);
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mQueueNotEmptyCondition.signal();
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
124be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    return event->eventID();
125be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber}
12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
127be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huberstatic bool MatchesEventID(
128be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        void *cookie, const sp<TimedEventQueue::Event> &event) {
129be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    TimedEventQueue::event_id *id =
130be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        static_cast<TimedEventQueue::event_id *>(cookie);
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
132be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    if (event->eventID() != *id) {
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
136be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    *id = 0;
13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return true;
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
141be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huberbool TimedEventQueue::cancelEvent(event_id id) {
142bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (id == 0) {
143bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return false;
144bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
145be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
146be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    cancelEvents(&MatchesEventID, &id, true /* stopAfterFirstMatch */);
147be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
148be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    // if MatchesEventID found a match, it will have set id to 0
149be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    // (which is not a valid event_id).
150be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
151be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    return id == 0;
152be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber}
153be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
154be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Hubervoid TimedEventQueue::cancelEvents(
155be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        bool (*predicate)(void *cookie, const sp<Event> &event),
156be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        void *cookie,
157be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        bool stopAfterFirstMatch) {
158be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    Mutex::Autolock autoLock(mLock);
159be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
160be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    List<QueueItem>::iterator it = mQueue.begin();
161be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    while (it != mQueue.end()) {
162be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        if (!(*predicate)(cookie, (*it).event)) {
163be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber            ++it;
164be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber            continue;
165be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        }
166be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
167be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        if (it == mQueue.begin()) {
168be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber            mQueueHeadChangedCondition.signal();
169be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        }
170be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
1713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("cancelling event %d", (*it).event->eventID());
172874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber
173bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        (*it).event->setEventID(0);
174be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        it = mQueue.erase(it);
175be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
176be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        if (stopAfterFirstMatch) {
177be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber            return;
178be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber        }
179be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber    }
180be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber}
181be11f392a8b8ff1006cf536350cc8a85f8788ff4Andreas Huber
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid *TimedEventQueue::ThreadWrapper(void *me) {
1840df82fcf56668bbde355cac7fb0828368441f6dcMarco Nelissen
18586106f8b0641444c97a39e9788eeef55ab2a2ac6Glenn Kasten    androidSetThreadPriority(0, ANDROID_PRIORITY_FOREGROUND);
186acb5621440968ddf62651a2e6c1ddb69cf675972Andreas Huber
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    static_cast<TimedEventQueue *>(me)->threadEntry();
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return NULL;
19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid TimedEventQueue::threadEntry() {
19303f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber    prctl(PR_SET_NAME, (unsigned long)"TimedEventQueue", 0, 0, 0);
19403f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (;;) {
19603f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber        int64_t now_us = 0;
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        sp<Event> event;
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            Mutex::Autolock autoLock(mLock);
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (mStopped) {
20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                break;
20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (mQueue.empty()) {
20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mQueueNotEmptyCondition.wait(mLock);
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
210874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            event_id eventID = 0;
21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            for (;;) {
21203f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                if (mQueue.empty()) {
21303f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    // The only event in the queue could have been cancelled
21403f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    // while we were waiting for its scheduled time.
21503f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    break;
21603f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                }
217874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber
218874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber                List<QueueItem>::iterator it = mQueue.begin();
219874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber                eventID = (*it).event->eventID();
22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
221af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber                now_us = ALooper::GetNowUs();
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                int64_t when_us = (*it).realtime_us;
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                int64_t delay_us;
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (when_us < 0 || when_us == INT64_MAX) {
22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    delay_us = 0;
22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                } else {
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    delay_us = when_us - now_us;
22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (delay_us <= 0) {
23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    break;
23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23503f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                static int64_t kMaxTimeoutUs = 10000000ll;  // 10 secs
23603f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                bool timeoutCapped = false;
23703f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                if (delay_us > kMaxTimeoutUs) {
2385ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW("delay_us exceeds max timeout: %lld us", delay_us);
23903f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber
24003f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    // We'll never block for more than 10 secs, instead
24103f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    // we will split up the full timeout into chunks of
24203f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    // 10 secs at a time. This will also avoid overflow
24303f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    // when converting from us to ns.
24403f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    delay_us = kMaxTimeoutUs;
24503f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    timeoutCapped = true;
24603f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                }
24703f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber
24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = mQueueHeadChangedCondition.waitRelative(
24903f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                        mLock, delay_us * 1000ll);
25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25103f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                if (!timeoutCapped && err == -ETIMEDOUT) {
25203f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    // We finally hit the time this event is supposed to
25303f4e14ec612d53b5e2b987555b24afcbbe319d1Andreas Huber                    // trigger.
254af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber                    now_us = ALooper::GetNowUs();
25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    break;
25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
259874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            // The event w/ this id may have been cancelled while we're
260874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            // waiting for its trigger-time, in that case
261874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            // removeEventFromQueue_l will return NULL.
262874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            // Otherwise, the QueueItem will be removed
263874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            // from the queue and the referenced event returned.
264874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            event = removeEventFromQueue_l(eventID);
265874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber        }
266874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber
267874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber        if (event != NULL) {
268874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            // Fire event with the lock NOT held.
269874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            event->fire(this, now_us);
270874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber        }
271874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber    }
272874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber}
273bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
274874b55f51c4c062c65aee043ec0f26044b504556Andreas Hubersp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l(
275874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber        event_id id) {
276874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber    for (List<QueueItem>::iterator it = mQueue.begin();
277874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber         it != mQueue.end(); ++it) {
278874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber        if ((*it).event->eventID() == id) {
279874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            sp<Event> event = (*it).event;
280bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            event->setEventID(0);
281874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber
28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mQueue.erase(it);
28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
284874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber            return event;
285874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber        }
28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
287874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber
2885ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW("Event %d was not found in the queue, already cancelled?", id);
289874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber
290874b55f51c4c062c65aee043ec0f26044b504556Andreas Huber    return NULL;
29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
295