| OLD | NEW |
| 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_ |
| OLD | NEW |