1 // Copyright (c) 2006-2008 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.
5 #ifndef SANDBOX_SRC_SHAREDMEM_IPC_CLIENT_H__
6 #define SANDBOX_SRC_SHAREDMEM_IPC_CLIENT_H__
8 #include "sandbox/win/src/crosscall_params.h"
9 #include "sandbox/win/src/sandbox.h"
11 // IPC transport implementation that uses shared memory.
12 // This is the client side
14 // The shared memory is divided on blocks called channels, and potentially
15 // it can perform as many concurrent IPC calls as channels. The IPC over
16 // each channel is strictly synchronous for the client.
18 // Each channel as a channel control section associated with. Each control
19 // section has two kernel events (known as ping and pong) and a integer
20 // variable that maintains a state
22 // this is the state diagram of a channel:
25 // kFreeChannel---------->BusyChannel-------------->kAckChannel
27 // |_________________________________________________|
30 // The protocol is as follows:
31 // 1) client finds a free channel: state = kFreeChannel
32 // 2) does an atomic compare-and-swap, now state = BusyChannel
33 // 3) client writes the data into the channel buffer
34 // 4) client signals the ping event and waits (blocks) on the pong event
35 // 5) eventually the server signals the pong event
36 // 6) the client awakes and reads the answer from the same channel
37 // 7) the client updates its InOut parameters with the new data from the
38 // shared memory section.
39 // 8) the client atomically sets the state = kFreeChannel
41 // In the shared memory the layout is as follows:
44 // [ channel control 0]
45 // [ channel control 1]
46 // [ channel control N]
47 // [ channel buffer 0 ] 1024 bytes
48 // [ channel buffer 1 ] 1024 bytes
49 // [ channel buffer N ] 1024 bytes
51 // By default each channel buffer is 1024 bytes
54 // the possible channel states as described above
58 // IPC in progress client side
60 // IPC in progress server side
64 // IPC abandoned by client side
68 // The next two constants control the time outs for the IPC.
69 const DWORD kIPCWaitTimeOut1
= 1000; // Milliseconds.
70 const DWORD kIPCWaitTimeOut2
= 50; // Milliseconds.
72 // the channel control structure
73 struct ChannelControl
{
74 // points to be beginning of the channel buffer, where data goes
76 // maintains the state from the ChannelState enumeration
78 // the ping event is signaled by the client when the IPC data is ready on
81 // the client waits on the pong event for the IPC answer back
83 // the IPC unique identifier
88 // total number of channels available, some might be busy at a given time
89 size_t channels_count
;
90 // handle to a shared mutex to detect when the server is dead
92 // array of channel control structures
93 ChannelControl channels
[1];
96 // the actual shared memory IPC implementation class. This object is designed
97 // to be lightweight so it can be constructed on-site (at the calling place)
98 // wherever an IPC call is needed.
99 class SharedMemIPCClient
{
101 // Creates the IPC client.
102 // as parameter it takes the base address of the shared memory
103 explicit SharedMemIPCClient(void* shared_mem
);
105 // locks a free channel and returns the channel buffer memory base. This call
106 // blocks until there is a free channel
109 // releases the lock on the channel, for other to use. call this if you have
110 // called GetBuffer and you want to abort but have not called yet DoCall()
111 void FreeBuffer(void* buffer
);
113 // Performs the actual IPC call.
114 // params: The blob of packed input parameters.
115 // answer: upon IPC completion, it contains the server answer to the IPC.
116 // If the return value is not SBOX_ERROR_CHANNEL_ERROR, the caller has to free
118 // returns ALL_OK if the IPC mechanism successfully delivered. You still need
119 // to check on the answer structure to see the actual IPC result.
120 ResultCode
DoCall(CrossCallParams
* params
, CrossCallReturn
* answer
);
123 // Returns the index of the first free channel. It sets 'severe_failure'
124 // to true if there is an unrecoverable error that does not allow to
126 size_t LockFreeChannel(bool* severe_failure
);
127 // Return the channel index given the address of the buffer.
128 size_t ChannelIndexFromBuffer(const void* buffer
);
129 IPCControl
* control_
;
130 // point to the first channel base
134 } // namespace sandbox
136 #endif // SANDBOX_SRC_SHAREDMEM_IPC_CLIENT_H__