1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MOJO_CORE_PORTS_MESSAGE_QUEUE_H_
6 #define MOJO_CORE_PORTS_MESSAGE_QUEUE_H_
7
8 #include <stdint.h>
9
10 #include <limits>
11 #include <memory>
12 #include <vector>
13
14 #include "base/component_export.h"
15 #include "base/macros.h"
16 #include "mojo/core/ports/event.h"
17
18 namespace mojo {
19 namespace core {
20 namespace ports {
21
22 constexpr uint64_t kInitialSequenceNum = 1;
23 constexpr uint64_t kInvalidSequenceNum = std::numeric_limits<uint64_t>::max();
24
25 class MessageFilter;
26
27 // An incoming message queue for a port. MessageQueue keeps track of the highest
28 // known sequence number and can indicate whether the next sequential message is
29 // available. Thus the queue enforces message ordering for the consumer without
30 // enforcing it for the producer (see AcceptMessage() below.)
COMPONENT_EXPORT(MOJO_CORE_PORTS)31 class COMPONENT_EXPORT(MOJO_CORE_PORTS) MessageQueue {
32 public:
33 explicit MessageQueue();
34 explicit MessageQueue(uint64_t next_sequence_num);
35 ~MessageQueue();
36
37 void set_signalable(bool value) { signalable_ = value; }
38
39 uint64_t next_sequence_num() const { return next_sequence_num_; }
40
41 bool HasNextMessage() const;
42
43 // Gives ownership of the message. If |filter| is non-null, the next message
44 // will only be retrieved if the filter successfully matches it.
45 void GetNextMessage(std::unique_ptr<UserMessageEvent>* message,
46 MessageFilter* filter);
47
48 // Takes ownership of the message. Note: Messages are ordered, so while we
49 // have added a message to the queue, we may still be waiting on a message
50 // ahead of this one before we can let any of the messages be returned by
51 // GetNextMessage.
52 //
53 // Furthermore, once has_next_message is set to true, it will remain false
54 // until GetNextMessage is called enough times to return a null message.
55 // In other words, has_next_message acts like an edge trigger.
56 //
57 void AcceptMessage(std::unique_ptr<UserMessageEvent> message,
58 bool* has_next_message);
59
60 // Takes all messages from this queue. Used to safely destroy queued messages
61 // without holding any Port lock.
62 void TakeAllMessages(
63 std::vector<std::unique_ptr<UserMessageEvent>>* messages);
64
65 // The number of messages queued here, regardless of whether the next expected
66 // message has arrived yet.
67 size_t queued_message_count() const { return heap_.size(); }
68
69 // The aggregate memory size in bytes of all messages queued here, regardless
70 // of whether the next expected message has arrived yet.
71 size_t queued_num_bytes() const { return total_queued_bytes_; }
72
73 private:
74 std::vector<std::unique_ptr<UserMessageEvent>> heap_;
75 uint64_t next_sequence_num_;
76 bool signalable_ = true;
77 size_t total_queued_bytes_ = 0;
78
79 DISALLOW_COPY_AND_ASSIGN(MessageQueue);
80 };
81
82 } // namespace ports
83 } // namespace core
84 } // namespace mojo
85
86 #endif // MOJO_CORE_PORTS_MESSAGE_QUEUE_H_
87