示例#1
0
void TestMessageQueue3()
{
    MessageQueue q;

    Uint32 sum = 0;

    for (Uint32 i = 1; i <= 5; i++)
    {
	q.enqueue(new Alarm(i));
	sum += i;
    }
    assert(sum == 15);

    while (!q.isEmpty())
	q.remove(q.back());

    assert(q.getCount() == 0);
}
示例#2
0
void TestMessageQueue1()
{
    MessageQueue q;

    Uint32 sum = 0;

    for (Uint32 i = 1; i <= 5; i++)
    {
	q.enqueue(new Alarm(i));
	sum += i;
    }

    assert(Sum(q) == sum);

    // Test removing from the middle:
    Message* m = q.findByKey(3);
    assert(m != 0);
    q.remove(m);
    assert(Sum(q) == sum - 3);
    assert(q.getCount() == 4);

    // Test removing from the front:
    q.remove(q.front());
    assert(Sum(q) == sum - 3 - 1);
    assert(q.getCount() == 3);

    // Test removing from the front:
    q.remove(q.back());
    assert(Sum(q) == sum - 3 - 1 - 5);
    assert(q.getCount() == 2);

    // Test dequeue:
    m = q.dequeue();
    assert(m->getKey() == 2);
    assert(Sum(q) == sum - 3 - 1 - 5 - 2);
    assert(q.getCount() == 1);

    // Test dequeue:
    m = q.dequeue();
    assert(m->getKey() == 4);
    assert(Sum(q) == sum - 3 - 1 - 5 - 2 - 4);
    assert(q.getCount() == 0);
}
void
RPCChannel::OnMessageReceivedFromLink(const Message& msg)
{
    AssertLinkThread();
    mMonitor->AssertCurrentThreadOwns();

    if (MaybeInterceptSpecialIOMessage(msg))
        return;

    // regardless of the RPC stack, if we're awaiting a sync reply, we
    // know that it needs to be immediately handled to unblock us.
    if (AwaitingSyncReply() && msg.is_sync()) {
        // wake up worker thread waiting at SyncChannel::Send
        mRecvd = msg;
        NotifyWorkerThread();
        return;
    }

    MessageQueue *queue = (msg.priority() == IPC::Message::PRIORITY_HIGH)
                          ? &mUrgent
                          : &mPending;

    bool compressMessage = (msg.compress() && !queue->empty() &&
                            queue->back().type() == msg.type() &&
                            queue->back().routing_id() == msg.routing_id());
    if (compressMessage) {
        // This message type has compression enabled, and the back of
        // the queue was the same message type and routed to the same
        // destination.  Replace it with the newer message.
        MOZ_ASSERT(queue->back().compress());
        queue->pop_back();
    }

    queue->push_back(msg);

    // There are three cases we're concerned about, relating to the state of
    // the main thread:
    //
    // (1) We are waiting on a sync reply - main thread is blocked on the IPC monitor.
    //   - If the message is high priority, we wake up the main thread to
    //     deliver the message. Otherwise, we leave it in the mPending queue,
    //     posting a task to the main event loop, where it will be processed
    //     once the synchronous reply has been received.
    //
    // (2) We are waiting on an RPC reply - main thread is blocked on the IPC monitor.
    //   - Always wake up the main thread to deliver the message.
    //
    // (3) We are not waiting on a reply.
    //   - We post a task to the main event loop.
    //
    bool waiting_rpc = (0 != StackDepth());
    bool urgent = (msg.priority() == IPC::Message::PRIORITY_HIGH);

    if (waiting_rpc || (AwaitingSyncReply() && urgent)) {
        // Always wake up our RPC waiter, and wake up sync waiters for urgent
        // messages.
        NotifyWorkerThread();
    } else {
        // Worker thread is either not blocked on a reply, or this is an
        // incoming RPC that raced with outgoing sync and needs to be deferred
        // to a later event-loop iteration.
        if (!compressMessage) {
            // If we compressed away the previous message, we'll reuse
            // its pending task.
            mWorkerLoop->PostTask(FROM_HERE, new DequeueTask(mDequeueOneTask));
        }
    }
}