MessageQueue.cpp revision f1d8e87b09abf963cd5b6a026194c1940fadb7b4
1f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian/* 2f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * Copyright (C) 2009 The Android Open Source Project 3f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * 4f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * you may not use this file except in compliance with the License. 6f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * You may obtain a copy of the License at 7f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * 8f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * 10f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * Unless required by applicable law or agreed to in writing, software 11f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * See the License for the specific language governing permissions and 14f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * limitations under the License. 15f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian */ 16f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 17f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <stdint.h> 18f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <errno.h> 19f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <sys/types.h> 20f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 21f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <utils/threads.h> 22f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <utils/Timers.h> 23f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <utils/Log.h> 24f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <utils/IPCThreadState.h> 25f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 26f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include "MessageQueue.h" 27f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 28f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopiannamespace android { 29f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 30f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian// --------------------------------------------------------------------------- 31f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 32f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias AgopianMessageQueue::MessageQueue() 33f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{ 34f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mInvalidateMessage = new MessageBase(INVALIDATE); 35f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian} 36f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 37f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias AgopianMessageQueue::~MessageQueue() 38f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{ 39f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian} 40f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 41f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias AgopianMessageList::NODE_PTR MessageQueue::waitMessage(nsecs_t timeout) 42f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{ 43f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian MessageList::NODE_PTR result; 44f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian bool again; 45f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian do { 46f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const nsecs_t timeoutTime = systemTime() + timeout; 47f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian while (true) { 48f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian Mutex::Autolock _l(mLock); 49f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t now = systemTime(); 50f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t nextEventTime = -1; 51f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 52f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // invalidate messages are always handled first 53f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (mInvalidate) { 54f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mInvalidate = false; 55f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mInvalidateMessage->when = now; 56f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian result = mInvalidateMessage; 57f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian break; 58f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 59f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 60f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian result = mMessages.head(); 61f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 62f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (result != 0) { 63f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (result->when <= now) { 64f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // there is a message to deliver 65f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mMessages.remove(result); 66f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian result->detach(); 67f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian break; 68f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 69f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (timeout>=0 && timeoutTime < now) { 70f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // we timed-out, return a NULL message 71f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian result = 0; 72f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian break; 73f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 74f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nextEventTime = result->when; 75f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian result = 0; 76f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 77f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 78f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (timeout >= 0 && nextEventTime > 0) { 79f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (nextEventTime > timeoutTime) { 80f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nextEventTime = timeoutTime; 81f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 82f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 83f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 84f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (nextEventTime >= 0) { 85f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian //LOGD("nextEventTime = %lld ms", nextEventTime); 86f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (nextEventTime > 0) { 87f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // we're about to wait, flush the binder command buffer 88f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian IPCThreadState::self()->flushCommands(); 89f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mCondition.wait(mLock, nextEventTime); 90f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 91f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } else { 92f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian //LOGD("going to wait"); 93f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // we're about to wait, flush the binder command buffer 94f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian IPCThreadState::self()->flushCommands(); 95f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mCondition.wait(mLock); 96f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 97f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 98f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // here we're not holding the lock anymore 99f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 100f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (result == 0) 101f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian break; 102f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 103f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian again = result->handler(); 104f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (again) { 105f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // the message has been processed. release our reference to it 106f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // without holding the lock. 107f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian result = 0; 108f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 109f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 110f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } while (again); 111f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian return result; 112f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian} 113f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 114f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopianstatus_t MessageQueue::postMessage( 115f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const MessageList::NODE_PTR& message, nsecs_t relTime, uint32_t flags) 116f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{ 117f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian return queueMessage(message, relTime, flags); 118f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian} 119f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 120f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopianstatus_t MessageQueue::invalidate() { 121f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian Mutex::Autolock _l(mLock); 122f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mInvalidate = true; 123f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mCondition.signal(); 124f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian return NO_ERROR; 125f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian} 126f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 127f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopianstatus_t MessageQueue::queueMessage( 128f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const MessageList::NODE_PTR& message, nsecs_t relTime, uint32_t flags) 129f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{ 130f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian Mutex::Autolock _l(mLock); 131f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian message->when = systemTime() + relTime; 132f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mMessages.insert(message); 133f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 134f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian //LOGD("MessageQueue::queueMessage time = %lld ms", message->when); 135f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian //dumpLocked(message); 136f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 137f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mCondition.signal(); 138f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian return NO_ERROR; 139f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian} 140f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 141f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopianvoid MessageQueue::dump(const MessageList::NODE_PTR& message) 142f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{ 143f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian Mutex::Autolock _l(mLock); 144f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian dumpLocked(message); 145f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian} 146f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 147f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopianvoid MessageQueue::dumpLocked(const MessageList::NODE_PTR& message) 148f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{ 149f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian MessageList::NODE_PTR l(mMessages.head()); 150f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian int c = 0; 151f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian while (l != 0) { 152f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const char tick = (l == message) ? '>' : ' '; 153f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian LOGD("%c %d: msg{.what=%08x, when=%lld}", tick, c, l->what, l->when); 154f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian l = l->getNext(); 155f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian c++; 156f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 157f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian} 158f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 159f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian// --------------------------------------------------------------------------- 160f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 161f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}; // namespace android 162