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

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

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

Powered by Google App Engine
This is Rietveld 408576698