1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
/*
* Copyright 2009, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// This file contains the declaration of the MessageQueue, the class which
// allows external code (clients) to connect via the IMC library to O3D
// (server) and issue calls to it.
#ifndef O3D_CORE_CROSS_MESSAGE_QUEUE_H_
#define O3D_CORE_CROSS_MESSAGE_QUEUE_H_
#include <vector>
#include "native_client/src/shared/imc/nacl_imc.h"
#include "core/cross/types.h"
#include "core/cross/message_commands.h"
namespace o3d {
class ServiceLocator;
class ObjectManager;
// Structure keeping information about shared memory regions created on the
// request of a client connection.
struct SharedMemoryInfo {
// Unique (to the MessageQueue object that created it) id of the shared
// memory buffer.
int buffer_id;
// Handle to the shared memory.
nacl::Handle shared_memory_handle;
// Address to which it maps in the local memory space.
void* mapped_address;
// Size in bytes
int32 size;
};
// The ConnectedClient class holds information about clients that have made
// contact with the this instance of the server.
class ConnectedClient {
public:
explicit ConnectedClient(nacl::Handle handle);
~ConnectedClient();
// Registers a newly created shared memory buffer with the client.
// Parameters:
// id - the unique id of the shared memory buffer.
// handle - the nacl handle to the shared memory.
// address - the beginning of the buffer in the local address space.
// size - the size of the buffer in bytes.
void RegisterSharedMemory(int id,
nacl::Handle handle,
void *address,
int32 size);
// Unregisters a client-allocated shared memory segment, referenced by ID.
// Parameters:
// id - the unique id of the shared memory buffer.
// Returns:
// true if the ID was valid, false otherwise
bool UnregisterSharedMemory(int id);
// Returns the socket handle the client uses to talk to the server.
nacl::Handle client_handle() { return client_handle_; }
// Returns the shared memory record that matches the given buffer id.
const SharedMemoryInfo* GetSharedMemoryInfo(int buffer_id) const;
private:
// Handle of the socket the client uses.
nacl::Handle client_handle_;
std::vector<SharedMemoryInfo> shared_memory_array_;
DISALLOW_COPY_AND_ASSIGN(ConnectedClient);
};
// The MessageQueue class handles the communcation between external code and
// O3D. It provides methods for initializing the communcation channel
// as well as reading data from and writing data to it. It is currently using
// the NativeClient Inter-Module Communication (IMC) library.
class MessageQueue {
public:
// Creates a MessageQueue that is able to receive messages and execute calls
// to the given Client object.
explicit MessageQueue(ServiceLocator* service_locator);
~MessageQueue();
// Initializes the communcation channel.
// Returns:
// true if the channel was initialized successfully, false otherwise.
bool Initialize();
// Checks for new messages on the queue. If messages are found then it
// it processes them, otherwise it simply returns.
// Returns:
// true if there were no new messages or new messages were succesfully
// received.
bool CheckForNewMessages();
// Returns the socket address used by the message queue.
String GetSocketAddress() const;
private:
// Processes a request from an already connected client. It parses the
// parameters provided in the message and executes the appropriate action.
// Parameters:
// client - pointer to the ConnectedClient the request came from.
// message_length - length of the received message in bytes.
// message_id - id of the request received by the message
// header - message header containing information about the received
// message.
// handles - the array of handles referenced by the header.
// Returns:
// true if the message is properly formed and is succesfully handled by the
// Client.
bool ProcessClientRequest(ConnectedClient* client,
int message_length,
imc::MessageId message_id,
nacl::MessageHeader* header,
nacl::Handle* handles);
// Processes the HELLO message, which initiates a new connection with a
// client.
// Parameters:
// header - message header containing information about the received
// message.
// handles - the array of handles referenced by the header.
// Returns:
// true if the new client connected successfully.
bool ProcessHelloMessage(nacl::MessageHeader* header, nacl::Handle* handles);
// Declare all the message processing functions. For each type of message
// will declare a function called Process<MessageName>.
#define O3D_IMC_MESSAGE_OP(id, class_name) \
bool Process ## class_name( \
ConnectedClient* client, \
int message_length, \
nacl::MessageHeader* header, \
nacl::Handle* handles, \
const class_name::Msg& message);
O3D_IMC_MESSAGE_LIST(O3D_IMC_MESSAGE_OP)
#undef O3D_IMC_MESSAGE_OP
// Sends a true of false (1 or 0) message using the given socket handle.
// Parameters:
// client_handle - handle of socket to send the response to.
// value - value to send.
// Returns:
// true on success.
bool SendBooleanResponse(nacl::Handle client_handle, bool value);
// Checks a socket for a message without blocking waiting for one. If a
// valid message is found then it returns the message id.
// Parameters:
// socket - socket to check for messages.
// header - pointer to the message header used for receiving the message.
// message_id [out] - the ID of the message received.
// message_length [out] - the length of the message received.
// Returns:
// true if a message with a valid ID is found. true if no message is found.
// false in every other case.
bool ReceiveMessageFromSocket(nacl::Handle socket,
nacl::MessageHeader* header,
imc::MessageId* message_id,
int* message_length);
ServiceLocator* service_locator_;
ObjectManager* object_manager_;
// A list of clients that are communicating via the message queue.
std::vector<ConnectedClient*> connected_clients_;
// Handle of server (i.e. O3D) bound socket.
nacl::Handle server_socket_handle_;
// Address of the server socket used by this MessageQueue.
nacl::SocketAddress server_socket_address_;
// Stores the next available unique id that can be assigned to a newly
// created shared memory buffer.
int32 next_shared_memory_id_;
// Stores the next available unique id for message queues. This allows
// us to create multiple instances of the MessageQueue, each with a unique
// address.
static int next_message_queue_id_;
DISALLOW_COPY_AND_ASSIGN(MessageQueue);
};
} // namespace o3d
#endif // O3D_CORE_CROSS_MESSAGE_QUEUE_H_
|