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