143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott/*
243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * Copyright 2010, The Android Open Source Project
343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott *
443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * Redistribution and use in source and binary forms, with or without
543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * modification, are permitted provided that the following conditions
643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * are met:
743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott *  * Redistributions of source code must retain the above copyright
843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott *    notice, this list of conditions and the following disclaimer.
943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott *  * Redistributions in binary form must reproduce the above copyright
1043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott *    notice, this list of conditions and the following disclaimer in the
1143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott *    documentation and/or other materials provided with the distribution.
1243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott *
1343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
1443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
1743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott */
2543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
2643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott#define LOG_TAG "MessageThread"
2743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
2843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott#include "config.h"
2943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
3043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott#include <sys/time.h>
3143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott#include <time.h>
3243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
3343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott#include "MessageThread.h"
3443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott#include "ScriptController.h"
3543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
3643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott#include <utils/Log.h>
3743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
3843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scottnamespace android {
3943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
4043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scottstatic bool compareMessages(const Message& msg1,
4143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott                            const Message& msg2,
4243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott                            bool memberIsNull) {
4343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    return (msg1.object() == msg2.object() &&
4443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            (memberIsNull || msg1.member() == msg2.member()));
4543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott}
4643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
4743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scottbool MessageQueue::hasMessages(const Message& message) {
4843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    AutoMutex lock(m_mutex);
4943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
5043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    static const Message::GenericMemberFunction nullMember = NULL;
5143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    const bool memberIsNull = message.member() == nullMember;
5243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
5343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    for (list<Message*>::iterator it = m_messages.begin();
5443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott         it != m_messages.end(); ++it) {
5543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        Message* m = *it;
5643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        if (compareMessages(message, *m, memberIsNull))
5743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            return true;
5843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    }
5943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    return false;
6043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott}
6143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
6243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scottvoid MessageQueue::remove(const Message& message) {
6343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    AutoMutex lock(m_mutex);
6443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
6543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    static const Message::GenericMemberFunction nullMember = NULL;
6643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    const bool memberIsNull = message.member() == nullMember;
6743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
6843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    for (list<Message*>::iterator it = m_messages.begin();
6943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott         it != m_messages.end(); ++it) {
7043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        Message* m = *it;
7143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        if (compareMessages(message, *m, memberIsNull)) {
7243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            it = m_messages.erase(it);
7343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            delete m;
7443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        }
7543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    }
7643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott}
7743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
7843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scottvoid MessageQueue::post(Message* message) {
7943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    AutoMutex lock(m_mutex);
8043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
8143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    double when = message->m_when;
826dd76b804786ec760bb04b137a6bf017064226dcSteve Block    ALOG_ASSERT(when > 0, "Message time may not be 0");
8343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
8443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    list<Message*>::iterator it;
8543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    for (it = m_messages.begin(); it != m_messages.end(); ++it) {
8643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        Message* m = *it;
8743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        if (when < m->m_when) {
8843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            break;
8943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        }
9043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    }
9143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    m_messages.insert(it, message);
9243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    m_condition.signal();
9343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott}
9443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
9543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scottvoid MessageQueue::postAtFront(Message* message) {
9643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    AutoMutex lock(m_mutex);
9743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    message->m_when = 0;
9843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    m_messages.push_front(message);
9943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott}
10043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
10143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick ScottMessage* MessageQueue::next() {
10243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    AutoMutex lock(m_mutex);
10343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    while (true) {
10443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        if (m_messages.empty()) {
10543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            // No messages, wait until another arrives
10643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            m_condition.wait(m_mutex);
10743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        }
10843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        Message* next = m_messages.front();
10943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        double now = WTF::currentTimeMS();
11043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        double diff = next->m_when - now;
11143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        if (diff > 0) {
11243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            // Not time for this message yet, wait the difference in nanos
11343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            m_condition.waitRelative(m_mutex,
11443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott                    static_cast<nsecs_t>(diff * 1000000) /* nanos */);
11543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        } else {
11643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            // Time for this message to run.
11743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            m_messages.pop_front();
11843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            return next;
11943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        }
12043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    }
12143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott}
12243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
12343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scottbool MessageThread::threadLoop() {
12443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    WebCore::ScriptController::initializeThreading();
12543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
12643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    while (true) {
12743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        Message* message = m_queue.next();
12843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        if (message != NULL) {
12943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott            message->run();
13043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        }
13143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    }
13243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    return false;
13343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott}
13443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
13543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott// Global thread object obtained by messageThread().
13643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scottstatic sp<MessageThread> gMessageThread;
13743fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
13843fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick ScottMessageThread* messageThread() {
13943fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    if (gMessageThread == NULL) {
14043fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        gMessageThread = new MessageThread();
14143fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott        gMessageThread->run("WebCoreThread");
14243fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    }
14343fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott    return gMessageThread.get();
14443fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott}
14543fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott
14643fbbb2aa64694b5006656423cd74e4ab1e65fbaPatrick Scott}  // namespace android
147