Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: media/audio/shared_mem_synchronizer.h

Issue 9605015: Add a SharedMemSynchronizer class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address review comments from Ami Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 MEDIA_AUDIO_SHARED_MEM_SYNCHRONIZER_H_
6 #define MEDIA_AUDIO_SHARED_MEM_SYNCHRONIZER_H_
7
8 #include <vector>
9
10 #include "base/basictypes.h"
11 #include "base/process.h"
12 #include "media/base/media_export.h"
13
14 #if defined(OS_WIN)
15 #include "base/win/scoped_handle.h"
16 #else
17 #include "base/file_descriptor_posix.h"
18 #include "base/sync_socket.h"
19 #endif
20
21 // A mechanism to synchronize access to a shared memory segment between
22 // two parties when the usage pattern resembles that of two players playing
23 // a game of chess. Each end has an instance of SharedMemSynchronizer and
24 // calls Signal() when it has finished reading from/writing to the shared
25 // memory section. Before accessing the memory, it must call Wait() in order
26 // to know when the other end has called Signal().
27 //
28 // Here's some pseudo code for how this class can be used:
29 //
30 // This method is used by both processes as it's a general way to access the
31 // shared memory section, write to it and then grant the privilege to the
32 // other process:
33 //
34 // void WriteToSharedMemory(SharedMemSynchronizer* synchronizer,
35 // SharedMemory* mem,
36 // const char my_char) {
37 // synchronizer->Wait(); // Wait for the other process to yield access.
38 // reinterpret_cast<char*>(mem->memory())[0] = my_char;
39 // synchronizer->Signal(); // Grant the other process access.
40 // }
41 //
42 // Process A:
43 //
44 // class A {
45 // public:
46 // void Initialize(base::ProcessHandle process_b) {
47 // mem_.CreateNamed("foo", false, 1024);
48 //
49 // SharedMemSynchronizer b;
50 // CHECK(SharedMemSynchronizer::InitializePair(&synchronizer_, &b));
51 // SharedMemSynchronizer::IPCHandle handle_1, handle_2;
52 // CHECK(b.ShareToProcess(process_b, &handle_1, &handle_2));
53 // // This could be implemented by using some IPC mechanism
54 // // such as MessageLoop.
55 // SendToProcessB(mem_, handle_1, handle_2);
56 // // Allow process B the first chance to write to the memory:
57 // synchronizer_.Signal();
58 // // Once B is done, we'll write 'A' to the shared memory.
59 // WriteToSharedMemory(&synchronizer_, &mem_, 'A');
60 // }
61 //
62 // SharedMemSynchronizer synchronizer_;
63 // SharedMemory mem_;
64 // };
65 //
66 // Process B:
67 //
68 // class B {
69 // public:
70 // // Called when we receive the IPC message from A.
71 // void Initialize(SharedMemoryHandle mem,
72 // SharedMemSynchronizer::IPCHandle handle_1,
73 // SharedMemSynchronizer::IPCHandle handle_2) {
74 // mem_.reset(new SharedMemory(mem, false));
75 // synchronizer_.reset(new SharedMemSynchronizer(handle_1, handle_2));
76 // WriteToSharedMemory(&synchronizer_, &mem_, 'B');
77 // }
78 //
79 // SharedMemSynchronizer synchronizer_;
80 // scoped_ptr<SharedMemory> mem_;
81 // };
82 //
83 class MEDIA_EXPORT SharedMemSynchronizer {
84 public:
85 #if defined(OS_WIN)
86 typedef HANDLE IPCHandle;
87 #else
88 typedef base::FileDescriptor IPCHandle;
89 #endif
90
91 typedef std::vector<SharedMemSynchronizer*> SynchronizerVector;
92
93 // Default ctor. Initializes a NULL synchronizer. User must call
94 // InitializePair() to initialize the instance along with a connected one.
95 SharedMemSynchronizer();
96
97 // Ctor for the user that does not call InitializePair but instead receives
98 // handles from the one that did. These handles come from a call to
99 // ShareToProcess.
100 SharedMemSynchronizer(IPCHandle handle_1, IPCHandle handle_2);
101 ~SharedMemSynchronizer();
102
103 // Raises a signal that the shared memory now can be accessed by the
104 // other party.
105 void Signal();
Ami GONE FROM CHROMIUM 2012/03/13 20:08:02 My point about blocking was that if a single synch
tommi (sloooow) - chröme 2012/03/14 13:32:43 Thanks. I added documentation to make that clear.
106
107 // Waits for the other party to finish using the shared memory.
108 void Wait();
109
110 bool IsValid() const;
111
112 // Copies the internal handles to the output parameters, |handle_1| and
113 // |handle_2|. The operation can fail, so the caller must be prepared to
114 // handle that case.
115 bool ShareToProcess(base::ProcessHandle process, IPCHandle* handle_1,
116 IPCHandle* handle_2);
117
118 // Initializes a pair of SharedMemSynchronizer instances. Note that this can
119 // fail (e.g. due to EMFILE on Linux), so the caller must handle that case.
120 static bool InitializePair(SharedMemSynchronizer* a,
121 SharedMemSynchronizer* b);
122
123 // Use an instance of this class when you have to repeatedly wait
124 // for multiple instances of SharedMemSynchronizer on the same thread.
125 // The class will store information about which synchronizer was last signaled
126 // and try to distribute the signals so that all synchronizers get a chance to
127 // be processed in times of high load and a busy one won't starve the
128 // others.
129 // TODO(tommi): Support a way to abort the wait.
130 class MEDIA_EXPORT WaitForMultiple {
131 public:
132 // Caller must make sure that the lifetime of the array is greater than
133 // that of the WaitForMultiple instance.
134 WaitForMultiple(const SynchronizerVector* synchronizers);
135
136 // Waits for any of the synchronizers to be signaled. Returns the 0 based
137 // index of a signaled synchronizer.
138 int Wait();
139
140 // Call when the array changes.
Ami GONE FROM CHROMIUM 2012/03/13 20:08:02 Doco the effect on outstanding Wait()'s? (namely,
tommi (sloooow) - chröme 2012/03/14 13:32:43 Done.
141 void Reset(const SynchronizerVector* synchronizers);
142
143 private:
144 const SynchronizerVector* synchronizers_;
145 size_t last_;
146 };
147
148 private:
149 // Only called by the WaitForMultiple class. See documentation
150 // for WaitForMultiple and comments inside WaitMultiple for details.
151 static int WaitMultiple(const SynchronizerVector& synchronizers,
152 size_t last_signaled);
153
154 #if defined(OS_WIN)
155 base::win::ScopedHandle mine_;
156 base::win::ScopedHandle other_;
157 #else
158 typedef base::CancelableSyncSocket SocketClass;
159 SocketClass socket_;
160 #endif
161
162 private:
163 DISALLOW_COPY_AND_ASSIGN(SharedMemSynchronizer);
164 };
165
166 #endif // MEDIA_AUDIO_SHARED_MEM_SYNCHRONIZER_H_
OLDNEW
« no previous file with comments | « no previous file | media/audio/shared_mem_synchronizer.cc » ('j') | media/audio/shared_mem_synchronizer.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698