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

Side by Side Diff: chrome/common/db_message_filter.h

Issue 1601005: Allow synchronous messages to be sent from threads other than the main thread... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 8 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
« no previous file with comments | « chrome/common/database_util.cc ('k') | chrome/common/db_message_filter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CHROME_COMMON_DB_MESSAGE_FILTER_H_ 5 #ifndef CHROME_COMMON_DB_MESSAGE_FILTER_H_
6 #define CHROME_COMMON_DB_MESSAGE_FILTER_H_ 6 #define CHROME_COMMON_DB_MESSAGE_FILTER_H_
7 7
8 #include "base/atomic_sequence_num.h"
9 #include "base/id_map.h"
10 #include "base/lock.h"
11 #include "base/scoped_ptr.h"
12 #include "base/waitable_event.h"
13 #include "ipc/ipc_channel_proxy.h" 8 #include "ipc/ipc_channel_proxy.h"
14 9
15 class Lock; 10 // Receives database messages from the browser process and processes them on the
16 class MessageLoop; 11 // IO thread.
17
18 namespace IPC {
19 class Channel;
20 }
21
22 // A thread-safe message filter used to send IPCs from DB threads and process
23 // replies from the browser process.
24 //
25 // This class should not be instantianted anywhere but RenderThread::Init(). It
26 // is meant to be a singleton in each renderer process. To access the singleton,
27 // use GetInstance().
28 class DBMessageFilter : public IPC::ChannelProxy::MessageFilter { 12 class DBMessageFilter : public IPC::ChannelProxy::MessageFilter {
29 public: 13 public:
30 // Returns the DBMessageFilter singleton created in this renderer process.
31 static DBMessageFilter* GetInstance() { return instance_; }
32
33 // Creates a new DBMessageFilter instance.
34 DBMessageFilter(); 14 DBMessageFilter();
35 15
36 // Returns a unique ID for use when calling the SendAndWait() method. 16 private:
37 virtual int GetUniqueID();
38
39 // Posts a task to the IO thread to send |message| to the browser.
40 virtual void Send(IPC::Message* message);
41
42 // Sends |message| and blocks the current thread. Returns the result from the
43 // reply message, or |default_result| if the renderer process is being
44 // destroyed or the message could not be sent.
45 template<class ResultType>
46 ResultType SendAndWait(IPC::Message* message,
47 int message_id,
48 ResultType default_result) {
49 ResultType result = default_result;
50 base::WaitableEvent waitable_event(false, false);
51 DBMessageState state =
52 { reinterpret_cast<intptr_t>(&result), &waitable_event };
53 {
54 AutoLock msgs_awaiting_replies_autolock(messages_awaiting_replies_lock_);
55 messages_awaiting_replies_->AddWithID(&state, message_id);
56 }
57
58 Send(message);
59
60 base::WaitableEvent* events[2] = { shutdown_event_, &waitable_event };
61 base::WaitableEvent::WaitMany(events, 2);
62
63 // Locking on messages_awaiting_replies_ guarantees that either the IO
64 // thread won't enter OnResponse(), or if it's already in OnResponse(),
65 // then WaitableEvent::Signal() will get a chance to do all its work
66 // before waitable_event is deleted.
67 AutoLock msgs_awaiting_replies_autolock(messages_awaiting_replies_lock_);
68 messages_awaiting_replies_->Remove(message_id);
69 return result;
70 }
71
72 // Processes incoming message |message| from the browser process.
73 virtual bool OnMessageReceived(const IPC::Message& message); 17 virtual bool OnMessageReceived(const IPC::Message& message);
74 18
75 private:
76 // The state we store for each message we send.
77 struct DBMessageState {
78 intptr_t result_address_;
79 base::WaitableEvent* waitable_event_;
80 };
81
82 // This is a RefCounted class, do not allow anybody to destroy it directly.
83 virtual ~DBMessageFilter() { instance_ = NULL; }
84
85 // Invoked when this filter is added to |channel|.
86 virtual void OnFilterAdded(IPC::Channel* channel);
87
88 // Called when the channel encounters a problem. The filter should clean up
89 // its internal data and not accept any more messages.
90 virtual void OnChannelError();
91
92 // Called when the channel is closing. The filter should clean up its internal
93 // and not accept any more messages.
94 virtual void OnChannelClosing();
95
96 // Processes the reply to a sync DB request.
97 template<class ResultType>
98 void OnResponse(int32 message_id, ResultType result) {
99 AutoLock msgs_awaiting_replies_autolock(messages_awaiting_replies_lock_);
100 DBMessageState *state = messages_awaiting_replies_->Lookup(message_id);
101 if (state) {
102 *reinterpret_cast<ResultType*>(state->result_address_) = result;
103 state->waitable_event_->Signal();
104 }
105 }
106
107 // Processes IPCs that indicate a change in the size of a DB file.
108 void OnDatabaseUpdateSize(const string16& origin_identifier, 19 void OnDatabaseUpdateSize(const string16& origin_identifier,
109 const string16& database_name, 20 const string16& database_name,
110 int64 database_size, 21 int64 database_size,
111 int64 space_available); 22 int64 space_available);
112
113 // Processes IPCs that ask for a DB to be closed immediately.
114 void OnDatabaseCloseImmediately(const string16& origin_identifier, 23 void OnDatabaseCloseImmediately(const string16& origin_identifier,
115 const string16& database_name); 24 const string16& database_name);
116
117 // The message loop for the IO thread.
118 MessageLoop* io_thread_message_loop_;
119
120 // The channel to which this filter was added.
121 IPC::Channel* channel_;
122
123 // A lock around the channel.
124 Lock channel_lock_;
125
126 // The shutdown event.
127 base::WaitableEvent* shutdown_event_;
128
129 // The list of messages awaiting replies. For each such message we store a
130 // DBMessageState instance.
131 scoped_ptr<IDMap<DBMessageState> > messages_awaiting_replies_;
132
133 // The lock for 'messages_awaiting_replies_'.
134 Lock messages_awaiting_replies_lock_;
135
136 // A thread-safe unique number generator.
137 scoped_ptr<base::AtomicSequenceNumber> unique_id_generator_;
138
139 // The singleton.
140 static DBMessageFilter* instance_;
141 }; 25 };
142 26
143 #endif // CHROME_COMMON_DB_MESSAGE_FILTER_H_ 27 #endif // CHROME_COMMON_DB_MESSAGE_FILTER_H_
OLDNEW
« no previous file with comments | « chrome/common/database_util.cc ('k') | chrome/common/db_message_filter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698